Наследование
Наследование — важнейшая концепция объектно-ориентированного программирования (ООП). Любой класс может иметь класс-наследник, который наследует все от родительского класса (суперкласса). Класс-наследник строится на основе родительского и наследует его методы, поля и конструкторы.
Рассмотрим пример: основной класс Building описывает общие характеристики строений: год постройки (year) и город (city).
class Building:
def __init__(self, year, city):
self.year = year
self.city = city
def get_info(self):
print(f"Год постройки: {self.year}, город: {self.city}")
school = Building(2000, "Москва")
school.get_info()
Добавление новых функций для каждого типа строения (школа, дом, магазин) в класс Building сделает код нечитабельным и сложным для понимания. Эффективнее создать отдельные классы-наследники.
Создадим класс School, наследующий от Building:
class School(Building):
pass
school = School(2000, "Москва")
school.get_info()
Класс School наследует все характеристики и методы из Building. Аналогично можно создать классы House и Shop.
class House(Building):
pass
class Shop(Building):
pass
Добавим специфические характеристики для каждого класса-наследника. Например, для School добавим количество учеников (pupils):
class School(Building):
def __init__(self, pupils, year, city):
self.pupils = pupils
super().__init__(year, city) # Вызов конструктора родительского класса
def get_info(self):
super().get_info()
print(f"Количество учеников: {self.pupils}")
school = School(100, 2000, "Москва")
school.get_info()
Обратите внимание на использование super().__init__(year, city) для вызова конструктора родительского класса и передачи ему необходимых параметров. В Python множественное наследование не поддерживается — класс может наследовать только от одного родительского класса. Однако, класс-наследник может сам иметь классы-наследники.
Полиморфизм
Полиморфизм позволяет переопределять методы, объявленные в родительском классе, в классах-наследниках. В нашем примере метод get_info() в классе School переопределен для вывода дополнительной информации о количестве учеников. При вызове get_info() для объекта класса School будет использован переопределенный метод, а для объектов других классов — метод из родительского класса.
Инкапсуляция
Инкапсуляция — это защита данных. В Python инкапсуляция реализована не очень строго. Хотя можно использовать двойное подчеркивание (__) перед именем поля для ограничения доступа, это не гарантирует полную защиту.
class Building:
def __init__(self, year, city):
self.__year = year # Попытка инкапсуляции
self.city = city
def get_year(self):
return self.__year
building = Building(2023, "New York")
print(building.city) # Доступ к полю city разрешен
print(building.get_year()) # Доступ к полю __year через метод get_year
#print(building.__year) # Прямой доступ к полю __year всё ещё возможен
Хотя прямого доступа к полю __year можно избежать, используя метод get_year(), полная защита данных в Python не гарантируется.
Рассмотрены наследование, полиморфизм и инкапсуляция — ключевые концепции ООП в Python. Наследование позволяет создавать иерархию классов, полиморфизм обеспечивает гибкость в работе с методами, а инкапсуляция (хотя и не очень строго в Python) помогает защитить данные.