继承和组合的区别

249

组合和继承是一样的吗? 如果我想实现组合模式,我应该如何在Java中实现?


2
其他相关问题:组合有没有什么继承可以实现不了的功能?https://dev59.com/t3E95IYBdhLWcg3wmvGh - ewernli
1
请参阅继承VS组合,哪个更好 - nawfal
1
这篇文章对我很有用,帮了我很多:https://www.thoughtworks.com/insights/blog/composition-vs-inheritance-how-choose - QMaster
请查看 https://themightyprogrammer.dev/article/inheritance-composition。 - The Mighty Programmer
17个回答

3

继承是指一个类继承另一个类,建立了“是一个”关系。

另一方面,组合是指在一个类中包含另一个类的实例,建立了“有一个”关系。在Java中,组合非常有用,因为它在技术上实现了多重继承。


1
尽管继承和组合都提供代码重用性,但Java中组合与继承的主要区别在于,组合允许重用代码而无需对其进行扩展,但对于继承,您必须扩展类以便重用代码或功能。由此带来的另一个区别是,通过使用组合,您可以重用甚至是不可扩展的最终类的代码,但是在这种情况下,继承不能重用代码。此外,通过使用组合,您可以从许多类中重用代码,因为它们只被声明为成员变量,但是通过继承,您只能从一个类中重用代码,因为在Java中,您只能扩展一个类,因为Java不支持多重继承,而在C ++中可以这样做,因为一个类可以扩展多个类。顺便说一下,在Java中,您应该始终优先选择组合而不是继承,这不仅是我的意见��而且连Joshua Bloch在他的书中也建议这样做。

1
为什么我应该“优先选择组合而非继承”?它们是不同的概念,用于不同的目的。坦白地说,我甚至不知道你怎么能从一个转到另一个。 - Kröw

1

1
仅提供链接的答案不被鼓励,因为它们会过时。请在您的回答中至少包含来自链接中最重要的相关信息。 - Scott Solmer

1

继承 vs 组合。

继承和组合都用于类行为的可重用性和扩展。

继承主要用于家族算法编程模型,例如 IS-A 关系类型表示相似类型的对象。例如:

  1. Duster 是一辆汽车
  2. Safari 是一辆汽车

这些都属于汽车家族。

组合表示 HAS-A 关系类型。它显示对象的能力,例如 Duster 有五档,Safari 有四档等。每当我们需要扩展现有类的功能时,就使用组合。例如,如果我们需要在 Duster 对象中添加一个更多的齿轮,则必须创建一个新的齿轮对象并将其组合到 Duster 对象中。

我们不应该在基类中进行更改,除非所有派生类都需要这些功能。对于这种情况,我们应该使用组合。例如:

类 A 派生自类 B

类 A 派生自类 C

类 A 派生自类 D。

当我们在A类中添加任何功能时,即使C类和D类不需要这些功能,它也对所有子类可用。为了处理这种情况,我们需要为这些功能创建一个单独的类,并将其组合到所需的类中(这里是B类)。
以下是示例:
          // This is a base class
                 public abstract class Car
                    {
                       //Define prototype
                       public abstract void color();
                       public void Gear() {
                           Console.WriteLine("Car has a four Gear");
                       }
                    }


           // Here is the use of inheritence
           // This Desire class have four gears.
          //  But we need to add one more gear that is Neutral gear.

          public class Desire : Car
                   {
                       Neutral obj = null;
                       public Desire()
                       {
     // Here we are incorporating neutral gear(It is the use of composition). 
     // Now this class would have five gear. 

                           obj = new Neutral();
                           obj.NeutralGear();
                       }

                       public override void color()
                       {
                           Console.WriteLine("This is a white color car");
                       }

                   }


             // This Safari class have four gears and it is not required the neutral
             //  gear and hence we don't need to compose here.

                   public class Safari :Car{
                       public Safari()
                       { }

                       public override void color()
                       {
                           Console.WriteLine("This is a red color car");
                       }


                   }

   // This class represents the neutral gear and it would be used as a composition.

   public class Neutral {
                      public void NeutralGear() {
                           Console.WriteLine("This is a Neutral Gear");
                       }
                   }

0

继承意味着重用类的完整功能,这里我的类必须使用超类的所有方法,我的类将与超类紧密耦合,并且在继承的情况下代码将在两个类中重复。

但是当我们使用组合来与另一个类交互时,我们可以克服所有这些问题。组合是将另一个类的属性声明为我的类,以便我们想要与其交互。我们可以通过使用该属性获得所需的功能。


0

组合意味着创建一个与特定类有关系的对象。 假设学生与账户有关系;

继承是指具有扩展功能的先前类。这意味着这个新类是旧类带有一些扩展功能。 假设学生是学生,但所有学生都是人类。因此,学生和人之间存在关系。这就是继承。


-1

不是,两者是不同的。组合遵循“HAS-A”关系,而继承遵循“IS-A”关系。组合的最佳示例是策略模式。


2
它只是评论的质量。 - Mathews Sunny
你刚才是不是评论了一个七年前已经被接受的答案所说的同样的话? - Anjil Dhamala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接