Полиморфизм - что это? Генетический полиморфизм. Что такое полиморфизм в Java Что означает термин полиморфизм

Лекция в виде презентации в формате pdf с примерами - 27 слайдов.
ВолгГТУ, кафедра ПОАС, - 2010 год

В лекции рассмотрены все формы полиморфизма функций и методов т представлена их иерархия в виде схемы.

Фрагменты из лекции

Понятие полиморфизма

  • Полиморфизм в языке программирования означает многозначность переменных и функций
  • Полиморфной функцией является такая функция, которая может вызываться с аргументами различного типа, а фактический выполняемый код зависит от типа аргументов

Преимущества использования полиморфизма

  • Полиморфизм позволяет записывать алгоритмы лишь однажды и затем повторно их использовать для различных типов данных, которые, возможно, еще не существуют (обобщенные действия или алгоритмы)
  • Полиморфизм сужает концептуальное пространство, т.е. уменьшает количество информации, которое необходимо помнить программисту

Параметризованный полиморфизм

  • Обеспечивается за счет так называемых обобщенных функций, которые в языке Си++ называются шаблонами
  • Аргументом обобщенной функции является тип, который используется при ее параметризации
  • С помощью механизма шаблонов можно создать функцию, которая бы работала с разнотипными аргументами
  • Примером таких функций являются обобщенные алгоритмы из STL

Чистый полиморфизм

  • Чистый полиморфизм имеет место, когда одна и та же функция применяется к аргументам различных типов
  • В случае чистого полиморфизма имеется одна функция (тело кода) и несколько ее интерпретаций
  • Реализация чистого полиморфизма возможна только при наличии полиморфных переменных, а точнее полиморфных аргументов
  • Чистый полиморфизм позволяет реализовывать обобщенные алгоритмы
Перегрузка или полиморфизм ad hoc
  • Перегрузка возникает, когда имеется два или более кода, связанных с одним именем
  • Главное назначение перегрузки − сужение концептуального пространства
Перегрузка методов в несвязанных классах
  • Все ОО-языки разрешают использовать методы с одинаковыми именами в несвязанных между собою классах − это перегрузка методов
  • В этом случае привязка перегруженного имени производится за счет информации о классе, к которому относится получатель сообщения

Параметрическая перегрузка

  • Стиль перегрузки, при котором функциям и методам в одном и том же контексте разрешается использовать совместно одно имя, а двусмысленность снимается за счет анализа числа и типов аргументов, называется параметрической перегрузкой.
Замещение методов
  • Замещение возникает, когда в базовом и производном классах имеются два метода с одинаковым именем и параметрами
  • В этом случае метод базового класса перекрывается методом производного класса с точки зрения пользователя класса
Назначение механизма замещения методов
  • Замещение происходит прозрачно (незаметно) для пользователя класса, и, как в случае перегрузки, два метода представляются семантически как одна сущность
  • Главное назначение замещения методов − сужение концептуального пространства
Пример замещения метода

Class MyEllipse
{
public:
float area() const

};


{
public:
float area() const
{//использ. более эффективный алгоритм расчета
}
};

MyEllipse ellipse;
MyCircle circle;

// Будет вызван метод MyEllipse::area()
ellipse.print();


// ВНИМАНИЕ!!! Будет вызван метод MyEllipse::area()
circle.print();


Переопределение методов
  • При замещении метод базового класса перекрывается методом производного класса только снаружи. Внутри класса вызывается метод базового класса (см. предыдущий пример)
  • Переопределение метода возникает, когда метод производного класса подменяет метод базового класса не только снаружи, но и внутри класса
  • В языке Си++ для переопределения метода необходимо использовать механизм динамического связывания, т.е. объявить метод виртуальным
Пример переопределения метода

Class MyEllipse
{
public:
virtual float area() const
{ /* численный метод расчета */ }
void print() { printf("area = %f\n", area()); }
};
class MyCircle: public MyEllipse
{
public:
float area() const
{ //использ. более эффективн. алгоритм расчета
return 3.14*Radius1*Radius2;
}
};

