Jump to content

Forwarding (object-oriented programming)

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Nbarth (talk | contribs) at 22:32, 10 April 2016 (top: fix link). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

In object-oriented programming, forwarding means that using a member of an object (either a property or a method) results in actually using the corresponding member of a different object: the use is forwarded to another object. Forwarding is used in a number of design patterns, where some members are forwarded to another object, while others are handled by the directly used object. The forwarding object is frequently called a wrapper object, and explicit forwarding members are called wrapper functions.

Forwarding is a simple form of delegation, and is distinguished from more general delegation in that in forwarding, the original object is not used by the delegate, and the delegation is a direct pass-through. Forwarding fulfills a similar purpose to inheritance, in allowing behavioral reuse (and concretely code reuse), but differs in having two separate objects, rather than a single object. In fact, in prototype-based programming, inheritance is typically implemented by delegation (retaining the original object); while in class-based programming forwarding allows reuse to be determined at run time (based on the object to which use is forwarded), rather than at compile time (based on the class which is inherited from). Forwarding is thus considerably more flexible than inheritance, but potentially more complex as well.

Examples

A simple example of explicit forwarding in Java: an instance of B forwards calls to the foo method to its a field:

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

Note that when executing a.foo(), the this object is a (a subtype of A), not the original object (an instance of B). Further, a need not be an instance of A: it may be an instance of a subtype. Indeed, A need not even be a class: it may be an interface/protocol.

Contrast with inheritance, in which foo is defined in a superclass A (which must be a class, not an interface), and when called on an instance of a subclass B, it uses the code defined in A, but the this object is still an instance of B:

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

class B extends A {
}

In this Python example, class B forwards the foo method and the x property to the object in its a field: using these on b (an instance of B) is the same as using them on b.a (the instance of A to which these are forwarded).

class A:
    def __init__(self, x):
        self.x = x

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

class B:
    def __init__(self, a):
        self.a = a

    def foo(self):
        a.foo()

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

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

    @x.deleter
    def x(self):
        del 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.

Applications

Forwarding is used in many design patterns.[1] Forwarding is used directly in several patterns:

Forwarding may be used in other patterns, but often use is modified; for example, a method call on one object results in several different methods being called on another:

References

  1. ^ Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 0-201-63361-2.