如果我有一些子类型,每个都继承一个抽象超类,这个超类实现了一个接口 - 当实现动态绑定/多态时,将对象声明为超类类型与接口类型相反有什么区别?
所以A,B,C,D从S扩展而S实现了我。
我能做到:
S a = new A();
S b = new B();
或
I a = new A();
I b = new B();
我倾向于使用接口,但我突然想知道如果你将接口拆分为两个接口,是否更好地使用超类....
答案 0 :(得分:3)
从打字的角度来看,没有区别。 (除非您通过使用反射在运行时内省类型来专门“寻找”...)
从运行时性能的角度来看,没有区别。 (除了加载类的时间上可能存在的微小差异之外......在所有实际用例中都可以忽略。)
从代码实现的角度来看,这两种方法都有优点和缺点:
如果仅使用超类(无接口),则可以编写更少的代码。但另一方面,你的代码灵活性较低:
您正在尝试使用外部API来限制您编写新实现的能力。 java.io.OutputStream
类就是一个典型的例子。因为它是一个类,所以必须创建一个子类才能实现新的流类型,并且您可能会发现必须对子类进行编码以覆盖您“继承”的所有基础结构。
一个类只有一个超类的事实进一步限制了你的树形API层次结构。
客户端必须在更大程度上针对实现类API进行编码...因为这就是全部。这限制了程序员改变主意的能力。
结论:如果特定用例不要求您能够执行这些操作(现在或将来),那么使用接口没有任何好处。但很少有用例就是这样。使用接口的增量实现工作量很小。
好吧,是的。但抽象方法也是如此。这不是使用接口的真正意义。真正的意义是接口:我应该补充一下,我不是在问是否使用接口。我猜测接口可以用来强迫某人实现方法(并且从不声明为类型)?
我只想问一下使用接口有什么好处,因为对象类型会带来多态性?
从打字和表现水平:无 - 见上文。
我想,您可能会争辩说,如果您以某种跨越实现层次结构的方式使用接口,那么您在客户端级别可以获得更大的灵活性。我想你可以称之为“多态性的好处”。 (相比之下,如果您的接口层次结构完全反映了您的实现类层次结构,那么您可能没有实现任何目标......至少就编写的代码而言。)
然而,多态性是达到目的的手段,而不是自身的目标,所以我认为在抽象意义上询问“多态性的好处”是错过了重点。真正的重点是以有意义的方式设计和实现程序,并产生可维护的代码。
答案 1 :(得分:1)
这完全取决于上下文。
实例化代码只能访问您将变量声明为的接口或类可用的成员。通常目标是限制实例化代码导入的内容。如果只需要了解List
,则将其声明为List
。如果它需要ArrayList
中的方法,则将其声明为ArrayList
。不要让实例化代码知道它需要的东西。