MyEllipse ellipse;
MyCircle circle;

// Будет вызван метод MyEllipse::area()
printf("Ellipse area= %f\n", ellipse.area());

// Будет вызван метод MyEllipse::area()
ellipse.print();

// Будет вызван метод MyCircle::area()
printf("Circle area= %f\n", circle.area());

// ВНИМАНИЕ!!! Будет вызван метод MyCircle::area()
circle.print();

Назначение механизма переопределения методов
  • Наличие механизма переопределения методов позволяет реализовать в базовом классе общую часть поведения, подразумевая, что отдельные действия будут доопределены (переопределены) в производных классах
  • Таким образом, главное назначение механизма переопределения методов - сокращение объема программы

Отложенные методы

  • Отложенный метод − это частный случай переопределения, когда метод базового класса не имеет реализации, а любая полезная деятельность задается в методе дочернего класса
Отложенные методы в языке Си++
  • В языке Си++ отложенный метод должен быть описан в явном виде с ключевым словом virtual
  • Тело отложенного метода не определяется, вместо этого функции «приписывается» значение 0

Полиморфизм – это принцип ООП, который позволяет использовать один интерфейс и разные алгоритмы. Целью полиморфизма, применительно к ООП, является использование одного имени для задания разных действий. Выполнение действия будет определяться типом данных.

Виды полиморфизма:

Статический (определяется во время компиляции). Перегрузка функций, методов, операторов и т.д.

Динамический (определяется во время выполнения). Содержит виртуальные функции и методы.

22. Наследование как механизм реализации полиморфизма, создания иерархий классов. Типы наследования.

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

Типы наследования: прямое и косвенное, простое и множественное.

23. Классы. Базовые, производные, полиморфные, абстрактные, виртуаль-ные. Примеры.

Класс – особый тип данных, в котором описываются и атрибуты данных и действия, выполняемые над атрибутами.

Базовый класс – класс, члены которого наследуются.

Производный класс – класс, который наследует чужие члены.

Полиморфный класс – класс, содержащий виртуальные методы.

Абстрактный класс – класс, содержащий чисто виртуальные методы.

Виртуальный класс - класс, который при множественном наследовании не включается в классы-потомки, а заменяется ссылкой в них, во избежание дублирования.

24. Принципы раннего и позднего связывания.

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

Ранее связывание - установка таких связей до начала выполнения программы. Обычно под этим понимается связывание в процессе компиляции исходных модулей и компоновки исполняемого модуля из объектных.

Позднее связывание - установка связей в процессе выполнения программы. Речь идет обычно либо о динамических связях (когда только в ходе работы приложения определяется какие объекты будут нужны) либо о формировании таких объектов во время работы.

25. Использование языка uml для спецификации

26. Описание иерархий классов диаграммами uml.

Отношения классов через . И показать разные отношения: прямое, косвенное, множественное.

27. Классы-шаблоны. Описание в uml.

Шабло́н класса - средство языка C++, предназначенное для кодирования обобщённых алгоритмов классов, без привязки к некоторым параметрам (например, типам данных, размерам буферов, значениям по умолчанию).

Синтаксис:

template

class NAME_CLASS

NAME_CLASS B; //Вызов

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

Постановка задачи

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

Самые простые варианты, которые приходят в голову — написать три отдельных класса и работать с ними. Или написать один класс, в которым будут все свойства, присущие всем трем типам публикаций, а задействоваться будут только нужные. Но ведь для разных типов аналогичные по логике методы должны работать по-разному. Делать несколько однотипных методов для разных типов (get_news, get_announcements, get_articles) — это уже совсем неграмотно. Тут нам и поможет полиморфизм.

Абстрактный класс

Грубо говоря, это класс-шаблон. Он реализует функциональность только на том уровне, на котором она известна на данный момент. Производные же классы ее дополняют. Но, пора перейти от теории к практике. Сразу оговорюсь, рассматривается примитивный пример с минимальной функциональностью. Все объяснения — в комментариях в коде.

