2010-07-20 23 views
4

使用继承作为重用代码的一种方式有什么缺点?使用继承作为重用代码的一种方式有什么缺点?

+7

是不是在你的教科书的某个地方? – Grumdrig 2010-07-20 21:06:10

+1

当你想从多个类继承功能,但是你的语言不支持多继承时会发生什么? – 2010-07-20 21:11:48

+0

C++支持多种继承 java支持使用接口 不知道其他人 – inglor 2010-07-20 21:13:45

回答

6

使用继承实现代码重用从具有以下问题:

  1. 你不能在运行时改变重用行为。继承是编译时依赖性,因此,如果一个GameClient类从TCPSocket继承重用connect()write()成员函数,它具有TCP功能的硬编码。你不能在运行时改变它。

  2. 不能取代来自外部的重复使用性能进行测试的缘故。如果一个GameClient类继承自TCPSocket,以至于得到write()(用于将数据写入套接字),则不能从外部交换此代码。你不能插入一个不同的write()函数来记录所有要写入文件的数据。

  3. 你是依赖于所有,但最简单的应用多重继承。这为diamond shaped inheritance trees打开了大门,这会增加代码复杂度。

喜欢使用继承的组合来重用代码可以避免所有这些问题。

0

它需要继承(用于反射它),这是仅适用于代码许多可能的结构中的一种。这就是为什么我们有程序编程,函数式编程,面向对象编程,面向方面编程,声明式编程等。请参阅programming paradigms

6

IIRC,所述里氏替换原则1)假定,一个人应该能够通过任何其派生类的替代的类;也就是说,派生类不应该表现出与它们的基类所建立的契约完全不同的行为,或者违反其基类设立的契约。

显然,这个原则对如何(基)类可以被另一个类(从它派生出来)“重用”提出了有意的限制。其他使用类的方法,如聚合或合成,不受原理的限制。


1)参见例如The Liskov Substitution Principle(指向PDF文档的链接)。

3

使用继承意味着当您在同一个类中调用一个方法(或C++中的虚拟方法)时,您可能实际上正在调用一个子类的方法并不是很清楚。可能导致的代码异味是在类层次结构中上下移动的调用堆栈,这实际上意味着您的超类和子类处于循环依赖状态。

使用组合和接口清楚地表明存在多种可能的实现,并且在存在循环依赖(通常应该被删除)时也很明显。 (由于一些原因(假设您通过构造函数使用类的传递依赖关系),构造使循环依赖显而易见)。如果A和B相互依赖,那么A构造B并且将thisself传递给B的构造函数,这是一个循环依赖的明确标志,或者其他一些类构造A和B,A变得不可能,因为A要求B先构建,而B需要先构建A)。

0

如果使用继承,则会将其绑定到可变状态的面向对象的范例中。如果您尝试使用不可变对象,您最终会写[伪代码]

class A (int X, int Y) 
    def self.nextX(int nextX) = A(newX, self.Y) 

class B (int X, int Y, int Z) extends A(X, Y) 
    def self.nextX(int nextX) = B(newX, self.Y, self.Z) 

并且没有代码重用。因此,你使用可变对象,并发生疯狂:)。

相关问题