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


当前回答

组合和继承是一样的吗?

它们不一样。

组合:它允许以对象的单个实例的方式处理一组对象。组合的目的是将对象“组合”成树状结构,以表示部分-整体层次结构

继承:类从其所有超类继承字段和方法,无论是直接的还是间接的。子类可以覆盖它继承的方法,也可以隐藏它继承的字段或方法。

如果我想实现组合模式,我如何在Java中做到这一点?

维基百科的文章足以在java中实现复合模式。

主要参与者:

组件:

是所有组件的抽象,包括复合组件吗 声明组合中对象的接口

叶:

表示组合中的叶对象 实现所有组件方法

复合材料:

表示一个复合组件(有子组件) 实现操作子节点的方法 实现所有Component方法,通常是将它们委托给其子方法

理解Composite模式的代码示例:

import java.util.List;
import java.util.ArrayList;

interface Part{
    public double getPrice();
    public String getName();
}
class Engine implements Part{
    String name;
    double price;
    public Engine(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Trunk implements Part{
    String name;
    double price;
    public Trunk(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Body implements Part{
    String name;
    double price;
    public Body(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Car implements Part{
    List<Part> parts;
    String name;

    public Car(String name){
        this.name = name;
        parts = new ArrayList<Part>();
    }
    public void addPart(Part part){
        parts.add(part);
    }
    public String getName(){
        return name;
    }
    public String getPartNames(){
        StringBuilder sb = new StringBuilder();
        for ( Part part: parts){
            sb.append(part.getName()).append(" ");
        }
        return sb.toString();
    }
    public double getPrice(){
        double price = 0;
        for ( Part part: parts){
            price += part.getPrice();
        }
        return price;
    }   
}

public class CompositeDemo{
    public static void main(String args[]){
        Part engine = new Engine("DiselEngine",15000);
        Part trunk = new Trunk("Trunk",10000);
        Part body = new Body("Body",12000);

        Car car = new Car("Innova");
        car.addPart(engine);
        car.addPart(trunk);
        car.addPart(body);

        double price = car.getPrice();

        System.out.println("Car name:"+car.getName());
        System.out.println("Car parts:"+car.getPartNames());
        System.out.println("Car price:"+car.getPrice());
    }

}

输出:

Car name:Innova
Car parts:DiselEngine Trunk Body
Car price:37000.0

解释:

Part是一片叶子 汽车包含许多部件 汽车的不同部分已经添加到car中 汽车价格=(各部件价格)之和

关于组合和继承的利弊,请参考下面的问题。

喜欢组合而不是继承?

其他回答

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

继承是,这是带有扩展特性的前一个类。这意味着这个新类是具有一些扩展特性的旧类。 假设学生是学生,但所有的学生都是人。所以这是学生和人类之间的关系。这就是继承。

继承Vs组合。

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

继承主要用在IS-A一类算法编程模型中,关系类型是指相似类型的对象。的例子。

吸尘器是一辆车 Safari是一辆车

这些是Car家族的。

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

除非所有派生类都需要这些功能,否则不应该对基类进行更改。对于这个场景,我们应该使用Composition。如

由类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");
                       }
                   }

构图是指某物由不同的部分组成,并且它与这些部分之间有很强的关系。如果主体死亡,其他部分也会死亡,他们就不能拥有自己的生命。一个粗略的例子就是人体。取出心脏,其他部分就会消失。

继承就是你取已经存在的东西并使用它。没有很强的关系。一个人可以继承他父亲的财产,但他也可以不继承。

我不知道Java,所以我不能提供一个例子,但我可以提供一个概念的解释。

它们完全不同。继承是一种“是-是”关系。作文是“has-a”。

通过使用另一个类C的实例作为类的字段来进行组合,而不是扩展C。java.util就是一个很好的例子,其中组合比继承要好得多。堆栈,它目前扩展了java.util.Vector。现在看来,这是一个大错。堆栈“is-NOT-a”向量;不应该允许任意插入和删除元素。应该是合成。

不幸的是,现在纠正这个设计错误已经太晚了,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack使用组合而不是继承,那么它总是可以被修改为使用另一种数据结构,而不会违反API。

我强烈推荐Josh Bloch的《Effective Java第二版》

项目16:比起继承,更喜欢组合 项目17:设计和文件的继承或禁止

好的面向对象设计不是随意扩展现有的类。你的第一直觉应该是作曲。


参见:

组合与继承:两种基本的类关联方法的比较

组合和继承是一样的吗?

它们不一样。

组合:它允许以对象的单个实例的方式处理一组对象。组合的目的是将对象“组合”成树状结构,以表示部分-整体层次结构

继承:类从其所有超类继承字段和方法,无论是直接的还是间接的。子类可以覆盖它继承的方法,也可以隐藏它继承的字段或方法。

如果我想实现组合模式,我如何在Java中做到这一点?

维基百科的文章足以在java中实现复合模式。

主要参与者:

组件:

是所有组件的抽象,包括复合组件吗 声明组合中对象的接口

叶:

表示组合中的叶对象 实现所有组件方法

复合材料:

表示一个复合组件(有子组件) 实现操作子节点的方法 实现所有Component方法,通常是将它们委托给其子方法

理解Composite模式的代码示例:

import java.util.List;
import java.util.ArrayList;

interface Part{
    public double getPrice();
    public String getName();
}
class Engine implements Part{
    String name;
    double price;
    public Engine(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Trunk implements Part{
    String name;
    double price;
    public Trunk(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Body implements Part{
    String name;
    double price;
    public Body(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Car implements Part{
    List<Part> parts;
    String name;

    public Car(String name){
        this.name = name;
        parts = new ArrayList<Part>();
    }
    public void addPart(Part part){
        parts.add(part);
    }
    public String getName(){
        return name;
    }
    public String getPartNames(){
        StringBuilder sb = new StringBuilder();
        for ( Part part: parts){
            sb.append(part.getName()).append(" ");
        }
        return sb.toString();
    }
    public double getPrice(){
        double price = 0;
        for ( Part part: parts){
            price += part.getPrice();
        }
        return price;
    }   
}

public class CompositeDemo{
    public static void main(String args[]){
        Part engine = new Engine("DiselEngine",15000);
        Part trunk = new Trunk("Trunk",10000);
        Part body = new Body("Body",12000);

        Car car = new Car("Innova");
        car.addPart(engine);
        car.addPart(trunk);
        car.addPart(body);

        double price = car.getPrice();

        System.out.println("Car name:"+car.getName());
        System.out.println("Car parts:"+car.getPartNames());
        System.out.println("Car price:"+car.getPrice());
    }

}

输出:

Car name:Innova
Car parts:DiselEngine Trunk Body
Car price:37000.0

解释:

Part是一片叶子 汽车包含许多部件 汽车的不同部分已经添加到car中 汽车价格=(各部件价格)之和

关于组合和继承的利弊,请参考下面的问题。

喜欢组合而不是继承?