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


当前回答

两个类之间的继承,其中一个类扩展了另一个类,建立了“IS A”关系。

另一端的组合包含类中另一个类的实例,建立了“Has A”关系。组合在java中是很有用的,因为它在技术上便于多重继承。

其他回答

组合意味着有A 继承意味着IS A

例子:Car有引擎,Car是一辆汽车

在编程中,这被表示为:

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.
}

遗产怎么会是危险的?

让我们举个例子

public class X{    
   public void do(){    
   }    
}    
Public Class Y extends X{
   public void work(){    
       do();    
   }
}

1)正如上面的代码所示,类Y与类X具有很强的耦合性。如果超类X发生任何变化,Y可能会急剧断裂。假设在未来的类X中实现了一个具有以下签名的方法work

public int work(){
}

改变是在类X中完成的,但它将使类Y不可编译。所以这种依赖可以上升到任何程度,这是非常危险的。每次超类都可能对其所有子类中的代码没有完全可见性,子类可能会一直注意到在超类中发生了什么。因此,我们需要避免这种强而不必要的耦合。

合成如何解决这个问题?

让我们复习一下同样的例子

public class X{
    public void do(){
    }
}

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

这里我们在Y类中创建X类的引用,并通过创建X类的实例调用X类的方法。 现在所有的强耦合都消失了。父类和子类现在彼此高度独立。类可以自由地进行更改,这在继承情况下是危险的。

2)第二个非常好的优点是它提供了方法调用的灵活性,例如:

class X implements R
{}
class Y implements R
{}

public class Test{    
    R r;    
}

在测试类中使用r引用,我可以调用X类以及Y类的方法。这种灵活性在继承中是不存在的

3)另一个巨大优势:单元测试

public class X {
    public void do(){
    }
}

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

在上面的例子中,如果x实例的状态未知,可以用一些测试数据很容易地模拟出来,所有的方法都可以很容易地测试出来。这在继承中是完全不可能的,因为您严重依赖于超类来获取实例的状态并执行任何方法。

4)我们应该避免继承的另一个很好的理由是Java不支持多重继承。

让我们举个例子来理解这一点:

Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b = new Deposit();    
        if(b.deposit()){    
            b = new Credit();
            c.credit();    
        }
    }
}

很高兴知道:

组合在运行时很容易实现,而继承在编译时提供其特性 组合也称为HAS-A关系,继承也称为is - a关系

因此,由于上述各种原因,要养成总是喜欢组合而不是继承的习惯。

另一个例子,考虑一个汽车类,这将是一个很好的组合使用,一个汽车将“有”一个发动机,一个变速器,轮胎,座位,等等。它不会扩展任何这些类。

继承带来IS-A关系。复合引出HAS-A关系。 策略模式解释了组合应该用于定义特定行为的算法族的情况。典型的例子是实现飞行行为的鸭子类。

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

 public Duck(){
  fly = new BackwardFlying();
 }
}

因此,我们可以有多个实现飞行的类 例如:

public class BackwardFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies backward ");
  }
}
public class FastFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies 100 miles/sec");
  }
}

如果是继承的话,我们就会有两个不同的鸟类,它们会反复实现fly函数。所以继承和组合是完全不同的。

不,两者都不一样。组合遵循“HAS-A”关系,继承遵循“IS-A”关系。组合的最佳例子是战略模式。