问题

多用组合少用继承中,接口继承算不算一种组合?

回答
在“多用组合,少用继承”这个设计原则的语境下,理解接口继承是否算作一种组合,关键在于抓住“组合”的核心思想——“hasa”关系,以及接口继承所建立的“isa”关系(或者更准确地说,是“cando”)。

我们先来回顾一下组合的精髓。组合,简单来说,就是在一个类中包含另一个类的实例作为其成员变量。这样做是为了实现“hasa”的关系。比如,一个“汽车”类组合了一个“发动机”对象。汽车“拥有”一个发动机,发动机是汽车的组成部分。通过这种方式,汽车可以调用发动机的方法来实现其功能,而无需直接继承发动机的实现。这种方式的优点在于灵活、解耦,可以轻松地替换或修改组成部分,而不会影响到整体。

现在来看看接口继承。接口继承,或者更常说的“实现接口”,是说一个类声明它能够提供一组特定的行为(由接口定义)。例如,一个“狗”类可以实现一个“会叫”的接口。这意味着狗“能够”叫。接口本身并不提供具体的实现,它只是定义了一种契约,规定了类必须具备哪些方法。

那么,接口继承和我们刚才说的组合有何相似之处,又有什么根本区别呢?

相似之处在于,它们都允许我们通过“委托”的方式来构建功能。一个类实现了一个接口,它就“承诺”了能够执行接口中定义的方法。当外部代码需要执行某个接口定义的功能时,它不必关心具体是哪个类在实现这个接口,只需要找到一个实现该接口的对象,然后调用相应的方法即可。这使得代码更加灵活,可以接受任何实现特定行为的类。从这个角度看,接口继承似乎也让类能够“拥有”或“提供”某种能力,而无需深入了解这个能力是如何具体实现的。

然而,根本的区别在于它们所代表的关系以及对“实现”的侧重。

组合关注的是“拥有”一个具体的、具有独立实现的“部件”。汽车拥有发动机,发动机是一个具体的对象,有自己的状态和行为。组合是关于“聚合”和“利用”已有功能的具体实例。

而接口继承,尤其是“实现接口”,更侧重于“能够做什么”的规范,而不是“拥有一个什么”。狗实现“会叫”接口,并不是说狗“拥有”了一个“叫”的对象,而是说狗“能够”发出叫声。这种关系更像是“isa”的另一种表现形式,或者更贴切地说,是“cando”的承诺。一个实现了“可排序”接口的列表,意味着它“能够”被排序,而不是说它“拥有”了一个“排序器”对象(尽管在内部实现上,它可能会委托给一个排序算法)。

因此,从严格的“hasa”关系和“组成部分”的角度来看,接口继承并不能被直接视为一种组合。组合强调的是通过组合具体对象来构建复杂功能,是“零件的堆叠”。而接口继承(实现接口)强调的是对一组行为能力的“承诺”和“契约”,是“能力的组合”。

但是,在“多用组合,少用继承”这个大原则下,我们常常会看到将接口的灵活性与组合的优势结合起来的应用。例如,一个类可能不直接继承另一个类,而是通过组合一个实现了某个接口的对象来获得某种能力。这看起来有些绕,但本质上是说:与其让一个类直接“是”另一个类(继承),不如让它“拥有”另一个类(组合),或者让它“能够做”某个事(实现接口)。

你可以这样理解:当你实现一个接口时,你是在说“我能够满足这个接口的要求”。当你组合一个对象时,你是在说“我需要这个对象来完成我的工作”。这两种方式都避免了硬编码具体的类,都为你提供了更多的选择空间,从而更加符合“少用继承”的精神。

所以,尽管接口继承(实现接口)不是狭义上的“hasa”的组合,但在“多用组合,少用继承”的语境下,它被视为一种重要的、替代继承的机制,因为它同样能带来解耦和灵活性,并且更侧重于行为的约定而非实现的继承。你可以把它看作是“能力”层面的组合,而不是“实体”层面的组合。它让你在设计类时,能够专注于“我需要什么能力”,而不是“我需要继承什么具体实现”。

网友意见

user avatar

我不知道多用组合少用继承是怎么搞出来的。一定要说的话,正确的说法应该是不要用继承来解决代码复用的问题,继承就是继承的语义,要解决代码复用问题应该优先考虑组合。

但这也不是铁板一块,并不是说用继承来实现代码复用就有多么不可取,只是说把继承和复用分开来,代码复用不是非用继承不可,不要滥用继承。


所以总的来说,和接口没啥关系。

user avatar

扣字面意思的话,接口是实现而不是继承。

我认为接口中没有可复用的代码,因此不算组合。


实际上,在继承与组合的讨论种,是不存在接口的。

举个例子,我们有一个Color类,现在需要实现一个Button类

       //继承 class Button extends Color {     ... } //组合 class Button {     //如果Color是接口,就不能new了     Color color = new Color();     ... }     

可以看到,继承和组合都是为了复用Color的代码,而接口是没有方法实现的,也就没有需要复用的代码。

因此问题不成立。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有