abstract class Publication
{
// таблица, в которой хранятся данные по элементу
protected $table ;

// свойства элемента нам неизвестны
protected $properties = array();

// конструктор

{
// обратите внимание, мы не знаем, из какой таблицы нам нужно получить данные
$result = mysql_query ("SELECT * FROM `" . $this -> table . "` WHERE `id`="" . $id . "" LIMIT 1" );
// какие мы получили данные, мы тоже не знаем
$this -> properties = mysql_fetch_assoc ($result );
}

// метод, одинаковый для любого типа публикаций, возвращает значение свойства
public function get_property ($name )
{
if (isset($this -> properties [ $name ]))
return $this -> properties [ $name ];

Return false ;
}

// метод, одинаковый для любого типа публикаций, устанавливает значение свойства
public function set_property ($name , $value )
{
if (!isset($this -> properties [ $name ]))
return false ;

$this -> properties [ $name ] = $value ;

Return $value ;
}

// а этот метод должен напечатать публикацию, но мы не знаем, как именно это сделать, и потому объявляем его абстрактным
abstract public function do_print ();
}

Производные классы

Теперь можно перейти к созданию производных классов, которые и реализуют недостающую функциональность.

class News extends Publication
{
// конструктор класса новостей, производного от класса публикаций
public function __construct ($id )
{
// устанавливаем значение таблицы, в которой хранятся данные по новостям
$this -> table = "news_table" ;
parent :: __construct ($id );
}

Public function do_print ()
{
echo $this -> properties [ "title" ];
echo "

" ;
echo $this -> properties [ "text" ];
echo "
Источник: " . $this -> properties [ "source" ];
}
}

Class Announcement extends Publication
{
// конструктор класса объявлений, производного от класса публикаций
public function __construct ($id )
{
// устанавливаем значение таблицы, в которой хранятся данные по объявлениям
$this -> table = "announcements_table" ;
// вызываем конструктор родительского класса
parent :: __construct ($id );
}

// переопределяем абстрактный метод печати
public function do_print ()
{
echo $this -> properties [ "title" ];
echo "
Внимание! Объявление действительно до "
. $this -> properties [ "end_date" ];
echo "

" . $this -> properties [ "text" ];
}
}

Class Article extends Publication
{
// конструктор класса статей, производного от класса публикаций
public function __construct ($id )
{
// устанавливаем значение таблицы, в которой хранятся данные по статьям
$this -> table = "articles_table" ;
// вызываем конструктор родительского класса
parent :: __construct ($id );
}

// переопределяем абстрактный метод печати
public function do_print ()
{
echo $this -> properties [ "title" ];
echo "

" ;
echo $this -> properties [ "text" ];
echo "
" . $this -> properties [ "author" ];
}
}

Теперь об использовании

Суть в том, что один и тот же код используется для обьектов разных классов.

// наполняем массив публикаций объектами, производными от Publication
$publications = new News ($news_id );
$publications = new Announcement ($announcement_id );
$publications = new Article ($article_id );

Foreach ($publications as $publication ) {
// если мы работаем с наследниками Publication
if ($publication instanceof Publication ) {
// то печатаем данные
$publication -> do_print ();
} else {
// исключение или обработка ошибки
}
}

Вот и все. Легким движением руки брюки превращаются в элегантные шорты:-).

Основная выгода полиморфизма — легкость, с которой можно создавать новые классы, «ведущие себя» аналогично родственным, что, в свою очередь, позволяет достигнуть расширяемости и модифицируемости. В статье показан всего лишь примитивный пример, но даже в нем видно, насколько использование абстракций может облегчить разработку. Мы можем работать с новостями точно так, как с объявлениями или статьями, при этом нам даже не обязательно знать, с чем именно мы работаем! В реальных, намного более сложных приложениях, эта выгода еще ощутимей.

