Назовите и объясните ключевые принципы ООП в Python

Ответ

Объектно-ориентированное программирование (ООП) в Python строится на четырех основных принципах:

  • 1. Инкапсуляция Сокрытие внутренней реализации объекта и предоставление публичного интерфейса для взаимодействия с ним. Данные (атрибуты) и методы объединяются в класс. В Python инкапсуляция реализуется соглашениями: префикс _ для защищенных членов и __ для приватных (с name mangling).

  • 2. Наследование Механизм, позволяющий создавать новый класс (потомок) на основе существующего (родителя). Потомок перенимает атрибуты и методы родителя, может их расширять или переопределять.

  • 3. Полиморфизм Возможность использовать объекты разных классов с одинаковым интерфейсом. Это позволяет писать более гибкий и обобщенный код. Яркий пример в Python — "утиная типизация" (duck typing): "Если это выглядит как утка и крякает как утка, то это утка".

  • 4. Абстракция Выделение наиболее значимых характеристик объекта и игнорирование второстепенных. В коде это часто реализуется через абстрактные классы (модуль abc), которые определяют общий интерфейс для своих потомков, но не имеют собственной реализации.

Пример, демонстрирующий все принципы:

from abc import ABC, abstractmethod

# 4. Абстракция: определяем общий интерфейс для всех фигур
class Shape(ABC):
    def __init__(self, color):
        # 1. Инкапсуляция: атрибут _color защищен
        self._color = color

    @abstractmethod
    def area(self):
        pass

# 2. Наследование: Circle наследуется от Shape
class Circle(Shape):
    def __init__(self, color, radius):
        super().__init__(color)
        self._radius = radius

    # 3. Полиморфизм: своя реализация метода area
    def area(self):
        return 3.14 * self._radius ** 2

# 2. Наследование: Square наследуется от Shape
class Square(Shape):
    def __init__(self, color, side):
        super().__init__(color)
        self._side = side

    # 3. Полиморфизм: другая реализация метода area
    def area(self):
        return self._side ** 2

# Полиморфизм в действии
shapes = [Circle("Red", 10), Square("Blue", 5)]
for shape in shapes:
    # Вызываем один и тот же метод area для разных объектов
    print(f"Площадь фигуры: {shape.area()}")

Ответ 18+ 🔞

Ну, слушай, вот есть эта ваша объектно-ориентированная хрень в Питоне. Четыре столпа, на которых всё держится, как бабка на костылях. И если один столп подломится — пиздец всему, всё накроется медным тазом.

Первый столп — Инкапсуляция. Это когда ты делаешь вид, что у тебя в классе всё чисто и красиво, а внутри — пиздец какой-то бардак, но ты его прячешь. В Питоне это вообще условность, блядь. Поставил один подчёркивание _ — типа «не лезь, защищённое». Поставил два __ — типа «вообще частное, не твоё собачье дело». Хотя, конечно, любой упоротый разработчик всё равно залезет, если захочет. Но приличия ради — не лезь, сука.

Второй столп — Наследование. Это когда ты такой: «О, у этого класса уже есть куча функционала, но мне надо чуть по-другому». И ты не пишешь всё с нуля, как мудак, а просто говоришь: «Я твой сын, папаша, дай мне твои методы, а я их тут чутка перепишу под себя». Экономия времени — овердохуища.

Третий столп — Полиморфизм. Вообще, слово страшное, а суть простая: «Если объект крякает как утка — значит, с ним можно работать как с уткой, а похуй, что он там внутри на самом деле». В Питоне это называется «утиная типизация». Главное — чтобы методы были, а остальное — хуй с горы.

Четвёртый столп — Абстракция. Это когда ты выделяешь из реальной сущности только самое важное, а всю шелуху — нахуй. Типа, «фигура» — у неё есть цвет и можно посчитать площадь. А как именно считается площадь — это уже проблемы круга, квадрата или твоего левого яйца. В коде это часто абстрактные классы, которые только говорят «вот такой метод должен быть», но сами нихуя не делают. Чисто указатель, блядь.

А вот тебе живой пример, чтобы не быть голословным, как тот мудак на лекции:

from abc import ABC, abstractmethod

# 4. Абстракция: говорим, что все фигуры должны уметь считать площадь, а как — их проблемы.
class Shape(ABC):
    def __init__(self, color):
        # 1. Инкапсуляция: цвет прячем за _color, типа не трогай.
        self._color = color

    @abstractmethod
    def area(self):
        pass  # А реализацию, блядь, пусть дети пишут.

# 2. Наследование: Круг — сын Фигуры. Получает цвет в наследство.
class Circle(Shape):
    def __init__(self, color, radius):
        super().__init__(color)
        self._radius = radius

    # 3. Полиморфизм: вот тебе, мама, реализация площади для круга.
    def area(self):
        return 3.14 * self._radius ** 2

# 2. Наследование: Квадрат — тоже сын Фигуры. Тоже не мудак, чтоб с нуля писать.
class Square(Shape):
    def __init__(self, color, side):
        super().__init__(color)
        self._side = side

    # 3. Полиморфизм: а тут площадь считается по-другому, потому что квадрат, ёпта.
    def area(self):
        return self._side ** 2

# А вот тут магия полиморфизма в действии, блядь.
shapes = [Circle("Red", 10), Square("Blue", 5)]
for shape in shapes:
    # Мне похуй, круг это или квадрат. Главное — у него есть метод .area().
    print(f"Площадь фигуры: {shape.area()}")

Вот и вся философия, блядь. Сначала кажется, что это какая-то заумная хуйня, а потом понимаешь — да это же просто способ не повторять один и тот же код, как последний распиздяй. Красота, в рот меня чих-пых!