Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗pyOpMiMA 149 of 174 menu
◀ ▶

Несколько абстрактных родителей в ООП в Python

Класс может наследовать сразу от нескольких баз. Если базы абстрактные, потомок должен реализовать все их абстрактные методы - иначе объект такого класса создать нельзя.

Абстрактный метод помечают декоратором @abstractmethod в модуле abc. Конкретный класс-потомок обязан дать ему реализацию.

Давайте попробуем на практике. Пусть кроме абстрактного класса Figure у нас также есть абстрактный класс Tetragon. Методы этого класса будут реализовывать классы Quadrate и Rectangle, так как у них 4 стороны, но не класс Disk.

Пусть класс Tetragon описывает геттеры для всех четырех сторон четырехугольника:

from abc import ABC, abstractmethod class Tetragon(ABC): @abstractmethod def get_a(self): pass @abstractmethod def get_b(self): pass @abstractmethod def get_c(self): pass @abstractmethod def get_d(self): pass

Пусть также у нас есть абстрактный класс Figure:

from abc import ABC, abstractmethod class Figure(ABC): @abstractmethod def get_square(self): pass @abstractmethod def get_perimeter(self): pass

Сделаем так, чтобы класс Quadrate наследовал оба абстрактных родителя. Для этого перечислим оба класса в скобках:

class Quadrate(Figure, Tetragon): pass

Доработаем теперь наш класс Quadrate, чтобы он реализовывал абстрактный класс Tetragon. Понятно, что наш квадрат является вырожденным случаем четырехугольника, ведь у квадрата все стороны равны. Поэтому все новые методы будут возвращать одно и тоже - ширину квадрата:

class Quadrate(Figure, Tetragon): def __init__(self, a): self.__a = a def get_a(self): return self.__a def get_b(self): return self.__a def get_c(self): return self.__a def get_d(self): return self.__a def get_square(self): return self.__a * self.__a def get_perimeter(self): return 4 * self.__a

Очевидно, что в прямоугольнике уже не все стороны одинаковы, а только противоположные. В этом случае новые методы станут немного отличаться. Ну, и в какой-нибудь трапеции вообще все 4 стороны будут разные.

Однако, не имеет значения, что за фигуру мы будем рассматривать - важно, что все эти фигуры будут иметь описанные методы (пусть некоторые фигуры и вырожденные) и работать однотипно.

Класс может сочетать обычного родителя и абстрактную примесь. Пусть мы хотим сделать класс Programmer на базе Employee и абстрактного контракта ProgrammerRole с методами для языков:

from abc import ABC, abstractmethod class Employee: def __init__(self, name, salary): self.__name = name self.__salary = salary def get_name(self): return self.__name def get_salary(self): return self.__salary class ProgrammerRole(ABC): @abstractmethod def get_langs(self): pass @abstractmethod def add_lang(self, lang): pass class Programmer(Employee, ProgrammerRole): def __init__(self, name, salary): super().__init__(name, salary) self.__langs = [] def get_langs(self): return self.__langs def add_lang(self, lang): self.__langs.append(lang)

Абстрактному родителю все равно, родные методы у класса или унаследованные - главное, чтобы все описанные абстрактные методы были реализованы.

Сделайте так, чтобы класс Rectangle также наследовал два абстрактных класса: и Figure, и Tetragon.

Сделайте абстрактный класс Circle с методами get_radius и get_diameter.

Сделайте так, чтобы класс Disk также наследовал два абстрактных класса: и Figure, и Circle.

Скопируйте код моего класса Employee и код абстрактного класса ProgrammerRole. Не копируйте мою заготовку класса Programmer - не подсматривая в мой код реализуйте этот класс самостоятельно.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить