13.6. OOP Inheritance

13.6.1. Rationale

  • Child inherits all fields and methods from parent

  • Used to avoid code duplication

parent
superclass
base class

Class from other classes inherits

child
subclass

Class which inherits from parent

13.6.2. Syntax

>>> class Parent:
...     def say_hello(self):
...         return 'Hello'
>>>
>>> class Child(Parent):
...     pass
>>>
>>>
>>> obj = Child()
>>> obj.say_hello()
'Hello'

13.6.3. Simple Inheritance

>>> class Person:
...     def __init__(self, firstname, lastname):
...         self.firstname = firstname
...         self.lastname = lastname
>>>
>>> class Astronaut(Person):
...     pass
>>>
>>> class Cosmonaut(Person):
...     pass
>>>
>>>
>>> mark = Astronaut('Mark', 'Watney')
>>> ivan = Cosmonaut('Ivan', 'Ivanovic')

13.6.4. Multilevel Inheritance

>>> class Person:
...     pass
>>>
>>> class Pilot(Person):
...     pass
>>>
>>> class Astronaut(Pilot):
...     pass
>>>
>>>
>>> watney = Astronaut()
>>> type(watney)
<class 'Astronaut'>
>>> isinstance(watney, Person)
True
>>> isinstance(watney, Pilot)
True
>>> isinstance(watney, Astronaut)
True

13.6.5. Multiple Inheritance

>>> class Person:
...     pass
>>>
>>> class Pilot:
...     pass
>>>
>>> class Astronaut(Person, Pilot):
...     pass
>>>
>>>
>>> watney = Astronaut()
>>> type(watney)
<class 'Astronaut'>
>>> isinstance(watney, Person)
True
>>> isinstance(watney, Pilot)
True
>>> isinstance(watney, Astronaut)
True

13.6.6. Overload

>>> class A:
...     def show(self):
...         return 'a'
>>>
>>> class B(A):
...     pass
>>>
>>>
>>> B().show()
'a'
>>> class A:
...     def show(self):
...         return 'a'
>>>
>>> class B(A):
...     def show(self):
...         return 'b'
>>>
>>>
>>> B().show()
'b'
>>> class Person:
...     lastname = 'Watney'
...
...     def hello(self):
...         print(f'Hello {self.firstname} {self.lastname}')
>>>
>>>
>>> class Astronaut(Person):
...     firstname = 'Mark'
>>>
>>>
>>> a = Astronaut()
>>> a.hello()
Hello Mark Watney

13.6.7. Use Cases

>>> class Iris:
...     def __init__(self, sepal_length, sepal_width,
...                  petal_length, petal_width, species):
...
...         self.sepal_length = sepal_length
...         self.sepal_width = sepal_width
...         self.petal_length = petal_length
...         self.petal_width = petal_width
...         self.species = species
>>>
>>>
>>> class Setosa(Iris):
...     pass
>>>
>>> class Versicolor(Iris):
...     pass
>>>
>>> class Virginica(Iris):
...     pass
>>>
>>>
>>> setosa = Setosa(
...     sepal_length=5.1,
...     sepal_width=3.5,
...     petal_length=1.4,
...     petal_width=0.2,
...     species='setosa')

13.6.8. Assignments

Code 13.11. Solution
"""
* Assignment: OOP Inheritance Simple
* Required: yes
* Complexity: easy
* Lines of code: 4 lines
* Time: 3 min

English:
    1. Create class `Woman` which inherits from `Venus`
    2. Create class `Man` which inherits from `Mars`
    3. Run doctests - all must succeed

Polish:
    1. Stwórz klasę `Woman`, która dziedziczy po `Venus`
    2. Stwórz klasę `Man`, która dziedziczy po `Mars`
    3. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from inspect import isclass

    >>> assert isclass(Venus)
    >>> assert isclass(Woman)
    >>> assert isclass(Mars)
    >>> assert isclass(Man)
    >>> assert issubclass(Woman, Venus)
    >>> assert issubclass(Man, Mars)
"""


class Venus:
    pass


class Mars:
    pass


Code 13.12. Solution
"""
* Assignment: OOP Inheritance Multiple
* Required: yes
* Complexity: easy
* Lines of code: 2 lines
* Time: 2 min

English:
    1. Create class `Astronaut` which inherits from all of those classes
    2. Run doctests - all must succeed

Polish:
    1. Stwórz klasę `Astronaut`, która dziedziczy po tych wszystkich klasach
    2. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0
    >>> from inspect import isclass

    >>> assert isclass(Scientist)
    >>> assert isclass(Engineer)
    >>> assert isclass(Pilot)
    >>> assert isclass(MedicalDoctor)
    >>> assert isclass(Astronaut)
    >>> assert issubclass(Astronaut, Scientist)
    >>> assert issubclass(Astronaut, Engineer)
    >>> assert issubclass(Astronaut, Pilot)
    >>> assert issubclass(Astronaut, MedicalDoctor)
"""


class Scientist:
    pass


class Engineer:
    pass


class Pilot:
    pass


class MedicalDoctor:
    pass