12.21. OOP Inheritance Super¶
super()
Calls a method from superclassOrder/location is important
Raymond Hettinger - Super considered super! - PyCon 2015 1
12.21.1. Super With Methods¶
>>> class Parent:
... def say_hello(self):
... print('hello')
>>>
>>>
>>> class Child(Parent):
... def say_hello(self):
... super().say_hello()
... print('yo')
>>>
>>>
>>> obj = Child()
>>> obj.say_hello()
hello
yo
Order of super()
is important:
>>> class Parent:
... def say_hello(self):
... print('hello')
>>>
>>>
>>> class Child(Parent):
... def say_hello(self):
... print('yo')
... super().say_hello()
>>>
>>>
>>> obj = Child()
>>> obj.say_hello()
yo
hello
12.21.2. Super With Attributes¶
>>> class Parent:
... def __init__(self):
... self.firstname = 'Mark'
... self.lastname = 'Watney'
>>>
>>>
>>> class Child(Parent):
... def __init__(self):
... super().__init__()
... self.job = 'astronaut'
>>>
>>>
>>> obj = Child()
>>> vars(obj)
{'firstname': 'Mark', 'lastname': 'Watney', 'job': 'astronaut'}
12.21.3. Super Attributes Problem¶
Note, that the problem exists when Parent and a Child defines attribute with the
same name. Than while calling super()
it will overload field value.
>>> class Parent:
... def __init__(self):
... self.firstname = 'Mark'
... self.lastname = 'Watney'
... self.job = 'unemployed'
>>>
>>>
>>> class Child(Parent):
... def __init__(self):
... self.job = 'astronaut'
... super().__init__()
>>>
>>>
>>> obj = Child()
>>> vars(obj)
{'job': 'unemployed', 'firstname': 'Mark', 'lastname': 'Watney'}
>>> class Parent:
... def __init__(self):
... self.firstname = 'Mark'
... self.lastname = 'Watney'
... self.job = 'unemployed'
>>>
>>>
>>> class Child(Parent):
... def __init__(self):
... super().__init__()
... self.job = 'astronaut'
>>>
>>>
>>> obj = Child()
>>> vars(obj)
{'firstname': 'Mark', 'lastname': 'Watney', 'job': 'astronaut'}
12.21.4. Super Init with Args¶
>>> class Parent:
... def __init__(self, firstname, lastname):
... self.firstname = 'Mark'
... self.lastname = 'Watney'
... self.job = 'unemployed'
>>>
>>>
>>> class Child(Parent):
... def __init__(self, firstname, lastname):
... super().__init__(firstname, lastname)
... self.job = 'astronaut'
>>>
>>>
>>> obj = Child('Mark', 'Watney')
>>> vars(obj)
{'firstname': 'Mark', 'lastname': 'Watney', 'job': 'astronaut'}
12.21.5. References¶
12.21.6. Assignments¶
"""
* Assignment: OOP Overload Super
* Required: yes
* Complexity: easy
* Lines of code: 6 lines
* Time: 5 min
English:
1. Create class `Astronaut` which inherits from `Person`
2. Class `Astronaut` takes two arguments `name` and `mission`
3. Set attribute `mission` in `Astronaut` inicializer method
4. Call initializer method of `Person` passing `name` as an argument
5. Define method `show()` returning name and after coma - a mission name
6. Run doctests - all must succeed
Polish:
1. Stwórz klasę `Astronaut` dziedziczącą po `Person`
2. Klasa `Astronaut` przyjmuje dwa argumenty `name` i `mission`
3. Ustaw atrybut `mission` w metodzie inicjalizacyjnej w `Astronaut`
4. Wywołaj metodę inicjalizacyjną z `Person` podając `name` jako argument
5. Zdefiniuj metodę `show()` zwracającą imię i po przecinku - nazwę misji
6. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> watney = Astronaut('Watney', 'Ares 3')
>>> watney.show()
'Watney, Ares 3'
>>> lewis = Astronaut('Lewis', 'Ares 3')
>>> lewis.show()
'Lewis, Ares 3'
"""
class Person:
def __init__(self, name):
self.name = name