Немного теории

  • Методы, которые требуют переопределения, называются абстрактными. Логично, что если класс содержит хотя бы один абстрактный метод, то он тоже является абстрактным.
  • Очевидно, что обьект абстрактного класса невозможно создать, иначе он не был бы абстрактным.
  • Производный класс имеет свойства и методы, принадлежащие базовому классу, и, кроме того, может иметь собственные методы и свойства.
  • Метод, переопределяемый в производном классе, называется виртуальным. В базовом абстрактном классе об этом методе нет никакой информации.
  • Суть абстрагирования в том, чтобы определять метод в том месте, где есть наиболее полная информация о том, как он должен работать.
UPD: по поводу sql-inj и нарушения MVC — господа, это просто пример, причем пример по полиморфизму, в котором я не считаю нужным уделять значения этим вещам. Это тема для совсем других статей.

Программирование - это процесс разработки решений «живых», динамичных задач в виде жёстких конструкций кода, данных, функций и алгоритмов. Процедура формирования строгого синтаксиса из неопределенной семантики. Реальные задачи - известная большая проблема алгоритмизации: чтобы достигнуть нужного решения, задачу нужно поместить в точные синтаксические конструкции.

ООП дважды делало попытку «сломать» эту древнюю концепцию программирования, но «оковы» классического стиля кодирования данных и алгоритмов все еще крепки.

Уровень и квалификация

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

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

Формы полиморфизма ООП, идеи инкапсуляции кода и наследование свойств (методов) лежат в сфере программирования, но никак не в сфере решаемой задачи.

Показательный пример - библиотека PHPOffice/PHPWord. Для её использования нужна квалификация разработчика, нужно создавать собственную систему объектов, но текущий уровень заказчика (требования заказчика) - это тривиальная композиция, которую программист перекрывает своей разработкой (иначе требования не удовлетворить). Ситуация вроде такой:

В данном случае применение библиотеки - задача форматирования документов, например, диплом или диссертация должны быть оформлены по стандарту. Заказчик предъявил свои требования, а программист пошел своим путем гораздо дальше.

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

Полиморфизм и ООП

Лучшего определения для полиморфизма не придумать, как сослаться на историю развития идеи объектно-ориентированного программирования, столь популярную ныне, столь часто используемую, но нереализованную в сути своей до сих пор.

  • инкапсуляция;
  • полиморфизм;
  • наследование.

Некоторые добавляют ещё: абстракция, и чаще всего именно этот, причем действительно основной момент, используют как фундамент для описания сущности ООП.

Итак, мнения об ООП полиморфны: описывают одно, сконструированы по-разному, или, наоборот, описывают разное, но базируются на четырех одинаковых позициях.

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

Популярные определения полиморфизма

ООП - очередной этап развития информационных технологий. С этим мало кто спорит, но его основные аксиомы и положения так разнятся в части семантики, что не заслуживают внимания вне их совокупности.

  1. Полиморфизм в программировании - это способность предоставлять один и тот же интерфейс для различных базовых форм (типов данных).
  2. Полиморфизм - возможность объектов иметь различную реализацию.
  3. Полиморфизмом называется способность функции...
  4. Классика (от создателя С/С++): «один интерфейс - много реализаций».
  5. Параметрический полиморфизм подразумевает...
  6. Полиморфизм - положение теории типов...
  7. Абстракция невозможна без инкапсуляции и наследования, как невозможен полиморфизм без наследования...

Можно согласиться, что всё это относится к одному и тому же: но форма выражения мысли, сущность и содержание - не подобны. Но что-то общее всё же есть.

Сущность: разработчик - заказчик

Классическая разработка программ предполагает наличие программиста и задачи (клиент, заказчик). Программист исследует задачу, формализует её и делает код, который приводит к решению. Заказчик отрицает всё предложенное или только его часть, указывая на недоработки, и программист делает свою работу вновь.

Такой круговорот процесса решения задачи наводит на мысль, что здесь явно совмещены две совершенно разные сущности:

  • компьютер не может сам решить задачу;
  • нужна программа, чтобы компьютер мог «понять» и «решить» задачу.

