接口是100%抽象类,因此我们可以使用接口进行高效编程.是否存在抽象类优于接口的情况?
当您打算创建具体类时,会使用抽象类,但希望确保所有子类中都存在某种公共状态,或者某些操作可能存在常见实现.
接口也不能包含.
是的,抽象类和接口都有一个位置.
我们来看一个具体的例子.我们将研究如何使一个CheckingAccount
并SavingsAccount
从一个抽象的AbstractBankAccount
,看看我们如何能够使用一个接口区分这两种类型的帐户.
首先,这是一个抽象类AbstractBankAccount
:
abstract class AbstractBankAccount { int balance; public abstract void deposit(int amount); public abstract void withdraw(int amount); }
我们有账户余额balance
和两个方法deposit
,并withdraw
必须由子类实现.
我们可以看到,抽象类声明了如何定义银行账户的结构.正如@Uri在他的回答中提到的那样,这个抽象类有一个状态,即balance
字段.接口无法实现这一点.
现在,让我们的子类AbstractBankAccount
来制作一个CheckingAccount
class CheckingAccount extends AbstractBankAccount { public void deposit(int amount) { balance += amount; } public void withdraw(int amount) { balance -= amount; } }
在这个子类中CheckingAccount
,我们实现了两个抽象类 - 这里没什么太有趣的.
现在,我们如何实施SavingsAccount
?它不同于CheckingAccount
它会获得兴趣.通过使用该deposit
方法可以增加利息,但是再次,并不是客户自己存入利息.因此,如果我们有另一种方法可以将钱添加到账户中,特别是对于利息,比如一种accrueInterest
方法,可能会更清楚.
我们可以直接实现该方法SavingsAccount
,但是我们可能会有更多的银行帐户类型可以在将来产生兴趣,因此我们可能希望创建一个InterestBearing
具有以下accrueInterest
方法的接口:
interface InterestBearing { public void accrueInterest(int amount); }
所以,我们现在可以SavingsAccount
通过实现InterestBearing
接口来创建一个可以获得兴趣的类:
class SavingsAccount extends AbstractBankAccount implements InterestBearing { public void deposit(int amount) { balance += amount; } public void withdraw(int amount) { balance -= amount; } public void accrueInterest(int amount) { balance += amount; } }
现在,如果我们想创建另一种类型的帐户,比如说a PremiumSavingsAccount
,我们可以创建一个子类AbstractBankAccount
并实现该InterestBearing
接口以创建另一个有息帐户.
所述InterestBearing
接口可以被看作是增加一个共同的特点不同的类.如果没有产生任何利息,那么在支票账户中有一个处理利息的功能是没有意义的.
因此,在一种情况下,确实存在抽象类和接口共存和协同工作的地方.