HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>21 фев 2023</li>
2 <ul><li>21 фев 2023</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><p>Объясняем сложную концепцию объектно-ориентированного программирования на примере интернет-магазина.</p>
4 </ul><p>Объясняем сложную концепцию объектно-ориентированного программирования на примере интернет-магазина.</p>
5 <p>Иллюстрация: Катя Павловская для Skillbox Media</p>
5 <p>Иллюстрация: Катя Павловская для Skillbox Media</p>
6 <p>Шеф-редактор Skillbox Media "Код". Пишет о разработке, софт-скиллах и культовых личностях в IT. Обожает Swift, продукты Apple и мемы про код.</p>
6 <p>Шеф-редактор Skillbox Media "Код". Пишет о разработке, софт-скиллах и культовых личностях в IT. Обожает Swift, продукты Apple и мемы про код.</p>
7 <p>Если вы начали изучать объектно-ориентированное программирование, то наверняка слышали о четырёх его главных концепциях:<a>абстракции</a>,<a>инкапсуляции</a>,<a>наследовании</a>и полиморфизме. Первые три мы подробно обсуждали в других статьях, а в этой поговорим о полиморфизме - разберёмся, что это такое, как работает и в чём его практический смысл для разработчика.</p>
7 <p>Если вы начали изучать объектно-ориентированное программирование, то наверняка слышали о четырёх его главных концепциях:<a>абстракции</a>,<a>инкапсуляции</a>,<a>наследовании</a>и полиморфизме. Первые три мы подробно обсуждали в других статьях, а в этой поговорим о полиморфизме - разберёмся, что это такое, как работает и в чём его практический смысл для разработчика.</p>
8 <p><strong>Перед началом:</strong>многие нюансы из этой статьи будет сложно освоить без понимания сути и основных принципов ООП. Если хотите освежить свои знания, почитайте наш<a>подробный материал</a>.</p>
8 <p><strong>Перед началом:</strong>многие нюансы из этой статьи будет сложно освоить без понимания сути и основных принципов ООП. Если хотите освежить свои знания, почитайте наш<a>подробный материал</a>.</p>
9 <ul><li><a>Что такое классы и объекты</a>.</li>
9 <ul><li><a>Что такое классы и объекты</a>.</li>
10 <li><a>Особенности работы с объектами</a>.</li>
10 <li><a>Особенности работы с объектами</a>.</li>
11 <li><a>Модификаторы доступа, инкапсуляция</a>.</li>
11 <li><a>Модификаторы доступа, инкапсуляция</a>.</li>
12 <li><a>Полиморфизм и перегрузка методов</a>.</li>
12 <li><a>Полиморфизм и перегрузка методов</a>.</li>
13 <li><a>Полиморфизм</a>.</li>
13 <li><a>Полиморфизм</a>.</li>
14 <li><a>Наследование и ещё немного полиморфизма</a>.</li>
14 <li><a>Наследование и ещё немного полиморфизма</a>.</li>
15 <li><a>Абстрактные классы и интерфейсы</a>.</li>
15 <li><a>Абстрактные классы и интерфейсы</a>.</li>
16 <li><a>Практикум</a>.</li>
16 <li><a>Практикум</a>.</li>
17 </ul><h2><strong>Что такое полиморфизм</strong></h2>
17 </ul><h2><strong>Что такое полиморфизм</strong></h2>
18 <p>Мы уже знаем, что в ООП все программы состоят из объектов. Но у разных на вид объектов может быть одинаковый интерфейс - какие-то общие методы, которые они выполняют каждый по-своему. Например, у объектов "квадрокоптер" и "самолёт" общим методом будет "летать".</p>
18 <p>Мы уже знаем, что в ООП все программы состоят из объектов. Но у разных на вид объектов может быть одинаковый интерфейс - какие-то общие методы, которые они выполняют каждый по-своему. Например, у объектов "квадрокоптер" и "самолёт" общим методом будет "летать".</p>
19 <p>Так вот,<strong>полиморфизм</strong>даёт возможность использовать одни и те же методы для объектов разных классов. Неважно, как эти объекты устроены, - в ООП можно сказать самолёту и квадрокоптеру: "Лети", и они будут делать это как умеют: квадрокоптер закрутит лопастями, а самолёт начнёт разгон по взлётно-посадочной полосе.</p>
19 <p>Так вот,<strong>полиморфизм</strong>даёт возможность использовать одни и те же методы для объектов разных классов. Неважно, как эти объекты устроены, - в ООП можно сказать самолёту и квадрокоптеру: "Лети", и они будут делать это как умеют: квадрокоптер закрутит лопастями, а самолёт начнёт разгон по взлётно-посадочной полосе.</p>
20 <p>Грубо говоря, полиморфизм - это диспетчер в аэропорту. Ему неважно, какую топливную систему предусмотрел авиаконструктор и как работает система форсажа - он просто даёт команду: "Взлёт разрешаю". После этого на лайнере начинают происходить какие-то свои внутренние процессы, на которые диспетчер уже не влияет.</p>
20 <p>Грубо говоря, полиморфизм - это диспетчер в аэропорту. Ему неважно, какую топливную систему предусмотрел авиаконструктор и как работает система форсажа - он просто даёт команду: "Взлёт разрешаю". После этого на лайнере начинают происходить какие-то свои внутренние процессы, на которые диспетчер уже не влияет.</p>
21 <p><strong>Минутка семантики.</strong>Слово "полиморфизм" переводится с греческого как "многоформенность". Смысл в том, что один и тот же метод может воплощаться по-разному - например, как полёт у дрона и самолёта.</p>
21 <p><strong>Минутка семантики.</strong>Слово "полиморфизм" переводится с греческого как "многоформенность". Смысл в том, что один и тот же метод может воплощаться по-разному - например, как полёт у дрона и самолёта.</p>
22 <p>Допустим, мы делаем онлайн-магазин с мерчем известного ютуб-канала. У нас есть три вида товаров: футболки, кружки и блокноты. Задача - сделать так, чтобы все их можно было складывать в корзину и сайт каждый раз автоматически выдавал покупателю сообщение: "Товар такой-то добавлен в корзину". Как это сделать?</p>
22 <p>Допустим, мы делаем онлайн-магазин с мерчем известного ютуб-канала. У нас есть три вида товаров: футболки, кружки и блокноты. Задача - сделать так, чтобы все их можно было складывать в корзину и сайт каждый раз автоматически выдавал покупателю сообщение: "Товар такой-то добавлен в корзину". Как это сделать?</p>
23 <p>Есть два варианта. Можно писать свою версию метода "добавить в корзину" на каждую категорию товара - но это долго, да и код получится неопрятный. А можно написать один полиморфный метод, а потом использовать его для каждого нового объекта - и вот это как раз наш случай. Разберём весь процесс пошагово.</p>
23 <p>Есть два варианта. Можно писать свою версию метода "добавить в корзину" на каждую категорию товара - но это долго, да и код получится неопрятный. А можно написать один полиморфный метод, а потом использовать его для каждого нового объекта - и вот это как раз наш случай. Разберём весь процесс пошагово.</p>
24 <p>Базовый класс описывает общие свойства объектов. Например, у нас это название товара и возможность добавлять его в корзину.</p>
24 <p>Базовый класс описывает общие свойства объектов. Например, у нас это название товара и возможность добавлять его в корзину.</p>
25 public class Good // Объявляем класс "Товар" { public string name; // Указываем свойство "Название" // Создаём метод "Добавить в корзину" // Virtual означает, что метод потом можно будет дополнить под нужды конкретного товара. public virtual void AddToCart() { Console.WriteLine("Товар " + name + " добавлен в корзину"); } }<p>Пока всё это выглядит очень абстрактно, но дальше - больше.</p>
25 public class Good // Объявляем класс "Товар" { public string name; // Указываем свойство "Название" // Создаём метод "Добавить в корзину" // Virtual означает, что метод потом можно будет дополнить под нужды конкретного товара. public virtual void AddToCart() { Console.WriteLine("Товар " + name + " добавлен в корзину"); } }<p>Пока всё это выглядит очень абстрактно, но дальше - больше.</p>
26 <p>Производные классы расширяют функциональность основного. То есть задают какие-то дополнительные параметры - в нашем случае это характеристики товаров: размер футболки, объём кружки и количество страниц у блокнота.</p>
26 <p>Производные классы расширяют функциональность основного. То есть задают какие-то дополнительные параметры - в нашем случае это характеристики товаров: размер футболки, объём кружки и количество страниц у блокнота.</p>
27 public class Cup : Good // Создаём класс "Кружка" { public int volume; // Вводим дополнительное свойство "Объём" public override void AddToCart() // Override означает, что мы переопределяем метод AddToCart и добавляем ему новую функциональность { Console.WriteLine("Кружка " + name + " объёмом " + volume + " мл добавлена в корзину"); } } public class Note : Good // Создаём класс "Блокнот" { public int pages; // Добавляем свойство "Количество страниц" public override void AddToCart() { Console.WriteLine("Блокнот " + name + " на " + pages + " страниц добавлен в корзину"); } } public class Shirt : Good // Создаём класс "Футболка" { public int size; // Добавляем свойство "Размер" public override void AddToCart() { Console.WriteLine("Футболка " + name + " размером " + size + " добавлена в корзину"); } }<p>Допустим, пользователь зашёл в наш магазин и решил купить три товара: футболку "Кислота" 48 размера, кружку "Омут" на 250 мл и блокнот "Древо жизни" на 180 страниц. Поставил он галочки напротив каждого товара, нажал "Добавить в корзину" - и вот какая история начинает происходить в коде:</p>
27 public class Cup : Good // Создаём класс "Кружка" { public int volume; // Вводим дополнительное свойство "Объём" public override void AddToCart() // Override означает, что мы переопределяем метод AddToCart и добавляем ему новую функциональность { Console.WriteLine("Кружка " + name + " объёмом " + volume + " мл добавлена в корзину"); } } public class Note : Good // Создаём класс "Блокнот" { public int pages; // Добавляем свойство "Количество страниц" public override void AddToCart() { Console.WriteLine("Блокнот " + name + " на " + pages + " страниц добавлен в корзину"); } } public class Shirt : Good // Создаём класс "Футболка" { public int size; // Добавляем свойство "Размер" public override void AddToCart() { Console.WriteLine("Футболка " + name + " размером " + size + " добавлена в корзину"); } }<p>Допустим, пользователь зашёл в наш магазин и решил купить три товара: футболку "Кислота" 48 размера, кружку "Омут" на 250 мл и блокнот "Древо жизни" на 180 страниц. Поставил он галочки напротив каждого товара, нажал "Добавить в корзину" - и вот какая история начинает происходить в коде:</p>
28 using System; class Program { static void Main() { // Создаём объекты для каждого товара Shirt someShirt = new Shirt(); someShirt.name = "Кислота"; // Футболка "Кислота" someShirt.size = 48; Cup someCup = new Cup(); // Кружка "Омут" someCup.name = "Омут"; someCup.volume = 250; Note someNote = new Note(); someNote.name = "Древо жизни"; // Блокнот "Древо жизни" someNote.pages = 180; // Создаём массив из всех трёх объектов Good[] goods = new Good[3]; goods[0] = someShirt; goods[1] = someCup; goods[2] = someNote // С помощью цикла вызываем метод "Добавить в корзину" для каждого товара for(int i = 0; i &lt; 3; i++) { goods[i].AddToCart(); } } }<p>Мы объединили товары в массив и с помощью цикла применили метод AddToCart сразу ко всем. Если бы наш магазин был реальным, пользователь получил бы примерно такие сообщения:</p>
28 using System; class Program { static void Main() { // Создаём объекты для каждого товара Shirt someShirt = new Shirt(); someShirt.name = "Кислота"; // Футболка "Кислота" someShirt.size = 48; Cup someCup = new Cup(); // Кружка "Омут" someCup.name = "Омут"; someCup.volume = 250; Note someNote = new Note(); someNote.name = "Древо жизни"; // Блокнот "Древо жизни" someNote.pages = 180; // Создаём массив из всех трёх объектов Good[] goods = new Good[3]; goods[0] = someShirt; goods[1] = someCup; goods[2] = someNote // С помощью цикла вызываем метод "Добавить в корзину" для каждого товара for(int i = 0; i &lt; 3; i++) { goods[i].AddToCart(); } } }<p>Мы объединили товары в массив и с помощью цикла применили метод AddToCart сразу ко всем. Если бы наш магазин был реальным, пользователь получил бы примерно такие сообщения:</p>
29 Футболка "Кислота размером" 48 добавлена в корзину Кружка "Омут" объёмом 250 мл добавлена в корзину Блокнот "Древо жизни" на 180 страниц добавлен в корзину<p>То есть мы достигли как раз того результата, который и планировали. Запустить код программы целиком и посмотреть, как он работает, можно<a>по этой ссылке</a>.</p>
29 Футболка "Кислота размером" 48 добавлена в корзину Кружка "Омут" объёмом 250 мл добавлена в корзину Блокнот "Древо жизни" на 180 страниц добавлен в корзину<p>То есть мы достигли как раз того результата, который и планировали. Запустить код программы целиком и посмотреть, как он работает, можно<a>по этой ссылке</a>.</p>
30 <p>Смысл полиморфизма в том, что нам не надо писать для каждого товара свой метод - например, какой-нибудь AddToCartShirt для футболки или AddToCartCup для кружки. У нас просто есть один AddToCart, и мы на него полагаемся. Если в магазине появятся, например, кепки, мы просто немного допилим наш метод под особенности кепок, и дело в шляпе.</p>
30 <p>Смысл полиморфизма в том, что нам не надо писать для каждого товара свой метод - например, какой-нибудь AddToCartShirt для футболки или AddToCartCup для кружки. У нас просто есть один AddToCart, и мы на него полагаемся. Если в магазине появятся, например, кепки, мы просто немного допилим наш метод под особенности кепок, и дело в шляпе.</p>
31 <p>Особенно это актуально в больших коммерческих программах со сложной логикой. Представьте, если бы у нас был не магазин с аксессуарами, а крупный маркетплейс вроде "Озона". Там без полиморфизма просто не обойтись - иначе код превратится в лапшу из функций, которые делают одно и то же, а называются по-разному.</p>
31 <p>Особенно это актуально в больших коммерческих программах со сложной логикой. Представьте, если бы у нас был не магазин с аксессуарами, а крупный маркетплейс вроде "Озона". Там без полиморфизма просто не обойтись - иначе код превратится в лапшу из функций, которые делают одно и то же, а называются по-разному.</p>
32 <p>Отсюда можно выделить три главных преимущества полиморфизма:</p>
32 <p>Отсюда можно выделить три главных преимущества полиморфизма:</p>
33 <ul><li><strong>Читаемость.</strong>Чем меньше кода и чем лучше он упакован, тем проще работать программистам и тем быстрее идёт разработка.</li>
33 <ul><li><strong>Читаемость.</strong>Чем меньше кода и чем лучше он упакован, тем проще работать программистам и тем быстрее идёт разработка.</li>
34 <li><strong>Масштабируемость.</strong>Можно добавить в магазин носки, ручки, напульсники, подвески и ещё кучу разных товаров, а за их покупку всё равно будет отвечать одна команда - AddToCart.</li>
34 <li><strong>Масштабируемость.</strong>Можно добавить в магазин носки, ручки, напульсники, подвески и ещё кучу разных товаров, а за их покупку всё равно будет отвечать одна команда - AddToCart.</li>
35 <li><strong>Предсказуемость кода.</strong>Когда у нас есть один метод для разных объектов, мы чувствуем себя спокойно. Можно не переживать, что команда "Добавить в корзину трусы" случайно применится к носкам и вызовет какой-то сбой в программе.</li>
35 <li><strong>Предсказуемость кода.</strong>Когда у нас есть один метод для разных объектов, мы чувствуем себя спокойно. Можно не переживать, что команда "Добавить в корзину трусы" случайно применится к носкам и вызовет какой-то сбой в программе.</li>
36 </ul><p>В ООП под полиморфизмом понимают только одну его разновидность - полиморфизм подтипов. Он как раз отвечает за то, чтобы объекты разных классов можно было вызывать одним методом. Но существует ещё два вида полиморфизма:<strong>параметрический</strong>и <strong>ad-hoc</strong>. О них мы и поговорим в следующих статьях - разберёмся, чем они различаются и для чего нужны.</p>
36 </ul><p>В ООП под полиморфизмом понимают только одну его разновидность - полиморфизм подтипов. Он как раз отвечает за то, чтобы объекты разных классов можно было вызывать одним методом. Но существует ещё два вида полиморфизма:<strong>параметрический</strong>и <strong>ad-hoc</strong>. О них мы и поговорим в следующих статьях - разберёмся, чем они различаются и для чего нужны.</p>
37 <a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
37 <a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>