Проблема приватных свойств при наследовании в ООП в Python
То, что приватные свойства не наследуются, может привести к неожиданной проблеме. Давайте посмотрим на примере. Пусть у нас есть следующий класс-родитель с приватным свойством:
class User:
def __init__(self):
self.__age = None
def set_age(self, age):
self.__age = age
def get_age(self):
return self.__age
Пусть в классе-потомке мы решили сделать метод, который будет увеличивать возраст на единицу. Однако, попытка изменить приватное свойство родителя приведет к ошибке:
class Student(User):
def inc_age(self):
self.__age += 1 # ошибка
Ошибка исчезнет, если в классе-потомке
объявить приватное свойство __age:
class Student(User):
def __init__(self):
self.__age = None
def inc_age(self):
self.__age += 1
Тут-то нас и поджидает ловушка! На самом деле мы породили два приватных свойства: одно в родителе и одно в потомке. И они работают полностью независимо. Это значит, что методы родителя будут изменять свое свойство, а методы потомка - свои.
В Python у приватного имени в родителе
получается имя _User__age,
а запись self.__age в потомке
создает другое свойство _Student__age.
Это разные поля объекта.
Эта проблема на самом деле имеет решение. Просто нужно манипулировать приватными свойствами родителя через методы этого родителя. Давайте перепишем наш код в соответствии с этим:
class Student(User):
def inc_age(self):
age = self.get_age()
age += 1
self.set_age(age)
Можно упростить:
class Student(User):
def inc_age(self):
self.set_age(self.get_age() + 1)
В следующем коде в классе потомка переопределяется метод родителя. Исправьте проблемы в этом коде:
class User:
def __init__(self):
self.__name = None
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
class Employee(User):
def set_name(self, name):
if len(name) > 0:
self.__name = name # ошибка