Перейти до змісту

Успадкування атрибутів класа

Дочірній клас успадковує атрибути базового класа.

Розглянемо на прикладі:

>>> class Base:
...     def __init__(self):
...         self.attr = 'Атрибут базового класа'
...     def method(self):
...         print('Це метод з класа Base')
...         print(f'У екземпляра класа Base є атрибут {self.attr=}')
...
>>> class Child(Base):
...     def child_method(self):
...         print('Це метод з класа Child')
...         print(f'У екземпляра класа Child є атрибут {self.attr=}')
...
>>>

Подивимось що тут відбувається:

  1. Клас Child не має власного ініціалізатора, отже він успадкує його від класа Base
  2. Клас Child успадкує від класа Base метод method()
  3. Клас Child має свій власний метод: child_method()
  4. При створенні екземпляра класа Child буде викликано успадкований ініціалізатор
  5. В ініціалізаторі буде для екземпляра буде створено атрибут attr

Перевіримо на практиці:

>>> object_of_child = Child()
>>> object_of_child.method()
Це метод з класа Base
У екземпляра класа Base є атрибут self.attr='Атрибут базового класа'
>>> object_of_child.child_method()
Це метод з класа Child
У екземпляра класа Child є атрибут self.attr='Атрибут базового класа'
>>> object_of_child.attr
'Атрибут базового класа'
>>>

Успадкування і приватні атрибути

Як нам вже відомо, атрибути, які починаються з двох символів підкреслення (але не закінчуються ними) є приватними атрибутами класа. Поза видимістю класа до таких атрибутів застосовується механізм name mangling (спотворення імені), тобто такі атрибути "поза класом" будуть мати інші імена (клас+атрибут), у тому числі і в успадкованих класах.

Використання приватних атрибутів дозволяє "приховати" внутрішню реалізацію базового класа для дочірніх класів. Тобто у дочірньому класі приватні атрибути базового класа не успадковуються:

>>> class Base:
...     def __init__(self):
...         self.__attr = 'Атрибут базового класа'
...     def method(self):
...         print('Це метод з класа Base')
...         print(f'У екземпляра класа Base є атрибут {self.__attr=}')
...
>>> class Child(Base):
...     def child_method(self):
...         print('Це метод з класа Child')
...         print(f'У екземпляра класа Child є атрибут {self.__attr=}')
...
>>> object_of_child = Child()
>>> object_of_child.method()
Це метод з класа Base
У екземпляра класа Base є атрибут self.__attr='Атрибут базового класа'
>>> object_of_child.child_method()
Це метод з класа Child
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in child_method
AttributeError: 'Child' object has no attribute '_Child__attr'
>>>

З метода method() "видно" атрибут __attr тому що вони знаходяться в одному класі Base. "Розгорнуте" ім'я атрибута буде _Base__attr.

Якщо ж ми звертаємось до атрибута __attr у методі child_method(), то тоді "розгорнуте" ім'я такого атрибута буде _Child__attr. А клас Child не має свого власного приватного атрибута __attr.

Back to top