组合与继承比较

时间:2020-02-23 14:36:11  来源:igfitidea点击:

作文与继承是面试中常见的问题之一。
您还必须听说过在继承上使用合成。

组合(Composition )与继承(Inheritance)

组合和继承都是面向对象的编程概念。
它们没有与任何特定的编程语言(例如Java)捆绑在一起。
在以编程方式比较继承与继承之间的构成之前,让我们对其进行快速定义。

组合

组合是面向对象编程中实现对象之间关系的设计技术。
Java中的合成是通过使用其他对象的实例变量来实现的。
例如,像下面的Java面向对象编程中那样实现具有Job的人。

package com.theitroad.localposition;

public class Job {
//variables, methods etc.
}
package com.theitroad.localposition;

public class Person {

  //composition has-a relationship
  private Job job;

  //variables, methods, constructors etc. object-oriented

继承

继承是面向对象编程中实现is-对象之间关系的设计技术。
Java中的继承是使用extend关键字实现的。

例如,Cat是动物关系,在Java编程中将像下面那样实现。

package com.theitroad.comheritance;
 
public class Animal {
//variables, methods etc.
}
package com.theitroad.comheritance;
 
public class Cat extends Animal{
}

重组合,轻继承

组合和继承都通过不同的方法促进代码重用。
那么选择哪一个呢?如何比较组成与继承。
您必须已经听说过,在编程中,您应该更喜欢组合而不是继承。
让我们来看看一些有助于您选择构图还是继承的原因。

  • 继承紧密耦合,而组成则松散耦合。
    假设我们下面有继承类。

为简单起见,我们在一个包中同时包含了超类和子类。
但是大多数情况下它们将在单独的代码库中。
可能会有许多类扩展超类ClassA。
这种情况的一个非常常见的示例是扩展Exception类。
现在,我们说ClassA实现的更改如下,添加了一个新方法bar()。

一旦开始使用新的ClassA实现,您将在ClassB中收到编译时错误,因为返回类型与ClassA.bar()不兼容。
解决方案是更改父类或者子类的bar()方法以使其兼容。
如果您在继承上使用了Composition,则永远不会遇到这个问题。
使用Composition的ClassB实现的简单示例如下。

  • 继承中没有访问控制,而访问可能受到限制。
    我们将所有超类方法公开给其他有权访问子类的类。
    因此,如果引入了新方法或者超类中存在安全漏洞,则子类将变得脆弱。
    由于在合成中我们选择使用哪种方法,因此它比继承更安全。
    例如,我们可以使用ClassB中的以下代码向其他类提供ClassA foo()方法。

这是组成优于继承的主要优点之一。

  • 组合可以灵活地调用对多个子类场景有用的方法。
    例如,假设我们有以下继承方案。

那么,如果有更多的子类,那么每个子类都有一个实例,那么组合会使我们的代码变得丑陋吗?不,我们可以像下面这样重写Test类。

这将使您能够灵活地使用基于构造函数中使用的对象的任何子类。

  • 与继承相比,组合的另一个好处是测试范围。
    单元测试很容易组合,因为我们从另一个类中知道我们正在使用的所有方法。
    我们可以模拟它进行测试,而在继承中,我们很大程度上依赖于超类,并且不知道将使用所有超类方法。
    因此,我们将必须测试超类的所有方法。
    这是另外的工作,由于继承,我们不需要这样做。