Object Composition

Objects can be attributes of other objects.

You can use this mechanism to represent relationships between objects. For instance you could model one-to-one, one-to-many or many-to-many relationships. This has some similarity to database design, but with classes you have more options.

Object Composition is something you use in Python all the time, e.g. when you have a list of integers and refer to the first item of the list, you are accessing an int object inside a list object.

Modeling classes using Object Composition is one of the most important techniques in Object-Oriented-Programming. Look up the terms Object-Oriented-Design and Design Patterns for further reading.

Here are two examples:


Example 1: Bank

Imagine you want to have a Bank class that represents many accounts.

A very bad design solution would be:

Bank is a subclass of Account

This violates Liskovs Substitution Principle. A bank is not a special type of account!

A better design solution would be:

A Bank contains many Accounts

An implementation could look like this:

class Bank:

    def __init__(self):
        self.accounts = {}

    def add_account(self, number, accounts):
        self.accounts[number] = account


barclays = Bank()
ada = Account('Ada Lovelace', 100)
barclays.add_account(1234, ada)
barclays.add_account(5555, Account('Bob', 255))

Example 2:Composite Pattern

In this exaple, Node objects contain other Node objects and Leaf objects to construct a tree. The traverse() method walks across all nodes in the tree.

class Node:

    def __init__(self, *args):
        self.subnodes = args

    def traverse(self):
        result = []
        for n in self.subnodes:
            result += n.traverse()
        return result


class Leaf:

    def __init__(self, name):
        self.value = name

    def traverse(self):
        return [self.value]


my_tree = Node(
            Node(
                Node(
                    Leaf('gorilla'),
                    Node(
                        Leaf('chimp'), Leaf('human')
                        )
                    ),
                Node(
                    Leaf('cat'),Leaf('dog')
                    ),
                ),
            Node(
                Node(
                    Leaf('chicken'),
                    Node(
                        Leaf('lizard'),Leaf('turtle')
                        ),
                    ),
                Node(
                    Leaf('shark')
                    ),
                )
            )

print(my_tree.traverse())

Dr. Kristian Rother

I am a professional Python trainer, developer and author based in Berlin. I believe everybody can learn programming.

Contact me via:
+49 176 3052 4691
krother@academis.eu

Feedback

BTW students were really impressed by my storytelling skills I demonstrated in class impromptu and was applausing at the end of the class... its all because of your excellent teaching, thank you!!

Kevin Wong, Data Scientist

See also