5.9. OOP Inheritance Patterns¶
no inheritance
single inheritance
multilevel inheritance
multiple inheritance (mixin classes)
- single inheritance¶
One class inherits from one other class. Has one parent.
- multilevel inheritance¶
One class inherits from other class, and yet another class inherits from it. This creates hierarchical structure.
- multiple inheritance¶
- mixin classes¶
One class derives from several other classes at once.
5.9.1. No Inheritance¶
>>> class Parent:
... pass
>>>
>>>
>>> class Child:
... pass
5.9.2. Single Inheritance¶
>>> class Parent:
... pass
>>>
>>>
>>> class Child(Parent):
... pass

5.9.3. Multilevel Inheritance¶
>>> class Grandparent:
... pass
>>>
>>>
>>> class Parent(Grandparent):
... pass
>>>
>>>
>>> class Child(Parent):
... pass

5.9.4. Composition¶
>>> class Mother:
... pass
>>>
>>> class Father:
... pass
>>>
>>>
>>> class Child:
... mother: Mother
... father: Father
...
... def __init__(self):
... self.mother = Mother()
... self.father = Father()
5.9.5. Aggregation¶
>>> class Parent:
... pass
>>>
>>> class Mother(Parent):
... pass
>>>
>>> class Father(Parent):
... pass
>>>
>>>
>>> class Child:
... parents: list[Parent]
...
... def __init__(self):
... self.parents = []
... self.parents.append(Mother())
... self.parents.append(Father())
5.9.6. Multiple Inheritance¶
Mother
andFather
are Mixin Classes
>>> class Mother:
... pass
>>>
>>>
>>> class Father:
... pass
>>>
>>>
>>> class Child(Mother, Father):
... pass
5.9.7. Use Case - 0x01¶
>>> class Mother:
... def say_hello(self):
... pass
>>>
>>> class Father:
... def say_hello(self):
... pass
>>>
>>>
>>> class Child:
... father: Father
... mother: Mother
...
... def __init__(self, mother: Mother = Mother(), father: Father = Father()):
... self.mother = mother
... self.father = father
...
... def father_say_hello(self):
... self.father.say_hello()
...
... def mother_say_hello(self):
... self.mother.say_hello()
5.9.8. Use Case - 0x02¶
>>> from json import JSONEncoder, JSONDecoder
>>>
>>>
>>> class User:
... json_encoder: JSONEncoder
... json_decoder: JSONDecoder
...
... def __init__(self,
... json_encoder: JSONEncoder = JSONEncoder(),
... json_decoder: JSONDecoder = JSONDecoder(),
... ) -> None:
... self.json_encoder = json_encoder
... self.json_decoder = json_decoder
...
... def json_encode(self, data):
... self.json_encoder.encode(data)
...
... def json_decoder(self, data):
... self.json_decoder.decode(data)
5.9.9. Assignments¶
"""
* Assignment: OOP Composition Multilevel
* Complexity: easy
* Lines of code: 8 lines
* Time: 3 min
English:
1. Create class `MarsMission` from classes `Habitat`, `Rocket`, `Astronaut`
2. Use multilevel inheritance
3. Assignment demonstrates syntax, so do not add any attributes and methods
4. Run doctests - all must succeed
Polish:
1. Stwórz klasę `MarsMission` z klas `Habitat`, `Rocket`, `Astronaut`
2. Użyj wielopoziomowego dziedziczenia
3. Zadanie demonstruje składnię, nie dodawaj żadnych atrybutów i metod
4. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(Habitat)
>>> assert isclass(Astronaut)
>>> assert isclass(Rocket)
>>> assert isclass(MarsMission)
>>> assert issubclass(MarsMission, Habitat)
>>> assert issubclass(MarsMission, Astronaut)
>>> assert issubclass(MarsMission, Rocket)
>>> assert len(Habitat.__subclasses__()) == 1
>>> assert len(Astronaut.__subclasses__()) == 1
>>> assert len(Rocket.__subclasses__()) == 1
>>> assert len(MarsMission.__subclasses__()) == 0
"""
"""
* Assignment: OOP Composition Composition
* Complexity: easy
* Lines of code: 10 lines
* Time: 3 min
English:
1. Create class `MarsMission` from classes `Habitat`, `Rocket`, `Astronaut`
2. Use composition
3. Assignment demonstrates syntax, so do not add any attributes and methods (only type annotations)
4. Run doctests - all must succeed
Polish:
1. Stwórz klasę `MarsMission` z klas `Habitat`, `Rocket`, `Astronaut`
2. Użyj kompozycji
3. Zadanie demonstruje składnię, nie dodawaj żadnych atrybutów i metod (tylko anotacje typów)
4. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(Habitat)
>>> assert isclass(Astronaut)
>>> assert isclass(Rocket)
>>> assert isclass(MarsMission)
>>> assert MarsMission.__annotations__['habitat'] is Habitat
>>> assert MarsMission.__annotations__['astronaut'] is Astronaut
>>> assert MarsMission.__annotations__['rocket'] is Rocket
"""
"""
* Assignment: OOP Composition Mixin
* Complexity: easy
* Lines of code: 8 lines
* Time: 3 min
English:
1. Create class `MarsMission` from classes `Habitat`, `Rocket`, `Astronaut`
2. Use mixins classes
3. You can modify given classes
4. Assignment demonstrates syntax, so do not add any attributes and methods
5. Run doctests - all must succeed
Polish:
1. Stwórz klasę `MarsMission` z klas `Habitat`, `Rocket`, `Astronaut`
2. Użyj klas domieszkowych (mixin)
3. Możesz modyfikować dane klasy
4. Zadanie demonstruje składnię, nie dodawaj żadnych atrybutów i metod
5. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(Habitat)
>>> assert isclass(Astronaut)
>>> assert isclass(Rocket)
>>> assert isclass(MarsMission)
>>> assert issubclass(MarsMission, Habitat)
>>> assert issubclass(MarsMission, Astronaut)
>>> assert issubclass(MarsMission, Rocket)
>>> assert len(Habitat.__subclasses__()) == 1
>>> assert len(Astronaut.__subclasses__()) == 1
>>> assert len(Rocket.__subclasses__()) == 1
>>> assert len(MarsMission.__subclasses__()) == 0
"""