4.1. Inheritance About
no inheritance
single inheritance
multilevel inheritance
multiple inheritance (mixin classes)
aggregation
composition
- 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.
4.1.1. No Inheritance
class User:
pass
class Staff:
pass
class Admin:
pass
4.1.2. Single Inheritance
class User:
pass
class Staff(User):
pass
class Admin(User):
pass
4.1.3. Multilevel Inheritance
class User:
pass
class Staff(User):
pass
class Admin(Staff):
pass
4.1.4. Multiple Inheritance
class User:
pass
class Staff:
pass
class Admin(User, Staff):
pass
4.1.5. Aggregation
class User:
pass
class Staff:
pass
class Admin:
def __init__(self):
self.permissions = [User(), Staff()]
4.1.6. Composition
class User:
pass
class Staff:
pass
class Admin:
def __init__(self):
self.user = User()
self.staff = Staff()
4.1.7. Further Reading
4.1.8. Assignments
"""
* Assignment: Inheritance About None
* Complexity: easy
* Lines of code: 8 lines
* Time: 3 min
English:
1. Define classe `Account`
2. Define classe `User`
3. Define classe `Admin`
4. Do not use inheritance
5. Assignment demonstrates syntax, so do not add any attributes and methods
6. Run doctests - all must succeed
Polish:
1. Zdefiniuj klasę `Account`
2. Zdefiniuj klasę `User`
3. Zdefiniuj klasę `Admin`
4. Nie używaj dziedziczenia
5. Zadanie demonstruje składnię, nie dodawaj żadnych atrybutów i metod
6. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(Account)
>>> assert isclass(User)
>>> assert isclass(Admin)
>>> assert not issubclass(User, Account)
>>> assert not issubclass(Admin, Account)
>>> assert len(Account.__subclasses__()) == 0
>>> assert len(User.__subclasses__()) == 0
>>> assert len(Admin.__subclasses__()) == 0
"""
# Define classe `Account`
...
# Define classe `User`
...
# Define classe `Admin`
...
"""
* Assignment: Inheritance About Single
* Complexity: easy
* Lines of code: 8 lines
* Time: 3 min
English:
1. Define class `Account`
2. Define classe `User` inheriting from `Account`
3. Define classe `Admin` inheriting from `Account`
4. Use single inheritance
5. Assignment demonstrates syntax, so do not add any attributes and methods
6. Run doctests - all must succeed
Polish:
1. Zdefiniuj klasę `Account`
2. Zdefiniuj klasę `User` dziedziczacą po `Account`
3. Zdefiniuj klasę `Admin` dziedziczacą po `Account`
4. Użyj pojedynczego dziedziczenia
5. Zadanie demonstruje składnię, nie dodawaj żadnych atrybutów i metod
6. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(Account)
>>> assert isclass(User)
>>> assert isclass(Admin)
>>> assert issubclass(User, Account)
>>> assert issubclass(Admin, Account)
>>> assert len(Account.__subclasses__()) == 2
>>> assert len(User.__subclasses__()) == 0
>>> assert len(Admin.__subclasses__()) == 0
"""
# Define class `Account`
...
# Define classe `User` inheriting from `Account`
...
# Define classe `Admin` inheriting from `Account`
...
"""
* Assignment: Inheritance About Multilevel
* Complexity: easy
* Lines of code: 8 lines
* Time: 3 min
English:
1. Define class `Account`
2. Define classe `User` inheriting from `Account`
3. Define classe `Admin` inheriting from `User`
4. Use multilevel inheritance
5. Assignment demonstrates syntax, so do not add any attributes and methods
6. Run doctests - all must succeed
Polish:
1. Zdefiniuj klasę `Account`
2. Zdefiniuj klasę `User` dziedziczacą po `Account`
3. Zdefiniuj klasę `Admin` dziedziczacą po `User`
4. Użyj wielopoziomowego dziedziczenia
5. Zadanie demonstruje składnię, nie dodawaj żadnych atrybutów i metod
6. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(Account)
>>> assert isclass(User)
>>> assert isclass(Admin)
>>> assert issubclass(User, Account)
>>> assert issubclass(Admin, User)
>>> assert issubclass(Admin, Account)
>>> assert len(Account.__subclasses__()) == 1
>>> assert len(User.__subclasses__()) == 1
>>> assert len(Admin.__subclasses__()) == 0
"""
# Define class `Account`
...
# Define classe `User` inheriting from `Account`
...
# Define classe `Admin` inheriting from `User`
...
# TODO: poprawić zadanie aby było spójne z pozostałymi
"""
* Assignment: Inheritance About Multiple
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min
English:
1. Create class `MyAccount` from classes `Account`, `User`, `Admin`
2. Use mixins classes
3. Assignment demonstrates syntax, so do not add any attributes and methods
4. Run doctests - all must succeed
Polish:
1. Stwórz klasę `MyAccount` z klas `Account`, `User`, `Admin`
2. Użyj klas domieszkowych (mixin)
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(Account)
>>> assert isclass(User)
>>> assert isclass(Admin)
>>> assert isclass(MyAccount)
>>> assert issubclass(MyAccount, Account)
>>> assert issubclass(MyAccount, User)
>>> assert issubclass(MyAccount, Admin)
>>> assert len(Account.__subclasses__()) == 1
>>> assert len(User.__subclasses__()) == 1
>>> assert len(Admin.__subclasses__()) == 1
>>> assert len(MyAccount.__subclasses__()) == 0
"""
# Create classes `MyAccount`, `Account`, `User`, `Admin`
# Use mixins classes, do not define attributes
class Account:
pass
class User:
pass
class Admin:
pass
class MyAccount:
pass
# TODO: poprawić zadanie aby było spójne z pozostałymi
"""
* Assignment: Inheritance About Composition
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min
English:
1. Define class `MyAccount` with attribute `type: Account`
2. Use composition
3. Allow for setting type `User` or `Admin` in `__init__()` method
4. Assignment demonstrates syntax
5. Run doctests - all must succeed
Polish:
1. Zdefiniuj klasę `MyAccount` z atrybutem `type: Account`
2. Użyj kompozycji
3. Pozwól na ustawianie typu `User` or `Admin` w metodzie `__init__()`
4. Zadanie demonstruje składnię
5. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> assert isclass(User)
>>> assert isclass(Admin)
>>> assert isclass(Account)
>>> assert isclass(MyAccount)
>>> result = MyAccount()
>>> assert hasattr(result, 'type')
>>> result = MyAccount()
>>> assert hasattr(result, 'type')
>>> assert not isclass(result.type)
>>> assert isinstance(result.type, Account)
>>> assert not isinstance(result.type, User)
>>> assert not isinstance(result.type, Admin)
>>> result = MyAccount(type=Account)
>>> assert hasattr(result, 'type')
>>> assert not isclass(result.type)
>>> assert isinstance(result.type, Account)
>>> assert not isinstance(result.type, User)
>>> assert not isinstance(result.type, Admin)
>>> result = MyAccount(type=User)
>>> assert hasattr(result, 'type')
>>> assert not isclass(result.type)
>>> assert isinstance(result.type, Account)
>>> assert isinstance(result.type, User)
>>> assert not isinstance(result.type, Admin)
>>> result = MyAccount(type=Admin)
>>> assert hasattr(result, 'type')
>>> assert not isclass(result.type)
>>> assert isinstance(result.type, Account)
>>> assert not isinstance(result.type, User)
>>> assert isinstance(result.type, Admin)
"""
class Account:
pass
class User(Account):
pass
class Admin(Account):
pass
# Use composition
# Define class `MyAccount` with attribute `type: Account`
# Allow for setting type `User` or `Admin` in `__init__()` method
class MyAccount:
pass