面向对象程序设计中，**转发**(forwarding)是指使用一个对象的成员（属性或方法）导致实际使用了另一个对象的对应的成员。即"转发"到另一个对象。转发被用于很多软件设计模式中，某些成员的使用被转发到别的对象，另外的成员由当前直接使用的对象使用。转发的对象可称作"包装对象）（wrapper object），显式转发的成员可称为包装函数。

与委托的区别
------

更多：委托\_(面向对象程序设计)
转发与委托在形式上是一对互补的概念。两种情况下，有2个对象，第一个（发送者、包装器）对象使用第二个（接收者、被包装者）对象，例如调用一个方法。两种情况的接收对象中的`self`指向不同的内容（可以理解为不同的运行时上下文）：对于委托，`self`指向发送者对象，对于转发，`self`指向接收者对象。`self`也常被隐式作为动态分派的一部分，即方法解析：方法名字指向了哪个函数。

委托类似于继承，允许行为复用(具体说代码复用)，转发类似于复合（英语：），执行仅依赖于接收者对象。两种情况，复用是动态的，在运行时确定其内容（基于委托或者转发到哪个对象）,而不是静态的（编译、链接时确定哪个类被"继承"）。

例子
--

Java的显式转发的例子：`B`的实例转发`foo`方法的调用给它的字段`a`:

```
class B {
 A a;
 T foo() { return a.foo(); }
}

```

当执行`a.foo()`, `this`对象是`a` (`A`的子类型), 不是最初对象的(`B`的实例)。进一步，`a`不必是`A`的实例，也可是其子类型的实例。甚至`A`不是一个类，而是接口/协议。

与继承相比较，`foo`定义于超类`A`中（必须是类，不能是接口），在子类B中调用方法，使用`A`中定义的代码，但`this`对象仍然是`B`的实例:

```
class A {
 T foo() { /\* ... \*/ };
}

class B extends A {
}

```

下述Python例子，类`B`转发`foo`方法调用和属性`x`到它的字段`a`的对象：

```
class A:
    def \_\_init\_\_(self, x) -> None:
        self.x = x

    def foo(self):
        print(self.x)

class B:
    def \_\_init\_\_(self, a) -> None:
        self.a = a

    def foo(self):
        self.a.foo()

    @property
    def x(self):
        return self.a.x

    @x.setter
    def x(self, x):
        self.a.x = x

    @x.deleter
    def x(self):
        del self.a.x

a = A(42)
b = B(a)
b.foo()  # Prints '42'.
b.x  # Has value '42'
b.x = 17   # b.a.x now has value 17
del b.x  # Deletes b.a.x.

```

### 简单示例

```
class RealPrinter { // the "receiver"
 void print() { 
 System.out.println("Hello world!"); 
 }
}

class Printer { // the "sender"
 RealPrinter p = new RealPrinter(); // create the receiver
 void print() {
 p.print(); // calls the receiver
 }
}
 
public class Main {
 public static void main(String[] arguments) {
 // to the outside world it looks like Printer actually prints.
 Printer printer = new Printer();
 printer.print();
 }
}

```

### 复杂示例

装饰模式使用接口，转发更为灵活且类型安全。下例子中，灵活是指类`C`不需要引用类`A`或`B`，类C可以转发到任何实现了接口`I`的类。 

```
interface I {
 void f();
 void g();
}
 
class A implements I {
 public void f() { System.out.println("A: doing f()"); }
 public void g() { System.out.println("A: doing g()"); }
}
 
class B implements I {
 public void f() { System.out.println("B: doing f()"); }
 public void g() { System.out.println("B: doing g()"); }
}
 
// changing the implementing object in run-time (normally done in compile time)
class C implements I {
 I i = null;
 // forwarding
 public C(I i){ setI(i); }
 public void f() { i.f(); }
 public void g() { i.g(); }
 
 // normal attributes
 public void setI(I i) { this.i = i; }
}
 
public class Main {
 public static void main(String[] arguments) {
 C c = new C(new A());
 c.f(); // output: A: doing f()
 c.g(); // output: A: doing g()
 c.setI(new B());
 c.f(); // output: B: doing f()
 c.g(); // output: B: doing g()
 }
}

```

应用
--

转发可用于许多设计模式。 Forwarding is used directly in several patterns:

* 责任链模式
* 装饰模式: 装饰器对象增加自己的成员，把其余成员的调用转发给被装饰对象。
* 代理模式: 代理对象把对成员的使用转发给真正的对象。

转发也可以用于其他设计模式，但可能是修改过的转发：

* 适配器模式
* 桥接模式
* 外观模式

参考文献
----

1. ↑  Büchi, Martin; Weck, Wolfgang.  (PDF).. Lecture Notes in Computer Science **1850**. 2000: 212–213  [2022-04-16]. ISBN 978-3-540-67660-7. doi:10.1007/3-540-45102-1\_10. （原始内容 (PDF)存档于2022-07-12）.
2. ↑  Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John.. Addison-Wesley. 1995. Bibcode:1995dper.book.....G. ISBN 978-0-201-63361-0.