Задача - сфера компетенции заказчика, программа - это алгоритм «адаптации» задачи к возможностям компьютера - сфера компетенции программиста. Роль последнего заключается в «адаптации» компьютера к требованиям задачи, а это лишнее!

Предлагает абстрагироваться . Есть объекты - это сфера заказчика; есть реализация объектов - это сфера программиста. Никакой «технологической» связи между заказчиком и разработчиком. Идея кардинальная, не реализованная по сей день, но что-то уже стабильно работает.

Окна, кнопки и другие объекты

История the Air Art Technology, Object Magazine, Turbo Vision, Graph Vision - это уже история. Мало кто помнит эти реализации ООП, они практически не используются и забыты, но оконный интерфейс Windows знаком миллионам пользователей, а объекты в средах PHP, JavaScript и других языках интернет-технологий применяются сотнями тысяч разработчиков кода, о них знают миллионы посетителей веб-ресурсов.

Вероятно, это единственно правильный путь, по которому должно было развиваться ООП: инкапсуляция, наследование, полиморфизм для разработчика, но не для пользователя. Характерно, что именно эта позиция была основной при разработке визуального оформления (интерфейса) программного обеспечения Windows, прикладных программ типа Turbo Vision и Graph Vision.

Концепция, положенная в основу продуктов типа the Air Art Technology и Object Magazine, существенно отличалась. Здесь абстрактный объект был самым первым предком информационной структуры, инкапсулировал на абстрактном уровне код обработки информации. Объекты окон, кнопок, элементов визуального оформления здесь были вторичны.

В первом варианте (Windows & etc.) парадигма ООП: инкапсуляция, наследование, полиморфизм обозначалась на уровне абстрактного предка, а реализация кода формировалась на уровне каждого конкретного потомка по ветке наследования согласно нужным структуре и содержанию.

Во втором варианте (the Air Art Technology и Object Magazine) важен уровень абстрактного объекта. Что будет у конкретного потомка - не суть, главное, чтобы его ветка наследования удовлетворяла требованиям всех родителей вниз до корневой абстракции.

Объект и система объектов: алгоритм

Идеальная объектно-ориентированная концепция может манипулировать только объектами и системами объектов.

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

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

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

Программисты приняли ООП как средство для повышения качества и производительности своей работы, но не уступили ни капли «своей территории» заказчику. Основные понятия ООП - инкапсуляция, наследование, полиморфизм - остались в сфере разработки, а не трансплантировались в сферу задачи.

Объект и система объектов: задача и решение

Компьютер - программист - задача. Среднее звено лишнее. Идеально должно существовать только два, относительно зависимых, контура: (компьютер - программист) - задача. То есть, пользователь, заказчик или посетитель имеет инструмент для решения своей задачи. Как реализован инструмент, заказчика не волнует.

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

Существенно, что между задачей и компьютером нет лишнего звена, но первое понимаемо и решаемо вторым. Для достижения такой цели компьютер и заказчик должны быть связаны одной системой объектов, причем смысл, структуру и содержание каждого объекта определяет заказчик, а методы и свойства объектов реализует программист.

Идеально, когда работа заказчика по созданию нужной ему системы объектов и работа по реализации методов и свойств этих объектов разнесены во времени. Чем дальше отстоит реализация системы объектов (программист) от её смыслового наполнения (заказчик), тем качественнее процесс.

Ничто не мешает заказчику и программисту взаимодействовать в процессе решения задачи, но важно четкое разделение семантики. Каждый должен заниматься своим делом, программист не обязан осваивать область применения задачи, а заказчик не должен разбираться в коде и уж, тем более, стороны не должны давать друг другу советы в том, что их не касается.

Традиционное и объектное программирование

Базовые постулаты ООП: инкапсуляция, наследование, полиморфизм в том виде, в котором они стали привычны и востребованы, приводят к заметному улучшению качества и надежности кода, значительно ускоряют работу программиста и имеют массу других положительных качеств.

Но воз и ныне там: классическое программирование не уступает своих позиций, и многие объектно-ориентированные идеи реализованы классическим кодом.

