A. Классная точка 3.0

Давайте расширим функционал класса, написанного вами в задаче «Классная точка 2.0».

Создайте класс PatchedPoint — наследника уже написанного вами Point.

Требуется реализовать следующие виды инициализации нового класса:

  • параметров не передано — координаты точки равны 0;
  • передан один параметр — кортеж с координатами точки;
  • передано два параметра — координаты точки.

Примечание

Ваше решение должно содержать только классы и функции.
В решении не должно быть вызовов инициализации требуемых классов.

Пример

Ввод

point = PatchedPoint()
print(point.x, point.y)
point.move(2, -3)
print(point.x, point.y)

Вывод

0 0
2 -3

Ввод

first_point = PatchedPoint((2, -7))
second_point = PatchedPoint(7, 9)
print(first_point.length(second_point))
print(second_point.length(first_point))

Вывод

16.76
16.76

Решение

В этой задаче мы знакомимся с наследованием. Ничего сложного, но есть нюансы. Нюанс связан с вопросом нужно ли использовать функцию super() или можно обойтись без нее?

Ответ на этот вопрос довольно простой. Если вы точно знаете что родительский __init__() не содержит никаких манипуляций с данными, и уверены, что инициализируете в наследуемом классе все необходимые для работы класса переменные, то такой необходимости нет. В общем же случае, использование родительской инициализации всегда безопасней.

Преимущества использования super()

  1. Автоматическое разрешение методов и поддержка множественного наследования: super() более удобен в использовании в случае множественного наследования, где класс имеет несколько родителей, так как позволяет автоматически определить, какой именно метод следует вызвать в цепочке наследования. Это полезно и в тех случаях, если класс имеет множество родителей.
  2. Более гибкий код: Если вы измените порядок классов в цепочке наследования, super() автоматически учтет эти изменения, в то время как явное указание имени родительского класса может потребовать изменений в коде.

Я привожу два варианта решения – с наивной инициализацией, когда мы не вызываем родительский метод __init__(), и инициализацию с помощью родительского __init__().

Посмотреть код

Решение

Python
class Point:
    def __init__(self, x, y) -> None:
        self.x = x
        self.y = y

    def move(self, new_x, new_y):
        self.x += new_x
        self.y += new_y

    def length(self, point):
        result = ((point.x - self.x) ** 2 + (point.y - self.y) ** 2) ** 0.5
        return round(result, 2)


class PatchedPoint(Point):
    def __init__(self, *args) -> None:
        match len(args):
            case 0:
                self.x = 0
                self.y = 0
            case 1:
                self.x, self.y = args[0]
            case 2:
                self.x, self.y = args

Решение

Python
class Point:
    def __init__(self, x, y) -> None:
        self.x = x
        self.y = y

    def move(self, new_x, new_y):
        self.x += new_x
        self.y += new_y

    def length(self, point):
        result = ((point.x - self.x) ** 2 + (point.y - self.y) ** 2) ** 0.5
        return round(result, 2)


class PatchedPoint(Point):
    def __init__(self, *args) -> None:
        match len(args):
            case 0:
                super().__init__(0, 0)
            case 1:
                super().__init__(*args[0])
            case 2:
                super().__init__(*args)
Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии