1.74M
Категория: ПрограммированиеПрограммирование

+Лекция 11

1.

ЛЕКЦИЯ 11
ПРИНЦИПЫ ООП

2.

3.

2. Основные принципы ООП
• Наследование
Наследование позволяет создавать новые классы на основе уже существующих. Оно
упрощает структуру кода, устраняет дублирование и позволяет расширять
функциональность классов.
• Абстракция
Абстракция позволяет выделять ключевые характеристики объекта, скрывая при этом
ненужные детали. В программировании это реализуется через классы и интерфейсы,
которые определяют общие черты для объектов.
• Инкапсуляция
Инкапсуляция защищает данные объекта от неконтролируемого доступа извне,
ограничивая доступ к ним через определенные методы. Это достигается с помощью
модификаторов доступа.
• Полиморфизм
Полиморфизм позволяет работать с объектами разных классов через единый интерфейс.
В языке программирования это реализуется через методы, которые могут вести себя поразному в зависимости от того, к какому классу принадлежит объект.

4.

Наследование
Наследование - способ создания нового класса на основе уже существующего, при
котором класс-потомок заимствует свойства и методы родительского класса и также
добавляет собственные.
На что обратить внимание?
1. Класс-потомок = Свойства и методы родителя + Собственные свойства и методы.
2. Класс-потомок автоматически наследует от родительского класса все поля и
методы.
3. Класс-потомок может дополняться новыми свойствами.
4. Класс-потомок
может
дополняться
новыми
методами,
а
также
заменять(переопределять)
унаследованные
методы.
Переопределить
родительский метод - это как? Это значит, внутри класса потомка есть метод,
который совпадает по названию с методом родительского класса, но функционал
у него новый - соответствующий потребностям класса-потомка.

5.

Объект Дом:
Наследование
Объект Частный Дом:

6.

Наследование
Основные термины наследования
Родительский (базовый) класс — класс, от которого наследуется
другой класс. Например, класс Animal может быть базовым для
различных типов животных.
Дочерний (производный) класс — класс, который наследует
свойства и методы родительского. Например, Dog или Cat могут быть
дочерними классами Animal.
Переопределение (overriding) — дочерний класс может
переопределить методы родительского класса, чтобы изменить или
дополнить их поведение.

7.

Наследование
Рассмотрим пример с классом Animal, который будет родительским классом,
и двумя дочерними классами Dog и Cat. Класс Animal содержит общие
характеристики и поведение, которые наследуются и расширяются дочерними
классами.

8.

Наследование
Класс Animal (родительский класс):
Содержит атрибуты name и age, которые описывают имя и возраст животного.
Содержит метод make_sound, который выводит общий звук, издаваемый
животным.
Метод describe выводит информацию о животном.
Класс Dog (дочерний класс):
Наследует все атрибуты и методы Animal.
Переопределяет метод make_sound, чтобы собака могла "лаять" ("Гав-гав!").
Добавляет новый метод fetch, который является уникальным для собаки и не
присутствует в родительском классе.
Класс Cat (дочерний класс):
Наследует все атрибуты и методы Animal.
Переопределяет метод make_sound, чтобы кошка могла "мяукать" ("Мяу!").
Добавляет новый метод scratch, уникальный для кошки.

9.

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

10.

Наследование
Преимущества наследования
Повторное использование кода: Базовый класс Animal содержит
общие атрибуты и методы, которые можно повторно использовать в
дочерних классах Dog и Cat.
Расширяемость: Дочерние классы могут добавлять новые атрибуты
и методы, расширяя функциональность базового класса.
Переопределение методов: Дочерние классы могут изменять
поведение унаследованных методов, делая его специфичным для
каждого класса.
Удобство иерархии: Наследование позволяет организовать классы в
иерархии, где общие характеристики вынесены в базовый класс, а
специфичные — в дочерние.

11.

