📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Концепция ООП простыми словами | Объектно-ориентированное программирование Python

selfedu13:40

Transcription

Здравствуйте, дорогие друзья! У многих начинающих программистов концепция объектно-ориентированного программирования вызывает недоумение и вопрос: Зачем она нужна? Я же уже умею писать программы, оперировать данными, создавать циклы, прописывать условия, вызывать функции и тем самым писать программы практически любой сложности. Разве этого мало? Этого было достаточно примерно до 60х годов прошлого века, когда в общем-то и зародилась эта концепция ООП.

Даже можно сказать, что вплоть до начала 90х, программисты могли свободно обходится без ООП, пока это не стало доминирующим направлением и внедрено в самый популярный на тот момент язык программирования C++. Так что же это такое и почему сейчас знать объектно-ориентированное программирование должен каждый уважающий себя начинающий программист? Я постараюсь ответить на все эти вопросы, не прибегая к конкретному языку программирования, то есть в целом разъяснить концепцию ООП, общую для всех языков программирования. И начну с того, что почти всегда в программах мы оперируем объектами данных. Например, создается программа по учету животных, в частности котов и кошек.

Значит, здесь мы имеем дело с объектами коты. И было бы хорошо все данные, связанные с котами, представить в программе как единое целое. Как раз это можно сделать с помощью класса. То есть вот этот прямоугольник это есть класс. И имя этого класса я назвал его так вот Cuts.

Вот этот вот класс можно воспринимать, как некий шаблон, по которому в дальнейшем будут формироваться данные о котах. В этом шаблоне есть три свойства: Порода, Имя, Возраст. Программист сам решает сколько и какие свойства будет содержать тот или иной класс. Я решил для примера пусть будут такие. А вот конкретные коты это уже объекты данного класса.

Например, вот такой кот. У него порода Бурма, зовут Васька и возраст 3 года. Другой объект это совершенно независимый объект, который создан по образу и подобию вот этого класса и содержит уже другие данные. Порода Саванна, зовут Красик и возраст 5 лет. Ну и так далее.

И таких объектов может быть множество. Далее в программе мы можем работать с этими объектами котами, как с единым целым и это очень удобно. Вообще класс может содержать не только свойства, т. Е. Данные, но и методы набор функций, определенный для работы с классом и его объектами.

Т. Е. Класс может описывать некий алгоритм, фрагмент программы, присущий именно этому объекту. Например, в классе можно определить метод, функцию, которая бы рисовала кота на экране устройства. Ну и пусть для примера она называется draw.

Тогда у каждого объекта этого класса можно будет вызывать метод draw для рисования кота. Разумеется, реализацию этого метода мы прописываем сами. То есть мы его прописываем так, чтобы вот эта вот функция, то есть метод, рисовал именно кота, а не делал что-то другое. То есть если сделано все правильно, вот именно так, как мы задумываем, то вызывая этот метод для соответствующего объекта, мы будем получать изображение соответствующего кота. Т.

Е. Видите, как удобно можно оперировать объектами на уровне классов. И это только начало. Разумеется, вот таких методов в классах может быть сколько угодно. И они, как правило, имеют доступ ко всем свойствам текущего класса и объекта, для которого вызываются.

В результате в рамках одного класса можно сформировать программу, которая часто работает независимо в каждом объекте этого класса. Чтобы всё это было понятней приведу ещё один пример из своей практики, когда я впервые применял объектно-ориентированного программирования и был этим очень доволен. Однажды мне понадобилось вывести в одном программном окне несколько независимых графиков. Тогда в программе я определил вот такой класс graphs для отображения графика и его манипулирования, изменение масштаба, перемещение и прочее. А затем каждый конкретный график был представлен просто объектом этого класса.

То есть первый график представлял собой первый объект этого класса, второй график второй объект этого класса, ну а третий и третий объект. И таким образом они работали совершенно независимо и отображали каждый свой график. И это было здорово. Благодаря этому у меня в программе один блок кода отвечал за независимое отображение сразу нескольких графиков. Итак, мы теперь с вами представляем, что такое класс и что такое объект класса.

