我不是在问这两者之间的区别,而是为什么通常更喜欢接口而不是抽象类。
答案 0 :(得分:15)
抽象类最明显的“缺点”是继承类型只能从一个抽象类继承。
对于接口,您可以实现多个接口。
因此,当您设计类型以便他们需要实现多个合同时,接口就是唯一的选择。
所以,至少在C#世界中,这与SOLID原则一起可以解释接口的倾向。
答案 1 :(得分:6)
我将在这里扮演魔鬼的倡导者......
ABCs在接口上的一个优点是,您可以在不破坏所有派生类的情况下向ABC添加方法。如果向接口添加方法,则会破坏实现该接口的每个类。
出于这个原因,微软的建议是favour classes over interfaces。
此外,ABC可以在适当的时候为其方法提供默认实现。
此外,ABC可以定义类型(例如枚举)和只读“常量”,而界面则不能。
答案 2 :(得分:5)
这真的是一个非常有问题的问题。它们在不同情况下都有各自的用途。
抽象类
当子类之间共享一个共同的功能时使用抽象类,但超类本身永远不会存在。例如,类Person
将永远不存在。但是课程Woman
会。我们只是将它提升到超类,而不是重复Woman
中Man
,Boy
和Girl
中的所有方法,因此它们都可以访问此功能,并且可以覆盖他们想要以不同方式执行的方法。
接口
有需求时使用接口。我看待它们的方式就像合同一样。协议是任何实现接口的类都必须为一定数量的方法提供代码。
例如,可以抛出类Rock
和类Ball
。如果每个对象实现ThrowingItem
接口(我出于显而易见的原因,我不想使用单词Throwable
),而不是抛出一个必须考虑可抛出的每个对象的球的方法,然后该方法可以只接受ThrowingItem
类型的对象,并知道商定的方法将在那里。
这使得throw
方法与使用它的类之间的松耦合成为可能,因为所有通信都是通过接口完成的。
<小时/> 如您所见,两种不同的类型在不同的情况下使用,比较它们就像比较苹果和橘子。
答案 3 :(得分:4)
根据经验,当我们至少部分实现时,当我们对实现和抽象类没有任何说法时,我们使用接口。
答案 4 :(得分:2)
以下是我最常见的经验法则:
一旦你转向抽象,你可以通过这个注释决定哪种类型:你不能从多个抽象类继承,所以你应该如何在抽象类或接口IMO之间做出真正的决定,除非你需要一个实现或不(如果没有,那么只需使用一个接口以避免以后的多重继承冲突潜力)
答案 5 :(得分:1)
如果你有一个可以设计为接口或抽象类的类型,你为什么要选择抽象类?
从这个意义上说,我们只在某些功能无法在界面中完成时才使用抽象类:
状态。虽然接口可以要求子类实现状态,但使用抽象超类来保存状态可能更方便。
限制成员访问protected
。界面中的所有内容都是public
静态方法。 (请注意,在Java 8中,接口可能有静态方法)
实现的具体方法。 (请注意,在Java 8中,接口方法可能具有defualt impl)
在不破坏子类的情况下添加更多具体方法。 (请注意,在Java 8中,如果方法具有默认impl,我们可以向现有接口添加更多方法)