Абстракция
Абстракция - принцип ООП, согласно которому объект характеризуется
свойствами, которые отличают его от всех остальных объектов и при этом
четко определяют его концептуальные границы.
Т. е. абстракция позволяет:
1. Выделить главные и наиболее значимые свойства предмета.
2. Отбросить второстепенные характеристики.

12.

Абстракция
Абстракция также тесно связана с инкапсуляцией: инкапсуляция
скрывает данные и детали реализации, а абстракция определяет, какие
данные и операции считаются важными для внешнего взаимодействия.
В Python также есть декоратор @abstractmethod, который
используется в абстрактных классах (импортируется из модуля abc). Он
отмечает метод как абстрактный, и такой метод должен быть
переопределен в наследниках. Этот декоратор используется для
реализации принципа абстракции.
Пример абстракции.
Рассмотрим пример абстракции на основе класса Car для
представления автомобиля. Мы определим основные методы, которые
важны для пользователя автомобиля, и скроем ненужные для него
технические детали.

13.

Абстракция
from abc import ABC, abstractmethod
class Animal (ABC):
@abstractmethod
def make_sound(self):
pass
Здесь @abstractmethod делает make_sound абстрактным
методом, и любой класс, наследующий Animal, обязан его
реализовать.

14.

Абстракция
from abc import ABC,
abstractmethod
class Car(ABC):
@abstractmethod
def start_engine(self):
pass
@abstractmethod
def stop_engine(self):
pass
@abstractmethod
def drive(self):
pass
Car — это абстрактный класс, который
содержит абстрактные методы start_engine,
stop_engine, и drive.
Эти
методы
определяют
базовое
поведение для всех автомобилей, но не
раскрывают,
как
именно
работают
конкретные детали.
Абстрактный класс используется для
определения интерфейса, а конкретные
классы реализуют его методы.

15.

