В программировании есть несколько парадигм — это набор правил и приёмов, как писать код. Вроде этикета за столом, в общественном месте. Или стиля художников конкретной эпохи: как делать мазки, какими красками пользоваться и какие объекты предпочтительно рисовать. Программисты договорились писать в одних правилах, чтобы понимать друг друга и создавать рабочие вещи.
Как и стандарты художников, парадигмы со временем меняются. Раньше единственно верным было процедурное программирование. Сейчас всё зависит от задачи и умений программиста сделать просто и понятно.
Одна из парадигм — объектно-ориентированное программирование. В статье расскажем о главных её принципах. Это сложная тема, поэтому углубляться в код мы не будем, а рассмотрим на примерах.
Что такое процедурное программирование
Начинать стоит с истоков современного программирования — процедурной парадигмы. Следующие правила — вызов, чтобы решить проблемы этой парадигмы. Рассмотрим на примере.
Самое простое сравнение — человек. Все мы — это набор клеток, из которых состоит тело: руки, ноги, органы чувств, кровеносные сосуды, мозг. Мы выполняем разнообразные действия: ходим, бегаем, смеёмся, спим и т.д.
В процедурном программировании делают простые последовательности действий. Например, человеку нужно утром пойти на работу. Для этого следует алгоритму: проснуться, позавтракать, одеться, пойти на работу. Для процедурной парадигмы это — завершённая программа.
А теперь расширим кругозор. Представим, что мир — это большая программа. И в ней живут тысячи таких человечков. У каждого свой набор клеток и генов. Они похожи по общим признакам: геном, части тела, строение мозга. Но занимаются человечки разными вещами: пока один пошёл на работу, другой — сидит за компьютером. Третий — читает книгу. Миллиарды человечков делают свои дела.
Если бы мир писали через правила процедурной парадигмы, человечки бы пошли в разные стороны. Программа развалилась.
Каждый человечек перетягивает одеяло: одному нужно на работу, другому — за ПК. Программа сыпется, потому что процедура — набор последовательных действий. А вместо одной последовательности — хаос.
Для сложных программ процедурное программирование не подходит. Если оставить парадигму, придётся выкручиваться:
-
Либо писать длинный код. Тогда следующие разработчики будут долго разбираться и читать строки. Проще написать новую программу.
-
Либо выкидывать программу и писать новую. Тратится куча времени и сил разработчиков, чтобы переписать те же свойства: руки, ноги, голова. А к ним добавить новые — действия человечков.
Чтобы решать сложные задачи, программисты договорились и придумали для этого новые стандарты. Назвали правила объектно-ориентированным программированием.
Что такое ООП
Мир состоит из объектов: человек, котик, компьютерная мышка или плита на кухне. У человека есть всё для существования — руки, ноги, органы и т.д. Компьютерная мышка тоже имеет всё, чтобы работать: провод или беспроводной датчик, корпус, лампочки, кнопки для клика. Все объекты состоят из таких деталей — набора данных для нормальной работы.
ООП — это тоже мир, но в программировании. Он состоит из объектов, а те — из своих деталек.
Вернёмся к примеру с человечками. У каждого есть похожий набор параметров-генов. Эти параметры — первый объект. Например, строение тела.
Также, все люди могут выполнять однотипные действия — ходить, бегать, плавать и т.д. Эти параметры относятся к первому объекту. Такой себе, стандартный человечек.
Если говорить языком ООП, то руки и ноги — переменные. Это конкретный набор данных, который можно подставить для любого человечка.
Ходить и прыгать — функции. Это действия, которые может выполнять человечек. Если бы мы писали программу, то функция Человечек. Ходить — это процедурная программа. Один параметр и одно действие.
А теперь добавим другие объекты. Например, человечки из разных континентов: Африка, Азия и Европа. У них похожий набор параметров (человечек). Но есть и свои — цвет кожи, рост, вес, цвет волос, тембр речи, возраст и т.д.
По правилам процедурного программирования мы бы сложили все параметры в одну коробку — программа готова. А для нового человечка раз за разом скопипастили переменные и функции. Представьте, сколько кода!
По принципам ООП общие характеристики складываются по коробкам — объектам. А те взаимодействуют между собой. Например, коробка человечков из Европы возьмёт общие характеристики из одной коробки, добавив свои.
Как видим, коробки с параметрами человечков соединяются и между собой. В реальной жизни так получаются смешанные расы: метисы, мулаты и другие. Ничего не писали заново, а просто смешали готовые коробочки — объекты.
Так в мире можно соединяется много вещей. Например, у животных есть много функций, которыми пользуются люди: ходьба, бег, прыжки. Для овощей и фруктов своя программа на ООП. А для компьютерных мышек и клавиатур — своя. Всё взаимосвязано и находится в своих коробочках.
Главные принципы ООП
То, как соединяются объекты в ООП, определяет четыре правила: инкапсуляция, абстракция, наследование и полиморфизм. Без них в объектно-ориентированном программировании делать нечего.
Инкапсуляция — объект независим от остальных. Например, если убрать коробку с главными характеристиками человечков, то другие не перестанут работать. Они возьмут эти же характеристики, но оставят внутри своей коробочки.
Абстракция ООП — у каждого объекта есть внутренний интерфейс. Представим, что нам нужно внести в программу всех сотрудников компании.
-
Что важно для человека, как живого существа: рост, вес, органы, кровеносные сосуды.
-
А что важно для работодателя: должность, возраст, семейное положение, заработная плата.
Вторые характеристики более важные для работодателя. Они и будут в объекте «Сотрудник компании».
Если бы мы создавали объект «Спортсмен», то для него важны другие переменные и функции: рост, вес, телосложение, возраст. Параметры для работодателя ему вряд ли пригодятся. Поэтому интерфейс их не использует, даже если данные внесли по какой-то причине.
Поэтому абстракция — самостоятельный интерфейс. Нам не важно, что внутри него. Важнее то, что нам дают правильные переменные и функции: работодателю — свои. А тренеру спортивной команды — свои.
Наследование — способность копировать переменные и функции с других объектов. Пример с человечками — родовое дерево.
Каждый человек — набор генов прошлых поколений. От мамы передались голубые глаза. От папы — родинка на плече. А от дедушки — высокий рост. Это и есть наследование: взять из объектов несколько переменных и функций. А из них создать новый.
С наследованием в программировании можно не копипастить код, а создать один вариант, который понадобится для всех объектов. После объекты подключить и всё заработает. Или переиспользовать код в будущем: для новых человечков, как в примере.
Полиморфизм — язык используется без «синонимов». Например, для всех человечков действие «ходить» — это одинаковый метод. Он звучит только так. Если мы для одного человечка напишем «ходить», а для другого «карабкаться» — это разные методы.
Так можно заранее продумывать связь между модулями. Возьмём для примера сервис рассылок в интернет-магазине. Это набор объектов из товаров и покупателей. И есть набор методов — придуманных программистом действий в рассылке.
-
Например, для покупок метод .Удалить — предупредить покупателя, а после отправить в архив.
-
А для пользователя метод .Удалить — отписать от рассылки и удалить аккаунт.
Метод может работать в разных объектах по-разному. Но программист об этом знает, поэтому доверяет методу .Удалить, и не придумывает синонимы.
Плюсы и минусы ООП
У объектно-ориентированного программирование много плюсов. Поэтому подход используется почти во всех современных языках программирования.
Вот неполный перечень языков программирования, в которых поддерживаются принципы ООП: Python, C++, Ruby, C#, JavaScript, Objective-C. А, например, Java — это чистый объектно-ориентированный язык.
-
Код просто читать. Помните структуру программы в процедурном программировании: дерево из строчек кода, где добавить элемент — переписать часть дерева и добавить корней. В ООП всё разбито на объекты и сразу понятно — из чего он состоит, и что из него берут другие объекты.
-
Меньше копипаста. В процедурном программировании ничего необычного, если для похожего кода дважды переписывают одинаковые значения. В ООП копипаст решается принципом наследования.
-
Сложные программы выглядят и пишутся проще. В начале статьи как пример комплексной программы мы приводили наш мир. ООП разбивает мир на маленькие блоки — их легко написать. А если нужно — подробно углубиться в конкретный объект.
-
Программы пишутся на едином языке. Между программистами нет «языкового барьера»: работу первого легко прочитает второй. Не копаясь в дереве с кучей корней, а пройдётся от объекта к объекту. Это как читать книгу: страница за страницей.
Без минусов ООП не остался:
-
Сложнее процедурного программирования. Нужно знать много теории: изучить строение объектов, их связь и принципы. В этой статье лишь общая информация. Если углубиться — деталей больше.
-
Потребуется больше памяти на обслуживание кода. Объекты ООП состоят из методов, переменных, внутренних интерфейсов. Структуры занимают больше памяти, чем в процедурном программировании. Но сейчас это менее важно. У всех дома компьютеры или ноутбуки с процессорами от 4 ядер, сносной оперативной памятью и видеокартами.
ООП — одна из главных тем программирования на курсе по Python. Студенты на каждом уроке подробно рассматривают принципы парадигмы, и как их использовать в повседневной работе программиста. А через принципы учат паттерны ООП — готовые структуры кода, с которыми работать быстрее. Подробности о курсе и программе обучения по ссылке.