Основы ООП на Python
Объектно-ориентированное программирование
Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на концепции «объектов», которые могут содержать данные и код. Данные принимают форму полей (часто известных как атрибуты или свойства), а код — форму процедур (часто известных как методы).
Инкапсуляция
Инкапсуляция — одна из фундаментальных концепций объектно-ориентированного программирования, которая помогает защитить данные и методы объекта от несанкционированного доступа и изменения. Это способ достижения абстракции данных, что означает, что детали реализации объекта скрыты от внешнего мира, и наружу выставляется только необходимая информация.
В Python инкапсуляция может быть достигнута с помощью модификаторов доступа. Модификаторы доступа — это ключевые слова, определяющие доступность атрибутов и методов в классе. Три модификатора доступа, доступные в Python, — это public (публичный), private (приватный) и protected (защищенный). Однако в Python нет явного способа определения модификаторов доступа, как в некоторых других языках программирования, таких как Java и C++. Вместо этого он использует соглашение об использовании префиксов подчеркивания для обозначения уровня доступа.
В приведенном примере кода класс MyClass имеет два атрибута: _protected_var и __private_var. _protected_var помечен как защищенный с помощью префикса из одного подчеркивания. Это означает, что к атрибуту можно получить доступ внутри класса и его подклассов, но не за пределами класса. __private_var помечен как приватный с помощью префикса из двух подчеркиваний. Это означает, что к атрибуту можно получить доступ только внутри класса и не за его пределами, даже в его подклассах.
Когда мы создаем объект класса MyClass, мы можем получить доступ к атрибуту _protected_var, используя имя объекта с префиксом из одного подчеркивания. Однако мы не можем получить доступ к атрибуту __private_var с помощью имени объекта, так как он скрыт от внешнего мира. Если мы попытаемся получить доступ к атрибуту __private_var, мы получим AttributeError, как показано в коде.
Таким образом, инкапсуляция является важной концепцией в объектно-ориентированном программировании, которая помогает защитить детали реализации объекта. В Python мы можем достичь инкапсуляции, используя модификаторы доступа и префиксы подчеркивания для обозначения уровня доступа.
# Определяем класс с именем MyClass
class MyClass:
# Конструктор, который инициализирует объект класса
def __init__(self):
# Определяем защищенную переменную с начальным значением 10
# Имя переменной начинается с одного подчеркивания, что указывает на защищенный доступ
self._protected_var = 10
# Определяем приватную переменную с начальным значением 20
# Имя переменной начинается с двух подчеркиваний, что указывает на приватный доступ
self.__private_var = 20
# Создаем объект класса MyClass
obj = MyClass()
# Получаем доступ к защищенной переменной, используя имя объекта с одним подчеркиванием, и выводим ее значение
# К защищенной переменной можно получить доступ за пределами класса, но
# предполагается, что она будет использоваться внутри класса или его подклассов
print(obj._protected_var) # вывод: 10
# Пытаемся получить доступ к приватной переменной, используя имя объекта, и выводим ее значение
# К приватной переменной нельзя получить доступ за пределами класса, даже из его подклассов
# Это вызовет AttributeError, поскольку переменная недоступна за пределами класса
print(obj.__private_var) # AttributeError: 'MyClass' object has no attribute '__private_var'
Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения
**variable_variable_**variableНаследование
Наследование способствует повторному использованию кода и позволяет создавать иерархию классов, которые разделяют общие атрибуты и методы. Это помогает создавать чистый и организованный код, сохраняя связанную функциональность в одном месте и способствуя концепции модульности. Базовый класс, от которого выводится новый класс, также известен как родительский класс, а новый класс известен как дочерний класс или подкласс.
В коде мы определяем класс Animal, который имеет конструктор, инициализирующий объект класса атрибутом name и методом speak. Метод speak определен в классе Animal, но не имеет тела.
Затем мы определяем два подкласса, Dog и Cat, которые наследуются от класса Animal. Эти подклассы переопределяют метод speak класса Animal.
Мы создаем объект Dog с атрибутом имени “Rover” и объект Cat с атрибутом имени “Whiskers”. Мы вызываем метод speak объекта Dog с помощью dog.speak(), и он выводит “Woof!”, потому что метод speak класса Dog переопределяет метод speak класса Animal. Аналогично, мы вызываем метод speak объекта Cat с помощью cat.speak(), и он выводит “Meow!”, потому что метод speak класса Cat переопределяет метод speak класса Animal.
# Определяем класс с именем Animal
class Animal:
# Конструктор, который инициализирует объект класса атрибутом name
def __init__(self, name):
self.name = name
# Метод, определенный в классе Animal, но не имеющий тела
# Этот метод будет переопределен в подклассах Animal
def speak(self):
pass
# Определяем подкласс Dog, который наследуется от класса Animal
class Dog(Animal):
# Переопределяем метод speak класса Animal
def speak(self):
print("Woof!")
# Определяем подкласс Cat, который наследуется от класса Animal
class Cat(Animal):
# Переопределяем метод speak класса Animal
def speak(self):
print("Meow!")
# Создаем объект Dog с атрибутом name "Rover"
dog = Dog("Rover")
# Создаем объект Cat с атрибутом name "Whiskers"
cat = Cat("Whiskers")
# Вызываем метод speak класса Dog и выводим результат
# Метод speak класса Dog переопределяет метод speak класса Animal
# Следовательно, при вызове метода speak объекта Dog будет выведено "Woof!"
dog.speak() # вывод: Woof!
# Вызываем метод speak класса Cat и выводим результат
# Метод speak класса Cat переопределяет метод speak класса Animal
# Следовательно, при вызове метода speak объекта Cat будет выведено "Meow!"
cat.speak() # вывод: Meow!
Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения
Полиморфизм
Полиморфизм — важная концепция в объектно-ориентированном программировании, которая позволяет писать код, способный работать с объектами разных классов единообразным образом. В Python полиморфизм достигается за счет переопределения методов или перегрузки методов.
Переопределение метода (Method overriding) — это когда подкласс предоставляет собственную реализацию метода, который уже определен в его родительском классе. Это позволяет подклассу изменять поведение метода, не меняя его имени или сигнатуры.
Перегрузка метода (Method overloading) — это когда несколько методов имеют одинаковое имя, но разные параметры. Python не поддерживает прямую перегрузку методов, но ее можно достичь с помощью аргументов по умолчанию или аргументов переменной длины.
Полиморфизм упрощает написание гибкого и многократно используемого кода. Он позволяет писать код, который может работать с разными объектами без необходимости знать их конкретные типы.
# Класс Shape определен с абстрактным методом area, который предполагается переопределить в подклассах.
class Shape:
def area(self):
pass
class Rectangle(Shape):
# Класс Rectangle определен с методом __init__, который инициализирует
# переменные экземпляра width и height.
# Он также определяет метод area, который вычисляет и возвращает
# площадь прямоугольника с использованием переменных экземпляра width и height.
def __init__(self, width, height):
self.width = width # Инициализация переменной экземпляра width
self.height = height # Инициализация переменной экземпляра height
def area(self):
return self.width * self.height # Возврат площади прямоугольника
# Класс Circle определен с методом __init__,
# который инициализирует переменную экземпляра radius.
# Он также определяет метод area, который вычисляет и
# возвращает площадь круга с использованием переменной экземпляра radius.
class Circle(Shape):
def __init__(self, radius):
self.radius = radius # Инициализация переменной экземпляра radius
def area(self):
return 3.14 * self.radius ** 2 # Возврат площади круга с использованием pi * r^2
# Создается список shapes, содержащий один объект Rectangle и один объект Circle. Цикл for
# перебирает каждый объект в списке и вызывает метод area каждого объекта.
# Вывод будет площадью прямоугольника (20) и площадью круга (153.86).
shapes = [Rectangle(4, 5), Circle(7)] # Создаем список объектов Shape
for shape in shapes:
print(shape.area()) # Вывод площади каждого объекта Shape
Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения
Абстракция
Абстракция — важная концепция в объектно-ориентированном программировании (ООП), поскольку она позволяет сосредоточиться на существенных характеристиках объекта или системы, игнорируя детали, не относящиеся к текущему контексту. Уменьшая сложность и скрывая ненужные детали, абстракция может сделать код более модульным, легким для чтения и легким для сопровождения.
В Python абстракция может быть достигнута с помощью абстрактных классов или интерфейсов. Абстрактный класс — это класс, который нельзя инстанцировать напрямую, но он предназначен для наследования другими классами. Он часто включает абстрактные методы, которые не имеют реализации, но предоставляют шаблон для того, как должен быть реализован подкласс. Это позволяет программисту определить общий интерфейс для группы связанных классов, при этом позволяя каждому классу иметь свое собственное специфическое поведение.
Интерфейс, с другой стороны, представляет собой набор сигнатур методов, которые класс должен реализовать, чтобы считаться «совместимым» с интерфейсом. Интерфейсы часто используются для определения общего набора методов, которые могут реализовать несколько классов, что позволяет использовать их взаимозаменяемо в определенных контекстах.
В Python нет встроенной поддержки абстрактных классов или интерфейсов, но их можно реализовать с помощью модуля abc (abstract base class). Этот модуль предоставляет класс ABC и декоратор abstractmethod, которые можно использовать для определения абстрактных классов и методов.
В целом, абстракция является мощным инструментом для управления сложностью и улучшения качества кода в объектно-ориентированном программировании, и Python предоставляет ряд вариантов для достижения абстракции в вашем коде.
# Импортируем модуль abc для определения абстрактных классов и методов
from abc import ABC, abstractmethod
# Определяем абстрактный класс Shape, который имеет абстрактный метод area
class Shape(ABC):
@abstractmethod
def area(self):
pass
# Определяем класс Rectangle, который наследуется от Shape
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
# Реализуем метод area для Прямоугольников
def area(self):
return self.width * self.height
# Определяем класс Circle, который также наследуется от Shape
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
# Реализуем метод area для Кругов
def area(self):
return 3.14 * self.radius ** 2
# Создаем список фигур, включающий как Прямоугольники, так и Круги
shapes = [Rectangle(4, 5), Circle(7)]
# Перебираем каждую фигуру в списке и выводим ее площадь
for shape in shapes:
print(shape.area())
Это некоторые из основных принципов ООП на Python. Эта страница в настоящее время находится в разработке, и скоро появятся более подробные примеры и объяснения.