Composition: "Composition is dynamic binding (run-time binding) while Inheritance is static binding (compile time binding)"

I learned that "Composition" is used in classes when complex objects are build from smaller "Object composition". Composition models a "has-a" relationship so private inheritance plays a role.

However in this website:
http://www.w3resource.com/java-tutorial/inheritance-composition-relationship.php

I found this statement:
Composition is dynamic binding (run-time binding) while Inheritance is static binding (compile time binding)


Why is composition a dynamic binding?
> I found this statement:
> Composition is dynamic binding (run-time binding) while Inheritance is static binding (compile time binding)

The terminology that is used ('binding') is inaccurate. This is what it is trying to say:

In a statically typed language, there is a dichotomy between types (compile-time) and objects (run-time).
(For simplicity, we ignore constexpr objects for now.)

Inheritance is a compile-time relationship between types.
Composition is a run-time relationship between objects.

1
2
3
4
5
6
7
8
struct A : B // that B is the base class is specified at compile-time
             // it can never be changed (to say C) at run-time
{
    A( D* p ) :ptr(p) {}
    D* ptr ; // this may be changed at run-time to point to a different object
                // the dynamic type of the composed object is not known at compile-time
                // it may be any class directly or indirectly derived from D
};


In languages where 'everything is an object' is not a political statement
(it is a technical statement), this dichotomy does not exist; inheritance too can be a run-time relationship.

For example, Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def foo( base ) :
     class bar(base) : #inheritance
        def who_am_i(self) : return 'i am bar with base ' + str(base)
     return bar
    
def bar(x) : return foo(x.__class__) #class can be determined at run-time  

class_x = bar("abc")
class_y = bar(32)
class_z = bar( [1,foo,class_x] )

x = class_x( "class with the name 'this is a string'" )
y = class_y(23)
z = class_z()

print( x.who_am_i() )
print( y.who_am_i() )
print( z.who_am_i() )

if( y < 35 ) : print( x + " says hello" ) ;

http://rextester.com/TSOX99289
https://en.wikipedia.org/wiki/Strategy_pattern#Strategy_and_open.2Fclosed_principle
http://blog.berniesumption.com/software/inheritance-is-evil-and-must-be-destroyed/
You can change the behaviour of each ball at runtime: a bouncing ball can become a fading ball at any time.
In C++ you have a choice of how to do composition.

You can either store an object directly within another object. (1)

1
2
class A {};
class B { A obj; };

Or you could use a reference, pointer or smart pointer to refer to an object stored elsewhere. (2)

1
2
class A {};
class B { A* ptr = new A; };


If you use #1 the type of the inner object B::obj is known at compile time. There is no way it could be anything other than A.

If you use #2 the type of the object pointed to by A::ptr is not fixed at compile time. If there are other classes that inherits from A you could at runtime decide which of them the pointer should point to. If A has a virtual function that can be overriden by the derived classes it would not be known at compile time which version of a function that should be called. Instead the decision would have to be based on the dynamic type of the object at runtime. This is what "dynamic binding" refers to.

In Java you cannot store objects within objects. You always have to use a reference variable when referring to an object. This means only #2 is possible in Java, and because all non-static methods are virtual (i.e. they can be overriden) they have to be resolved at runtime (=dynamic binding).

I want to point out that I'm not totally sure what kind of optimizations is allowed in C++, and especially in Java. There might be situations where a clever compiler can (and is allowed to) resolve a virtual function call at compile time even though it's called through a pointer/reference variable.
Last edited on
Topic archived. No new replies allowed.