继承与构成的区别?

时间:2011-11-08 05:47:34

标签: java inheritance composition

class B extends A 

这个代码类B可以使用A类的变量和方法。

class B
{
    A a=new A();
}

现在我们也可以使用类B中的对象a来使用类A的变量和方法。

所以我的问题是这个----为什么我们使用这两种不同的方式来使用其他类属性(在变量和方法方面)..

5 个答案:

答案 0 :(得分:4)

第二种方法称为委托。当AB的成员时,还有组合

两者之间的区别在于,如果AB不在同一个包中(包访问是另一种情况 - 留给读者的练习) - 那么在委派或组合您只能访问类A的公共数据成员和方法,而在继承的情况下,继承类B可以访问公共和受保护的成员以及类A的方法。

<强>更新

即使在A可以访问B的所有方法和成员的情况下,还存在许多其他差异(大多数方法与您不是这两个类的所有者的情况有关)而是当第三方向您提供A并且您无法控制其访问修饰符时。)

但即使你确实拥有控制权并且可以将A的所有成员和方法定义为公开 - 你想要吗?它会引入大量额外的维护问题 - 最重要的是,IMO,你定义的任何 公开是你和你的代码用户之间的合同 - 也许是某人在这个星球的不同部分。这反过来意味着你无法隐藏你的实现细节,你的私人实用工具方法或者他的任何东西 - 没有什么能阻止他使用一些你只为内部计算而直接编写的方法。

这意味着 - 明天您决定不再维护该方法或者它引入某种性能或安全问题时 - 您无法删除它。 有人已经使用过它。

另一次更新

如下所述,以及我未提及的内容,在继承的情况下,您还会收到“免费礼物” - 多态。的 See here.

答案 1 :(得分:1)

我认为 B类扩展A 引入某种层次,你可以使用A的方法,B中的变量即使你不知道A;而且在面向对象的设计方面也更加美观。

答案 2 :(得分:1)

一个明显的区别是覆盖了A类中定义的函数。

想象一下,您有10个在A中定义的函数,并且您只想覆盖其中一个函数。然后,如果你使用继承,你只覆盖一个继承,仍然可以调用所有10.使用你的另一种方法除非你重新实现它们,否则你不能调用任何方法。 (或者让a公开并直接调用它,但这是反对封装的。)

答案 3 :(得分:1)

第一个例子是继承,第二个例子叫做组合。

继承最好代表“是一种”关系,当B是一种比A更具体的实体时。例如,汽车是一种载体。继承为您提供超类的所有公共和受保护的方法和变量。因此,子类应该具有每个继承特征的逻辑实现。例如,车辆可以具有颜色,因此所有车辆也必须具有颜色。

当A是B的子组件时,

组合最能代表“有”关系。例如,汽车有引擎。它们都不是真正的另一个超集,它们是完全不同的类。然而,汽车必须使用发动机来执行。它们不太可能共享许多方法和变量,因此继承会很尴尬。想象一下,汽车类必须实施或公开许多特定发动机细节的方法,例如油位和温度。汽车对象不应该只是将所有这些方法暴露给... drive()。

答案 4 :(得分:1)

第一个示例是 is-a 关系的示例。 class B将是class A的扩展,包含所有class A的公共成员,并且也可以访问受保护的成员(在第二个示例中您不会这样做) 。这也允许您将从class A派生的对象组合在一起(包括class A的类型),从而为任何重写方法启用多态性。这是第二个例子不允许你做的另一件事,覆盖class A中定义的方法,使它们更适合class B。如果你想从一个类中继承行为,你就可以这样做。

第二个是 has-a 关系的示例。例如,如果您有class Parent拥有 class Child,则可以使用它。

有大量的书籍/指南/文件可以为您提供每个选项的差异和优势,并且最适合特定情况。

编辑:我花了太长时间发帖,如果你搜索“is-a”和“has-a”关系,你会发现很多信息。