Давайте сделаем следующий шаг и отметим, что класс вообще должен восприниматься как единая целостная конструкция и все внутренние манипуляции с его данными должны быть сокрыты в этом классе и в идеале недоступны извне. То есть программисты, использующие класс, не могли бы обращаться ко всем его данным и методам, а только к некоторым разрешенным. Это как с реальными вещами. Например, когда мы покупаем автомобиль, то нам важно как им управлять, какие у него характеристики. Но совершенно не имеет значения как работает двигатель, почему крутятся колёса, из чего сделаны стёкла, как взаимодействуют между собой все его агрегаты и прочее-прочее.

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

Они вроде капсулы, которые содержат в себе данные и методы И эти действия определяют внутренний алгоритм функционирования данного класса. Так вот, чтобы пользователь класса не мог случайно или намеренно вмешать свою внутреннюю работу, данные и методы можно скрывать. Т. Е. К скрытым данным и методам из вне напрямую обращаться нельзя, только внутри класса.

Такой механизм в объектно-ориентированном программировании называется инкапсуляцией. Благодаря инкапсуляции класс становится единым целым, а работа с ним возможна только через разрешенные свойства и методы. Например, в автомобиле такие разрешенные методы это руль, коробка передач, педали газа и тормоза и прочее, чем мы можем управлять во время движения. А все остальное лишнее для нас скрыто внутри. И по большому счету нам не важно, как именно достигается результат, главное чтобы ехали.

Это и есть идея инкапсуляции в объектно-ориентированного программирования. Следующая важная идея объектно-ориентированного программирования наследование классов. Наследование позволяет как бы вынести за скобки общие для разных классов. Я часто здесь привожу пример с разработкой графического редактора, в котором можно рисовать графические примитивы: линии, прямоугольники, эллипсы и другие фигуры. С точки зрения объектно-ориентированного программирования каждый такой примитив удобно представить своим классом.

Но очевидно в этих классах будут общие свойства, например координаты, толщина линии, цвет и другие. В результате получаем дублирование кода. То есть нарушение принципа DRI. Не повторяйся. Именно эти общие свойства целесообразно вынести в общий для всех них базовый класс.

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

В нашем примере есть класс Figure, который только хранит данные, а унаследованные дочерние классы расширяют его функциональность и выполняют дополнительно рисование конкретных графических примитивов. Наконец, последняя важная концепция объектно-ориентированного программирования полиморфизм. Это необычное слово применительно к классам и объектам означает, что мы можем единым образом работать с разными типами данных. Вообще программирование различает два типа полиморфизма. Это так называемый ad hoc полиморфизм и параметрический полиморфизм.

Первый Ad hoc существовал еще до появления объектно-ориентированного программирования и реализовывался через перегрузку функций и приведение различных типов данных. Я не буду на нем подробно останавливаться, тем более что в Python он не используется. А вот второй параметрический это очень классная вещь. Чтобы его объяснить я снова вернусь к примеру с графическим редактором, где у нас было три класса с одним базовым классом Figure. В базовый класс я также добавил метод Draw.

И вы сейчас поймете почему. Допустим, что в нашей программе для каждого дочернего класса были созданы объекты. И наша задача их нарисовать в окне программы. Для этого есть метод Draw, который присутствует в каждом дочернем классе. Так вот, если бы не было полиморфизма, то мы в программе должны были бы сначала перебрать список из объектов лайн и прорисовать каждый элемент, каждую линию.

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

Но благодаря параметрическому полиморфизму мы можем оперировать разными типами объектов через их единый базовый класс фигр. В этом случае будет достаточно создать единый список объектов, каждый элемент которого будет иметь вот такой вот тип Figure. То есть каждый объект будет приведен вот к такому типу. И это можно сделать, потому что дочерние классы наследуется вот от такого единого базового класса. А далее в этом едином списке вызвать вот этот метод Draw в базовом классе, который на самом деле будет вызывать переопределенный метод Draw соответствующего дочернего класса.

Так устроено наследование. В результате мы имеем единый интерфейс, т. Е. Класс Figure для управления самыми разными типами графических примитивов. Причем в будущем в программу можно будет добавлять новые классы графических примитивов, просто унаследовав их от этого базового класса Figure и они автоматически будут встраиваться в общую логику работы программы.

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

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