Однако идеи ООП и рекурсия привели к адекватному влиянию на синтаксис классических операторов синтаксиса, на логику построения обычного кода, не имеющего никакого отношения к объектно-ориентированному стилю письма и мышления.

Списки и очереди преобразились, появилось понятие первого и последнего элемента массива, появились циклы «по каждому», а ссылочные варианты именования, использования и исполнения стали ещё более востребованными, чем раньше.

Собственно, сам факт, что переменные потеряли свое «чёткое» лицо (тип переменной может меняться по мере надобности, а описывать переменную вовсе нет необходимости) говорит, что классика, на самом деле, давно стала объектно-ориентированной и признала основные принципы ООП: инкапсуляция, наследование, полиморфизм как идеи, имеющие существенное значение.

Что в основе: объект или система

Абстракция, как основное концептуальное положение ООП, вне зависимости от того, где находится зона ответственности (реализация) объекта - на уровне первого абстрактного объекта или на уровне конкретного потомка, - оставляет открытым вопрос: с чего всё начинать, с объекта или с системы?

Если в основу положить объект, то он никогда не станет системой, поскольку система будет находиться внутри него, а сам он станет жёстким образом вполне конкретного начала. Здесь с абстракцией возникают проблемы: начальный объект точно фиксирует основное в решаемой задаче, то есть он уже не переносим на другую задачу.

Если в основу положить систему объектов, то получается система систем. Это трудно представить в отношении конкретной задачи, и с чего начинать разработку - тоже сложно понять. По большому счёту, полиморфизм ООП c его различиями в сущностях, формах реализации, количествах актуальных параметров в функциях даёт представление о системе, которая лежит в начале, как:

  • о вариантах решения задачи (например, меню);
  • о начальных условиях (применение задачи в разных условиях, данных);
  • о режимах работы (тестирование, настройка, работа).

Но это и подобное ему не даёт никаких оснований ставить в основу решения задачи систему объектов. Часто достаточно определить один единственный начальный объект.

История процесса решения задачи

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

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

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

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

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

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

Реальный полиморфизм ООП, пример

Сложность задач, которая по силам ООП, не сравнима с той, что доступна классическому варианту написания программ. Конечно, решить любую задачу всегда доступно обычным образом, но вопрос, сколько это будет «стоить» времени и сил, часто делает результат бесполезным.

Не так давно была разработана библиотека PHPOffice/PHPWord, но для того чтобы использовать её возможности, практически всегда приходится создавать собственную систему объектов. Например, простой файл *.docx:

представляет собой zip-архив множества файлов и папок в формате Office Open XML (OpenXML, OOXML). Каждый файл записан в тегами XML, причём при добавлении, изменении и удалении букв, слов, таблиц, списков и пр. элементов содержимое файлов начинает представлять собой последовательность тегов, которые не всегда содержат полные элементы, часто один элемент записывается множеством тегов.

Если представить этот файл в виде последовательности тегов, получится интересная картинка:

Легко заметить, что первый и единственный абзац документа представлен множеством тегов. Что касается таблицы и встроенных в неё таблиц, то объём описания всех элементов не поддается восприятию, но доступен объектно-ориентированному приложению.

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

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

Состояние области ООП

Развитие систем управления сайтами, технологий настройки и управления серверами, опыт разработки динамичных сайтов сделали объектно-ориентированное программирование доступным каждому. Проблема в том, как изменить свое мышление и привыкнуть мыслить на уровне объектов, а не в контексте последовательно исполняемого кода.

Обычно переход от классического программирования к объектно-ориентированному занимает два-три месяца, но затраты окупаются с лихвой. Потенциал современных языков программирования, в первую очередь PHP и JavaScript, удовлетворит самого искушенного разработчика.

Современное ООП - полиморфизм, наследование и возможности формирования свойств объектов - удобны и практичны, синтаксис языков и вспомогательные инструменты обеспечивают комфорт в работе и эффективность кода.

Перспективы объектной идеи

