这可能是一个通用的OOP问题。我想在接口和抽象类的使用基础上做一个通用的比较。
什么时候需要使用接口,什么时候需要使用抽象类?
这可能是一个通用的OOP问题。我想在接口和抽象类的使用基础上做一个通用的比较。
什么时候需要使用接口,什么时候需要使用抽象类?
当前回答
抽象类可以有实现。
接口没有实现,它只是定义了一种契约。
也可能存在一些依赖于语言的差异:例如c#没有多重继承,但在一个类中可以实现多个接口。
其他回答
我为此写了一篇文章:
抽象类和接口
总结:
当我们谈论抽象类时,我们是在定义对象类型的特征;指定对象是什么。
当我们谈论接口和定义我们承诺提供的功能时,我们谈论的是建立一个关于对象可以做什么的契约。
基本的经验法则是:对于“名词”使用抽象类,对于“动词”使用接口
例如:car是一个抽象类和驱动器,我们可以让它成为一个接口。
如果我们有一个对所有派生类都相同的实现,那么此时最好使用抽象类而不是接口。当我们有一个接口时,我们可以将我们的实现移动到任何实现接口的类。在抽象类中,它避免了代码重复,并共享所有派生类的实现。接口允许开发松散耦合的系统,这有助于更好的测试。
我的观点是:
接口基本上定义了一个契约,任何实现类都必须遵守(实现接口成员)。它不包含任何代码。
另一方面,抽象类可以包含代码,并且可能有一些标记为抽象的方法,继承类必须实现这些方法。
我很少使用抽象类的情况是,当我有一些默认功能时,继承类可能对重写不感兴趣,比如一个抽象基类,一些专门的类继承自它。
示例(非常基本的一个!):考虑一个名为Customer的基类,它具有抽象方法,如CalculatePayment(), CalculateRewardPoints()和一些非抽象方法,如GetName(), SavePaymentDetails()。
像RegularCustomer和GoldCustomer这样的专门的类将继承自Customer基类,并实现它们自己的CalculatePayment()和CalculateRewardPoints()方法逻辑,但是重用GetName()和SavePaymentDetails()方法。
您可以向抽象类(即非抽象方法)添加更多功能,而不会影响使用旧版本的子类。然而,向接口添加方法会影响实现它的所有类,因为它们现在需要实现新添加的接口成员。
具有所有抽象成员的抽象类类似于接口。
车辆包括汽车、坦克、飞机、手推车等。
抽象类Vehicle可以有子类,如car、tank、plane、cart等。
public abstract Vehicle {...}
public Car extends Vehicle {...}
public Tank extends Vehicle {...}
那么,什么是可移动的?几乎一切! 然后
石头,蛋糕,汽车,行星,星系,甚至你都是可移动的!
它们中的大多数也是可观察的!
什么是可吃的?这是一款名为《美味星球》的游戏。 然后
石头,汽车,行星,星系,甚至时间!
public interface Movable {...}
public interface Observable {...}
public interface Eatable {...}
public class Stone implements Movable, Eatable, Observable {...}
public class Time implements Eatable, Observable {...}
public class Stupidity implements Observable {...}
终于!
public class ChocolateCar extends Vehicle implements Eatable {...}