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