Java中继承与委派的区别

What is the Difference between inheritance and delegation in java

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Prefer composition over inheritance?

Java中继承和委派的区别是什么?

如何在我的项目中使用以下示例?请你代表团来指导我。我知道继承,但对委托不太了解。所以,请给出一个适当的理由。我为什么要用这个?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 package com.m;

 class RealPrinter { // the"delegate"
     void print() {
      System.out.println("something");
    }
 }

 class Printer { // the"delegator"
     RealPrinter p = new RealPrinter(); // create the delegate
     void print() {
     p.print(); // delegation
     }
 }

 public class Tester {

// to the outside world it looks like Printer actually prints.
     public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
     }

   }


当您委托时,您只是调用了一些知道必须做什么的类。你并不真正关心它是如何做到的,你所关心的只是你打电话给的班级知道你需要做什么。

如果我是你的话,我会创建一个接口并将其命名为IPrinter(或者沿着这些行命名的东西),它有一个名为print的方法。然后我会让RealPrinter实现这个接口。最后,我将把这一行改为:RealPrinter p = new RealPrinter();IPrinter p = new RealPrinter()

由于RealPrinter实现了IPrinter,所以我确信它有一个print方法。然后,我可以使用此方法通过将应用程序委托给适当的类来更改其打印行为。

这通常允许更多的灵活性,因为您不将行为嵌入到特定的类中,而是将其留给另一个类。

在这种情况下,要更改应用程序关于打印的行为,只需创建另一个实现IPrinter的类,然后将此行更改为:IPrinter p = new RealPrinter();IPrinter p = new MyOtherPrinter();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public interface IPrinter {
    void print();
}

public class RealPrinter implements IPrinter {

    @Override
    public void print() {
        System.out.println("This is RealPrinter");
    }
}

public class RealPrinter2 implements IPrinter {

    @Override
    public void print() {
        System.out.println("This is RealPrinter2");
    }
}

public class Main {

    public static void main(String...arg){
        IPrinter printer  = new RealPrinter();
        printer.print();

        printer = new RealPrinter2();
        printer.print();
    }
}

继承使用Java编译器的类型系统隐式地包含来自别处的代码,用委托您显式实现标注。

继承仅限于一个父类(和祖先类),但有时代码的去向并不明显;委托不那么优雅,但您可以从多个其他类引入功能,并且流清晰可见。

就调用外部函数而言,委托通常是首选的,因为这个原因,继承应该保留在您想要实现一个行为特别类似于基类的类的情况下,因此它基本上可以被其他代码(即它是多态的)视为基类的实例。