Объектно-ориентированное программирование (ООП) — широко популярная парадигма программирования. Этот метод структурирования программы использует объекты, обладающие свойствами и поведением. Каждый язык программирования обрабатывает принципы ООП немного по-своему, поэтому важно изучать ООП для каждого изучаемого языка. Сегодня мы обсудим основы ООП в Python, чтобы развить ваши навыки Python.
Если вы новичок в ООП или просто интересуетесь его использованием в Python, это идеальная статья для начала. Вы узнаете о преимуществах ООП в Python и о том, как применять концепции ООП в своём коде. К концу этой статьи вы сможете создавать классы, инициализировать объекты и применять наследование к своим проектам Python.
Что такое объектно-ориентированное программирование?
Объектно-ориентированное программирование — это парадигма программирования, основанная на создании повторно используемых «объектов», которые имеют свои собственные свойства и поведение, с которыми можно действовать, манипулировать и объединять.
Эти объекты упаковывают связанные данные и поведение в представления реальных объектов. ООП — широко используемая парадигма в различных популярных языках программирования, таких как Python, C ++ и Java.
Многие разработчики используют ООП, потому что это делает ваш код логичным и многократно используемым, а также упрощает реализацию наследования. Он следует принципу DRY, который делает программы намного более эффективными.
В ООП каждый объект определяется со своими собственными свойствами. Например, скажем, наш объект — сотрудник. Этими свойствами могут быть их имя, возраст и роль. ООП позволяет легко моделировать объекты реального мира и отношения между ними. Многие новички предпочитают использовать языки ООП, потому что они организуют данные так же, как человеческий мозг организует информацию.
Четыре основных принципа ООП — это наследование, инкапсуляция, абстракция и полиморфизм. Чтобы узнать больше об этом, прочтите нашу статью Что такое объектно-ориентированное программирование? для освежения знаний, прежде чем продолжить здесь.
Давайте освежим нашу память о строительных блоках ООП, прежде чем посмотреть, как это работает в Python.
Характеристики
Поля свойств в объекте sneaker1
Свойства — это данные, описывающие объект. Каждый объект имеет уникальные свойства, к которым можно получить доступ или которыми можно управлять с помощью функций в программе. Думайте об этом как о переменных, описывающих отдельный объект.
Например, sneaker1объект может иметь свойства sizeи isOnSale.
Методы
объект sneaker1, который содержит свойства (вверху) и методы (внизу)
Методы определяют поведение объекта. Методы подобны функциям, которые находятся в пределах объекта. Они часто используются для изменения свойств объекта.
Например, у нашего sneaker1объекта будет метод, putOnSale который включает isOnSale или выключает свойство.
Их также можно использовать для отчёта о свойствах конкретного объекта. Например, тот же sneaker1объект может также иметь printInfo метод, отображающий его свойства для пользователя.
Классы
объект sneaker1, созданный из класса Shoe
Каждый объект создаётся с помощью класса. Думайте об этом как о чертеже определённого типа объекта. Классы перечисляют свойства, существенные для этого типа объекта, но не присваивают им значения. Классы также определяют методы, доступные для всех объектов этого типа.
Например, sneaker1был создан из класса, Shoe который определяет наши свойства, sizeи isOnSale, и наши методы, putOnSale и printInfo. Для всех объектов, созданных из Shoe схемы класса, будут определены те же поля.
Классы подобны зонтичной категории, под которую попадает каждый объект.
Экземпляры
Два экземпляра класса Shoe: sneaker1 и sneaker2.
Объект — это экземпляр своего родительского класса с уникальным именем и значениями свойств. В одной программе может быть несколько экземпляров одного и того же типа класса. Вызовы программ направляются к отдельным экземплярам, тогда как класс остаётся неизменным.
Например, у нашего shoe класса может быть два экземпляра sneaker1, с одним size из 8и sneaker2с одним sizeиз 12. Любые изменения, внесённые в экземпляр sneaker1, не повлияют на него sneaker2.
ООП в Python
Python — это язык программирования с несколькими парадигмами, что означает, что он поддерживает ООП, а также другие парадигмы. Вы используете классы для достижения ООП в Python. Python предоставляет все стандартные функции объектно-ориентированного программирования.
Разработчики часто предпочитают использовать ООП в своих программах на Python, потому что это делает код более пригодным для повторного использования и упрощает работу с более крупными программами. Программы ООП предотвращают повторение кода, поскольку класс можно определить один раз и многократно использовать повторно. Таким образом, ООП позволяет легко реализовать принцип «Не повторяйся» (DRY).
Давайте посмотрим на пример того, как ООП улучшает Python. Допустим, вы организовываете свои данные с помощью списка, а не класса.
sneaker1 = [8, true, "leather", 60]
Вот список sneaker1содержит значение для свойств size, isOnSale, material и cost. Этот подход не использует ООП и может привести к нескольким проблемам:
- Вы должны помнить, какой индекс они использовали для хранения определённого типа данных, т.е. sneaker1[0] = размер. Это не так интуитивно понятно, как объектный вызов size.
- Не многоразовый. Вам нужно создать новый список для каждого элемента, а не просто инициализировать новый объект.
- Трудно создать объектно-ориентированное поведение. Списки не могут содержать методы. Каждый список должен вызывать одну и ту же глобальную функцию для достижения заданного поведения, а не метод, зависящий от объекта.
Вместо этого с помощью ООП мы могли бы написать это как Shoeо бъект класса, чтобы избежать этих проблем и сделать наш код более полезным в дальнейшем.
sneaker1 = Shoe(8, true, "leather", 60)
Чтобы избежать этих проблем, разработчики Python часто используют ООП вместо других доступных парадигм. Ниже мы рассмотрим, как вы можете реализовать ООП в своих программах на Python.
Как определить класс в Python
Чтобы создать класс в Python, мы используем class ключевое слово и свойство вроде этого:
class MyClass: x = 4
Затем мы используем MyClass для создания такого объекта:
p1 = MyClass() print(p1.x)
Давайте рассмотрим это немного глубже. В следующих примерах представьте, что вас наняли для создания интернет-магазина для обувного магазина. Мы узнаем, как использовать Python для определения Shoe класса и свойств, которые каждая обувь должна указывать на сайте.
Сначала мы используем class ключевое слово, чтобы начать наш класс, а затем присваиваем ему имя Shoe. Каждый экземпляр Shoe представляет собой отдельную пару обуви. Затем мы перечислим свойства каждого ботинка будет иметь, size, isOnSale, material, и price. Наконец, мы устанавливаем для каждого свойства значение None. Мы установим значения каждого из этих свойств при инициализации Shoe объекта.
class Shoe:# define the properties and assign none valuesize = NoneisOnSale= Nonematerial = Noneprice = None
Не забудьте включить четыре пробела перед всеми свойствами или методами в классе, чтобы Python распознал, что все они находятся в определённом классе.
Как создать объект в Python
Теперь мы посмотрим, как инициализировать объекты и установить значения свойств для представления каждой пары обуви.
Чтобы создать объект, мы должны сначала установить наш метод инициализатора. Метод инициализатора уникален, потому что он имеет предопределённое имя __init__, и не имеет возвращаемого значения. Программа автоматически вызывает метод инициализатора при создании нового объекта из этого класса.
Метод инициализатора должен принимать специальный self параметр, а затем все свойства класса как параметры. self Параметр позволяет метод инициализатора, чтобы выбрать экземпляр вновь созданный объект.
Затем мы заполняем метод инициализатора инициализацией одной переменной экземпляра для каждого свойства. Каждая из этих инициализаций устанавливает для свойства созданного объекта значение соответствующего параметра.
Например, первый self.size = size устанавливает size свойство созданного объекта равным size параметру, переданному при создании объекта.
После настройки инициализатора мы можем создать объект с [objectName] = Shoe()необходимыми параметрами и передать их. В строке 10 мы создаём Shoeобъект с именем sneaker3со свойствами size = 11, isOnSale = false, material = «leather», иprice = 81
Мы можем использовать этот код, чтобы создать столько экземпляров, сколько Shoeнам нужно.
class Shoe:# defines the initializer methoddef __init__(self, size, isOnSale, material, price):self.size = sizeself.isOnSale = isOnSaleself.material = materialself.price = price# creates an object of the Shoe class and sets# each property to an appropriate valuesneaker3 = Shoe(11, ‘false’, «leather», 81)
Как создать методы экземпляра в Python
Затем мы добавим методы экземпляра в наш Shoe класс, чтобы мы могли взаимодействовать со свойствами объекта в нашей программе обувного магазина. Основное преимущество методов экземпляра заключается в том, что все они доступны для Shoe объекта любого типа сразу после его создания.
Чтобы создать экземпляры, вы вызываете класс и передаёте аргументы, которые __init__принимает его метод.
class Shoe:# defines the initializer methoddef __init__(self, size, isOnSale, material, price):self.size = sizeself.isOnSale = isOnSaleself.material = materialself.price = price# Instance methoddef printInfo(self):return f» This pair of shoes are size {self.size}, are made of {self.material}, and costs ${self.price}»# Instance methoddef putOnSale(self):self.isOnSale = truesneaker3 = Shoe(11, ‘false’, «leather», 81)print (sneaker3.printInfo())
Наш первый метод экземпляра — printInfoэто список всех свойств, кроме isOnSale. В строке 10 мы используем ключевое слово, defч тобы начать объявление нового метода, затем называем этот метод printInfoи, наконец, перечисляем специальный параметр self.
В этом случае self позволяет методу получить доступ к любому параметру в объекте, для которого вызывается этот метод. Затем мы записываем наше сообщение в строке 11, используя self.[property]вызовы.
Примечание: здесь используется функциональность f-строки Python 3.6. Любой раздел сообщения в фигурных скобках фактически не печатается, а вместо этого печатается значение указанного свойства для выбранного объекта.
Наш второй метод экземпляра putOnSale, изменяет значение isOnSaleсвойства в выбранном объекте на true. В строке 15 мы используем ключевое слово def, имя нашего метода и self параметр для определения метода.
Затем мы заполняем этот метод оператором для изменения isOnSale свойства trueна строку 16. Первая часть этого оператора выбирает isOnSale свойство текущего выбранного объекта. Вторая часть этого оператора устанавливает значение этого выбранного свойства равным true.
Изменение значения свойства этого Shoeобъекта isOnSaleне приводит к изменению значения по умолчанию в Shoe классе. Python не требует return значения внутри каждого метода.
Как использовать наследование в Python
Наконец, мы добавим подкатегорию Sandalиз Shoe класса с использованием наследования. Наследование позволяет новому классу брать на себя свойства и поведение другого класса. Класс, от которого унаследован, называется родительским классом. Любой класс, наследуемый от родительского класса, называется дочерним классом.
Дочерние классы непросто наследуют все свойства и методы, но также могут расширять или перезаписывать их.
Expand относится к добавлению свойств или методов к дочернему классу, которых нет в родительском классе. Перезапись — это возможность переопределить метод в дочернем классе, который уже был определён в родительском классе.
Общий синтаксис для наследования одного класса:
class BaseClass: Base class body class DerivedClass(BaseClass): Derived class body
У нас также может быть множественное наследование классов:
class BaseClass1: Base class1 body class BaseClass: Base class2 body class DerivedClass(BaseClass1,BaseClass2): Derived class body
Чтобы реализовать наследование в Python, определите класс как обычный, но добавьте имя его родительского класса в круглые скобки перед последним двоеточием (строка 2).
#Sandal is the child class to parent class Shoeclass Sandal(Shoe):def __init__(self, size, isOnSale, material, price, waterproof):#inherit self, size, isOnSale, material, and price propertiesShoe.__init__(self, size, isOnSale, material, price)#expands Sandal to contain additional property waterproofself.waterproof = waterproof#overwrites printInfo to reference «pair of sandals» rather than shoesdef printInfo(self):return f» This pair of sandals are size {self.size}, are made of {self.material}, and costs ${self.price}»sandal1 = Sandal(11, False, «leather», 81, True)print (sandal1.printInfo())
Затем мы определяем новый метод инициализатора, который берет все свойства Shoeи добавляет уникальное waterproofсвойство.
В строке 3 мы объявляем метод инициализации для всех необходимых нам свойств как из родительского, так и из дочернего классов. Затем в строке 5 мы вызываем метод инициализатора из родительского Shoeкласса для обработки общих свойств. Затем мы расширяем унаследованные свойства, чтобы добавить waterproofсвойство в строке 7.
Вы можете использовать расширенные классы, чтобы уменьшить количество перезаписываемого кода. Если бы наш класс не унаследовал от Shoe, нам нужно было бы воссоздать весь метод инициализатора, чтобы иметь только одно небольшое отличие.
Затем мы перезаписываем printInfoкласс, определённый в, Shoeчтобы быть Sandalконкретным. Python всегда будет использовать наиболее локальное определение метода.
Следовательно, Python будет использовать вновь определённый printInfoметод Sandalвместо унаследованного printInfoметода с Shoeмомента его printInfoвызова.
Собираем всё вместе: проблема с калькулятором
Давайте попробуем применить полученные навыки на практике. Ваша цель — написать класс Python с именем Calculator. Для решения этой задачи потребуется два шага: определение свойств калькулятора и добавление методов для каждой из четырёх операций.
Задание 1
Напишите инициализатор для инициализации значений num1и num2. Свойства: num1и num2.
Задача 2
Добавьте в программу четыре метода:
- add(), метод, который возвращает сумму num1и num2.
- subtract(), метод, который возвращает вычитание num1из num2.
- multiply(), метод, который возвращает произведение num1и num2.
- divide(), метод, который возвращает деление num2на num1.
На входе будут целые числа свойств объекта, а на выходе — результаты сложения, вычитания, деления и умножения этих чисел.
# Sample input obj = Calculator(10, 94); obj.add() obj.subtract() obj.multiply() obj.divide() # Sample output 104 84 940 9.4
Попробуйте сами и проверьте решение, если вы застряли. Удачи!
class Calculator:def __init__(self, num1, num2):self.num1 = num1self.num2 = num2def add(self):return (self.num2 + self.num1)def subtract(self):return (self.num2 — self.num1)def multiply(self):return (self.num2 * self.num1)def divide(self):return (self.num2 / self.num1)demo1 = Calculator(10, 94)print(«Addition:», demo1.add())print(«Subtraction:», demo1.subtract())print(«Mutliplication:», demo1.multiply())print(«Division:», demo1.divide())
Разбивка решения
Давайте погрузимся в решение. Ничего страшного, если не получилось с первого раза! Практика — это то, как мы учимся.
- Сначала мы реализуем Calculator класс с двумя свойствами: num1и num2.
- В строке 3-4 мы инициализируем оба свойства, num1и num2.
- В строке 7 мы реализовали add()метод, который возвращает сумму num1+ num1обоих свойств.
- А также в строке 10 мы реализуем subtraction(). Этот метод возвращает разницу между num1и num2.
- В строке 13 мы реализовали multiplication()метод, который возвращает произведение num2и num1.
- В строке 16 мы реализуем division(). Этот метод возвращает частное от num2by num1.
Заключение
Вы завершили своё погружение в мир объектно-ориентированного программирования на Python. Сегодня мы раскрыли определение объектно-ориентированного программирования, объяснили, почему оно популярно в Python, и познакомили вас с ключевыми частями объектно-ориентированной программы на Python.
Однако концепции, описанные в этой статье, — это только начало того, на что способно ООП. Следующие темы, о которых нужно узнать в вашем путешествии по ООП:
- Инкапсуляция данных.
- Полиморфизм.
- Агрегирование.
- Перегрузка оператора.
- Скрытие информации.