Сколько продержится классическое программирование и как будет развиваться ООП - сказать достаточно сложно. Судя по всему, разработчики инструментальных средств не планируют рассматривать контекст потребителя (пользователя, заказчика).

Инструментарий ООП - полиморфизм, наследование, инкапсуляция и абстракция - ориентируются на разработчика.

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

Привет! Это статья об одном из принципов ООП - полиморфизм.

Что такое полиморфизм

Определение полиморфизма звучит устрашающе 🙂

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

Слово "полиморфизм " может показаться сложным - но это не так. Нужно просто разбить данное определение на части и показать на примерах, что имеется в виду. Поверьте, уже в конце статьи данное определение полиморфизма покажется Вам понятным 🙂

Полиморфизм , если перевести, - это значит "много форм". Например, актер в театре может примерять на себя много ролей - или принимать "много форм".

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

Так о каких формах идет речь? Давайте сначала приведем примеры и покажем, как на практике проявляется полиморфизм, а потом снова вернемся к его определению.

Как проявляется полиморфизм

Дело в том, что если бы в Java не было принципа полиморфизма , компилятор бы интерпретировал это как ошибку:

Как видите, методы на картинке отличаются значениями, которые они принимают:

  • первый принимает int
  • а второй принимает String

Однако, поскольку в Java используется принцип полиморфизма, компилятор не будет воспринимать это как ошибку, потому что такие методы будут считаться разными :

Называть методы одинаково - это очень удобно. Например, если у нас есть метод, который ищет корень квадратный из числа, гораздо легче запомнить одно название (например, sqrt() ), чем по одному отдельному названию на этот же метод, написанный для каждого типа:

Как видите, мы не должны придумывать отдельное название для каждого метода - а главное их запоминать! Очень удобно.

Теперь Вы можете понять, почему часто этот принцип описывают фразой:

Один интерфейс - много методов

Это предполагает, что мы можем заполнить одно название (один интерфейс), по которому мы сможем обращаться к нескольким методам.

Перегрузка методов

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

Переопределение методов родителя

Когда мы наследуем какой-либо класс, мы наследуем и все его методы. Но если нам хочется изменить какой-либо из методов, который мы наследуем, мы можем всего-навсего переопределить его. Мы не обязаны, например, создавать отдельный метод с похожим названием для наших нужд, а унаследованный метод будет "мертвым грузом" лежать в нашем классе.

Именно то, что мы можем создать в классе-наследнике класс с таким же названием, как и класс, который мы унаследовали от родителя, и называется переопределением.

Пример

Представим, что у нас есть такая структура:

Вверху иерархии классов стоит класс Animal . Его наследуют три класса - Cat , Dog и Cow .

У класса "Animal" есть метод "голос" (voice). Этот метод выводит на экран сообщение "Голос". Естественно, ни собака, ни кошка не говорят "Голос" 🙂 Они гавкают и мяукают. Соответственно, Вам нужно задать другой метод для классов Cat , Dog и Cow - чтобы кошка мяукала, собака гавкала, а корова говорила "Муу".

Поэтому, в классах-наследниках мы переопределяем метод voice() , чтобы мы в консоли получали "Мяу", "Гав" и "Муу".

  • Обратите внимание: перед методом, который мы переопределяем, пишем "@Override ". Это дает понять компилятору, что мы хотим переопределить метод.

Так что же такое полиморфизм

Тем не менее, полиморфизм - это принцип. Все реальные примеры, которые мы приведодили выше - это только способы реализации полиморфизма.

Давайте снова посмотрим на определение, которое мы давали в начале статьи:

Полиморфизм - возможность применения одноименных методов с одинаковыми или различными наборами параметров в одном классе или в группе классов, связанных отношением наследования.

Выглядит понятнее, правда? Мы показали, как можно:

  • создавать "одноименные методы" в одном классе ("перегрузка методов")
  • или изменить поведение методов родительского класса ("переопределение методов").

Все это - проявления "повышенной гибкости" объектно-ориентированных языков благодаря полиморфизму.

Надеемся, наша статья была Вам полезна. Записаться на наши курсы по Java можно у нас на .