Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 继承与组合的区别_Java_Oop_Inheritance_Composition - Fatal编程技术网

Java 继承与组合的区别

Java 继承与组合的区别,java,oop,inheritance,composition,Java,Oop,Inheritance,Composition,组成和继承是一样的吗? 如果我想实现组合模式,我该如何在Java中实现呢?它们完全不同。继承是一种“是一种”关系。作文是一个“has-a” 通过将另一个类的实例C作为类的字段,而不是扩展C,可以进行组合。组合比继承好得多的一个好例子是java.util.Stack,它目前扩展了java.util.Vector。这现在被认为是一个错误。堆栈“不是”向量;不应允许您任意插入和删除元素。应该是作文 不幸的是,现在纠正这个设计错误为时已晚,因为现在更改继承层次结构将破坏与现有代码的兼容性。如果Stack

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

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

通过将另一个类的实例
C
作为类的字段,而不是扩展
C
,可以进行组合。组合比继承好得多的一个好例子是
java.util.Stack
,它目前扩展了
java.util.Vector
。这现在被认为是一个错误。堆栈“不是”向量;不应允许您任意插入和删除元素。应该是作文

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

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

  • 第16项:偏爱组合而非继承
  • 第17项:继承或禁止的设计和文件
好的面向对象设计不是对现有类进行大量扩展。你的第一反应应该是作曲


另见:


作为另一个例子,考虑一个Car类,这将是一个很好的使用构图,一个汽车将有一个引擎,一个变速器,轮胎,座椅等。它不会扩展任何一个类。

组成意味着<代码>有一个< /代码> BR> 继承意味着

是一个

示例
:汽车有一个发动机,而汽车是一辆汽车

在编程中,这表示为:

class Engine {} // The Engine class.

class Automobile {} // Automobile class which is parent to Car class.

class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}

构图和听起来一样——你通过插入部分来创建一个对象

编辑此答案的其余部分错误地基于以下前提。
这是通过接口实现的。
例如,使用上面的
汽车
示例

Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel
因此,使用一些标准的理论组件,您可以构建您的对象。然后,你的工作就是填写
房子
如何保护居住者,以及
汽车
如何保护居住者

继承与此相反。从一个完整(或半完整)的对象开始,替换或覆盖要更改的各个位

例如,
机动车辆
可能带有
可供燃料
方法和
驾驶
方法。您可以保留燃油方法,因为它与加注摩托车和汽车的方法相同,但您可以覆盖
Drive
方法,因为摩托车的驾驶方式与
汽车的驾驶方式非常不同

有了继承,一些类已经完全实现了,而另一些类则具有强制重写的方法。有了作文,你什么也没得到。(但是,如果您碰巧有什么东西,您可以通过调用其他类中的方法来实现接口)

合成被认为是更灵活的,因为如果你有一个方法,比如iUsesFuel,你可以在其他地方(另一个类,另一个项目)有一个方法,它只担心处理可以添加燃料的对象,不管它是汽车,船,炉子,烧烤,接口要求说实现该接口的类实际上拥有该接口所涉及的方法。比如说,

iFuelable Interface:
   void AddSomeFuel()
   void UseSomeFuel()
   int  percentageFull()
然后你可以在别的地方找到一个方法

private void FillHerUp(iFuelable : objectToFill) {

   Do while (objectToFill.percentageFull() <= 100)  {

        objectToFill.AddSomeFuel();
   }
private void FillHerUp(如果可用:objectToFill){

Do while(objectToFill.percentageFull()Michael Rodrigues给出的答案不正确(很抱歉,我无法直接评论),可能会导致一些混乱

接口实现…当您实现一个接口时,您不仅继承了所有常量,还将对象提交为接口指定的类型;它仍然是一个“is-a”关系。如果一辆汽车实现了filleble,那么汽车“就是-a”可填充的,并且可以在任何需要使用可填充的代码中使用

合成与继承有着根本的不同。当你使用合成时,你(正如其他答案所指出的)在两个对象之间建立了一种“是一种”关系,而不是使用继承时建立的“是一种”关系

因此,从其他问题中的汽车示例来看,如果我想说一辆汽车“有一个”油箱,我会使用成分,如下所示:

public class Car {

private GasTank myCarsGasTank;

}

希望这能消除任何误解。

继承带来了IS-A关系。组合带来了HAS-A关系。 Strategy pattern(策略模式)解释说,在有一系列算法定义特定行为的情况下,应该使用组合。
典型的例子是实现飞行行为的duck类

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

 public Duck(){
  fly = new BackwardFlying();
 }
}
因此,我们可以有多个实现飞行的类 例如:

如果是为了继承,我们会有两个不同的类,它们一遍又一遍地实现fly函数。因此继承和组合是完全不同的。

两个类之间的继承,其中一个类扩展另一个类建立了“是一种关系


另一端的组合包含类中另一个类的实例,从而建立“具有”关系。java中的组合很有用,因为它在技术上促进了多重继承。

继承有多危险

让我们举个例子

public class X{    
   public void do(){    
   }    
}    
Public Class Y extends X{
   public void work(){    
       do();    
   }
}
1) 正如上面代码中所清楚的,类Y与类X有很强的耦合。如果超类X中有任何变化,Y可能会急剧中断。假设
public class X{    
   public void do(){    
   }    
}    
Public Class Y extends X{
   public void work(){    
       do();    
   }
}
public int work(){
}
public class X{
    public void do(){
    }
}

Public Class Y{
    X x = new X();    
    public void work(){    
        x.do();
    }
}
class X implements R
{}
class Y implements R
{}

public class Test{    
    R r;    
}
public class X {
    public void do(){
    }
}

Public Class Y {
    X x = new X();    
    public void work(){    
        x.do();    
    }    
}
Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b = new Deposit();    
        if(b.deposit()){    
            b = new Credit();
            c.credit();    
        }
    }
}
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
          // 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");
                       }
                   }