这可能是一个通用的OOP问题。我想在接口和抽象类的使用基础上做一个通用的比较。

什么时候需要使用接口,什么时候需要使用抽象类?


当前回答

我的观点是:

接口基本上定义了一个契约,任何实现类都必须遵守(实现接口成员)。它不包含任何代码。

另一方面,抽象类可以包含代码,并且可能有一些标记为抽象的方法,继承类必须实现这些方法。

我很少使用抽象类的情况是,当我有一些默认功能时,继承类可能对重写不感兴趣,比如一个抽象基类,一些专门的类继承自它。

示例(非常基本的一个!):考虑一个名为Customer的基类,它具有抽象方法,如CalculatePayment(), CalculateRewardPoints()和一些非抽象方法,如GetName(), SavePaymentDetails()。

像RegularCustomer和GoldCustomer这样的专门的类将继承自Customer基类,并实现它们自己的CalculatePayment()和CalculateRewardPoints()方法逻辑,但是重用GetName()和SavePaymentDetails()方法。

您可以向抽象类(即非抽象方法)添加更多功能,而不会影响使用旧版本的子类。然而,向接口添加方法会影响实现它的所有类,因为它们现在需要实现新添加的接口成员。

具有所有抽象成员的抽象类类似于接口。

其他回答

基本的经验法则是:对于“名词”使用抽象类,对于“动词”使用接口

例如:car是一个抽象类和驱动器,我们可以让它成为一个接口。

什么时候选择抽象类而不是接口?

如果计划在程序/项目的整个生命周期中更新基类,最好允许基类是一个抽象类 如果有人试图为层次结构中密切相关的对象构建主干,那么使用抽象类是非常有益的

什么时候选择接口而不是抽象类?

如果不需要处理大量的层次结构类型的框架,那么接口将是一个很好的选择 因为抽象类不支持多重继承(菱形问题),所以接口可以挽救局面

1.如果您正在创建为不相关的类提供公共功能的东西,请使用接口。

2.如果您正在为层次结构中密切相关的对象创建一些东西,请使用抽象类。

车辆包括汽车、坦克、飞机、手推车等。

抽象类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 {...}

如果你认为java是面向对象语言,

“接口不提供方法实现”在Java 8启动后不再有效。现在java为默认方法提供了接口实现。

简单来说,我想用

接口:通过多个不相关的对象实现一个契约。它提供了“HAS A”功能。

抽象类:在多个相关对象之间实现相同或不同的行为。它建立了“IS A”关系。

Oracle网站提供了接口和抽象类之间的关键区别。

考虑使用抽象类,如果:

您希望在几个密切相关的类之间共享代码。 您希望扩展抽象类的类具有许多公共方法或字段,或者需要除public以外的访问修饰符(例如protected和private)。 您希望声明非静态或非final字段。

考虑使用接口,如果:

您希望不相关的类实现您的接口。例如,许多不相关的对象都可以实现Serializable接口。 您希望指定特定数据类型的行为,但不关心由谁实现其行为。 您希望利用类型的多重继承。

例子:

抽象类(IS一个关系)

Reader是一个抽象类。

BufferedReader是一个Reader

FileReader是一个阅读器

FileReader和BufferedReader用于一个共同的目的:读取数据,它们通过Reader类相互关联。

接口(具有功能)

Serializable是一个接口。

假设您的应用程序中有两个实现Serializable接口的类

Employee实现Serializable

游戏实现Serializable

在这里,你不能通过Serializable接口在员工和游戏之间建立任何关系,这是为了不同的目的。两者都能够序列化状态,比较到此结束。

看看这些帖子:

我应该如何解释接口和抽象类之间的区别?