Решение 1. Порядок поиска метода
Порядок MRO: D → B → C → A → object.
Python ищет метод greet сначала в D, затем в B. B не переопределяет метод, поэтому поиск идёт в C. Метод найден в C, и Hello from C печатается. До A Python не доходит.
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>,
# <class '__main__.C'>, <class '__main__.A'>,
# <class 'object'>)
Решение 2. Назначение super()
Правильный ответ: b.
- a — неверно:
super()не привязан к конкретному родителю. - b — верно:
super()переходит к следующему методу в MRO. - c — неверно: чтобы заменить метод, достаточно переопределить его без
super(). - d — неверно:
super()не обращается напрямую кobject.
Решение 3. Конфликт имён в миксинах
Правильный ответ: a — Saving….
Класс Document(SaveMixin, PrintMixin) наследует SaveMixin первым. При совпадающих именах методов Python выбирает метод первого подходящего родителя слева направо. Поэтому вызывается SaveMixin.process.
Решение 4. Сопоставьте понятия
Правильный ответ: 1-b, 2-c, 3-a.
- Композиция — объект создаётся и управляется внешним объектом (b).
- Агрегация — объект передаётся извне и может существовать отдельно (c).
- Вложенный класс — класс определён внутри другого класса (a).
Решение 5. Тип связи
Правильный ответ: b — агрегация.
Объект teacher передаётся извне и может существовать отдельно от Course. Course не управляет созданием преподавателя.
Решение 6. Класс Student
Класс содержит имя и email, строковое представление и метод для отправки уведомлений.
class Student:
def __init__(self, name: str, email: str) -> None:
self.name = name
self.email = email
def __str__(self) -> str:
return self.name
def notify(self, message: str) -> None:
print(f"Email to {self.email}: {message}")
student = Student("Alice", "alice@example.com")
print(student)
student.notify("You have been enrolled.")
Решение 7. Класс Course
Класс Course агрегирует объекты Student и делегирует им отправку уведомлений.
# Класс Student из решения 6 включён сюда, чтобы блок можно было запустить отдельно.
class Student:
def __init__(self, name: str, email: str) -> None:
self.name = name
self.email = email
def __str__(self) -> str:
return self.name
def notify(self, message: str) -> None:
print(f"Email to {self.email}: {message}")
class Course:
def __init__(self, title: str) -> None:
self.title = title
self.students: list[Student] = []
def add_student(self, student: Student) -> None:
self.students.append(student)
def show_students(self) -> None:
print(f"Students enrolled in {self.title}:")
for student in self.students:
print(f"- {student}")
def notify_all(self, message: str) -> None:
for student in self.students:
student.notify(message)
s1 = Student("Alice", "alice@example.com")
s2 = Student("Bob", "bob@example.com")
course = Course("Python OOP")
course.add_student(s1)
course.add_student(s2)
course.show_students()
course.notify_all("Welcome to the course!")
Логика: Course не наследует Student, а содержит список студентов. Это агрегация: студенты существуют независимо от курса.
super(), MRO и множественное наследование см. Multiple Inheritance; про типы коллекций — typing.