class ElectricCar(Car):
def __init__(self, battery_level):
self.battery_level = battery_level
Абстракция
def start_engine(self):
if self.battery_level > 0:
print("Электродвигатель запущен.")
else:
print("Низкий заряд батареи! Запуск невозможен.")
def stop_engine(self):
print("Электродвигатель остановлен.")
def drive(self):
if self.battery_level > 0:
print("Автомобиль едет на электродвигателе.")
self.battery_level -= 10 # Потребление энергии при
движении
else:
print("Низкий заряд батареи! Движение
невозможно.")
Класс ElectricCar наследуется от
абстрактного класса Car и реализует его
абстрактные методы (start_engine,
stop_engine, и drive).
Метод drive уменьшает уровень заряда
батареи на 10 единиц при каждом
использовании, но все внутренние
детали,
касающиеся
работы
электродвигателя, остаются скрытыми.

16.

Инкапсуляция
Инкапсуляция - принцип ООП, согласно которому сложность реализации
программного компонента должна быть спрятана за его интерфейсом.
1. Отсутствует доступ к внутреннему устройству программного компонента.
2. Взаимодействие компонента с внешним миром осуществляется
посредством интерфейса, который включает публичные методы и поля.

17.

Инкапсуляция
Модификаторы доступа
Для реализации инкапсуляции используются модификаторы доступа. Они
задают, каким образом к полям и методам объекта можно получить доступ:
• Public (открытые) — поля и методы доступны из любого места кода.
• Protected (защищенные) — поля и методы доступны только внутри класса и его
подклассов.
• Private (закрытые) — поля и методы доступны только внутри класса.
В Python отсутствуют строгие модификаторы доступа, как в некоторых других
языках (например, private и protected в Java). Вместо этого, Python опирается на
соглашения:
Открытые (public) атрибуты пишутся без подчеркиваний: name.
Защищенные (protected) атрибуты пишутся с одним подчеркиванием: _name.
Закрытые (private) атрибуты пишутся с двумя подчеркиваниями: __name.

18.

Инкапсуляция
Сеттеры и геттеры — это методы, которые используются для
управления доступом к атрибутам объекта, обеспечивая инкапсуляцию
данных. В Python они позволяют контролировать, как изменяются и
читаются значения атрибутов, и помогают сделать доступ к данным более
безопасным и управляемым.
• Геттер (getter) — это метод, который возвращает значение приватного
или защищённого атрибута объекта. Его основная задача —
контролировать доступ на чтение к атрибуту.
• Сеттер (setter) — это метод, который изменяет значение приватного
или защищённого атрибута. Он проверяет и ограничивает изменения
атрибута, чтобы значение оставалось корректным и допустимым.

19.

Инкапсуляция

20.

Инкапсуляция
Абстрактный метод make_sound:
Метод make_sound объявлен как
абстрактный, поэтому он должен быть
реализован в подклассах, таких как
Dog.
В классе Dog этот метод реализуется,
чтобы выводить звук, который издает
собака.
Проверка инкапсуляции:
Попытка получить доступ к полям
__age или __health_status напрямую
(dog.__age) вызовет ошибку
AttributeError, поскольку эти поля
являются приватными.

21.

Инкапсуляция
Преимущества использования инкапсуляции
Контроль доступа: Инкапсуляция защищает внутреннее
состояние объекта. В этом примере, возраст и состояние здоровья
можно менять только через методы set_age и set_health_status, что
предотвращает установку некорректных значений.
Упрощение обновлений: Если в будущем потребуется изменить
логику изменения возраста или проверки статуса здоровья, можно
будет просто изменить методы set_age или set_health_status, не
затрагивая остальной код.
Чистота кода: Методы инкапсуляции делают интерфейс класса
понятным и безопасным для использования, а сами поля скрыты от
постороннего доступа.

22.

Полиморфизм
Полиморфизм (от греч. "много форм") — это принцип ООП, который
позволяет объектам разных классов использовать одинаковые интерфейсы, но
выполнять различные действия в зависимости от их типов. Проще говоря,
полиморфизм позволяет использовать одно и то же имя метода для
выполнения разных действий, в зависимости от класса, к которому
принадлежит объект.
Полиморфизм даёт возможность:
1.Писать универсальный код, который работает с разными типами объектов.
2.Упрощать добавление новых типов объектов в программу, без
необходимости менять существующий код.
Полиморфизм достигается с помощью переопределения методов в дочерних
классах, а также через интерфейсы и абстрактные классы.
Как итог - за одинаковым названием могут скрываться методы с
совершенно разным функционалом, который в каждом конкретном
случае соответствует нуждам класса, к которому он относится.

23.

Полиморфизм

24.

Полиморфизм
Виды полиморфизма
Полиморфизм времени компиляции (перегрузка методов) —
встречается в языках, поддерживающих перегрузку методов и
операторов (например, C++ или Java). Python напрямую не
поддерживает перегрузку, но позволяет создать поведение, похожее на
перегрузку, используя аргументы по умолчанию или *args и **kwargs.
Полиморфизм
времени
выполнения
(переопределение
методов) — свойство, когда один и тот же метод вызывает разные
реализации в зависимости от класса объекта.
В Python полиморфизм достигается через переопределение
методов в наследуемых классах.
Рассмотрим класс Animal, который является базовым. Дочерние
классы Dog и Cat будут переопределять метод make_sound, чтобы
каждый из них издавал свой уникальный звук.

25.

Полиморфизм

26.

Полиморфизм
Переопределение метода make_sound:
Каждый дочерний класс (Dog, Cat, Cow) имеет свою реализацию метода
make_sound, которая отличается от других.
При вызове метода make_sound у каждого объекта (будь то Dog, Cat, или Cow)
выполняется его собственная версия метода.
Использование единого интерфейса animal_sound:
Функция animal_sound принимает объект типа Animal и вызывает метод
make_sound, не зная, как конкретно метод реализован в каждом подклассе.
Благодаря полиморфизму, функция animal_sound работает с любым
объектом, который имеет метод make_sound. Это делает код универсальным и легко
расширяемым: чтобы добавить новый тип животного, нужно лишь создать новый
дочерний класс и реализовать в нем метод make_sound, не меняя саму функцию
animal_sound.

27.

Полиморфизм
Полиморфизм с использованием абстрактных классов
Чтобы гарантировать, что каждый дочерний класс реализует метод make_sound,
можно использовать абстрактный базовый класс Animal с абстрактным методом
make_sound. Для этого в Python используется модуль abc (Abstract Base Classes).
В этом примере:
Базовый класс Animal теперь
является
абстрактным
классом
благодаря наследованию от ABC.
Метод make_sound объявлен как
абстрактный метод с помощью
декоратора @abstractmethod, что
означает, что все дочерние классы
должны его реализовать.
Это помогает гарантировать, что
каждый класс-наследник (Dog, Cat)
реализует
собственную
версию
метода make_sound.

28.

Полиморфизм
Преимущества полиморфизма
Гибкость и расширяемость: Код становится более гибким,
поскольку можно добавлять новые классы без изменения уже
существующих функций. В примере выше можно легко добавить
новый тип животного, просто создав новый дочерний класс с
реализацией метода make_sound.
Понятный интерфейс: Полиморфизм позволяет работать с
объектами разных классов через общий интерфейс, упрощая
взаимодействие и улучшая читаемость кода.
Меньше дублирования кода: Нет необходимости писать
отдельные функции или условия для каждого типа объекта.
Полиморфизм позволяет использовать один и тот же метод для
объектов разных типов.

29.

Проверка типа объекта
При работе с объектами бывает необходимо в зависимости от их
типа выполнить те или иные операции. И с помощью встроенной
функции isinstance() мы можем проверить тип объекта. Эта функция
принимает два параметра:
isinstance(object, type)
Первый параметр представляет объект, а второй - тип, на
принадлежность к которому выполняется проверка. Если объект
представляет указанный тип, то функция возвращает True

30.

Пример
• Например, возьмем иерархию классов:
for person in people:
if isinstance(person, Student):
print(person.university)
elif isinstance(person, Employee):
print(person.company)
else:
print(person.name)
print()

31.

Преимущества ООП
Объектно-ориентированное программирование как другие парадигмы имеет свои преимущества и
недостатки.
Преимущества
1.Улучшение производительности разработки ПО.
ООП способствует модульности, расширяемости и повторному использованию кода (за счет аспекта
наследования и полиморфизма).
2.Улучшение сопровождения ПО.
Благодаря модульности, расширяемости и повторному использованию кода его легче
поддерживать.
3.Ускорение разработки.
Повторное использование кода позволяет выполнять разработку быстрее, в т.ч. в смежных проектах.
4.Снижение стоимости разработки.
Повторное использование кода также позволяет снизить издержки и сосредоточиться на
объектно-ориентированном анализе и проектировании, снижающем общую стоимость ПО.
5.Повышение качества ПО.
Ускорение разработки и снижение затрат позволяет уделить больше времени и ресурсов на
тестирование ПО.

32.

Недостатки ООП
Недостатки
1.Крутая кривая обучения.
Мышление в ООП-стиле требует определенных навыков, а переход от
императивного стиля на взаимодействие объектов может потребовать
времени.
2.Больший объем кода.
Как правило, ООП приводит появлению большего количества кода,
нежели в императивном программировании.
3.Медленные программы.
ООП-программы чаще выполняются медленнее, т.к. содержат больше
кода для выполнения.
4.ООП не подходит для всех случаев.
Ряд задач могут лучше решаться в императивном, логическом или
функциональном стиле, где использование ООП не даст выигрыша.

33.

Задание
1. Создайте класс Employee, который моделирует
сотрудника, и дочерние классы Manager и Developer.
2. Создайте базовый класс Shape (Форма), а затем
создайте
классы-наследники
Rectangle
(Прямоугольник) и Circle (Круг).
English     Русский Правила