Полиморфизм - что это? Генетический полиморфизм. Что такое полиморфизм в 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
Полиморфизм — одна из трех основных парадигм ООП. Если говорить кратко, полиморфизм — это способность обьекта использовать методы производного класса, который не существует на момент создания базового. Для тех, кто не особо сведущ в ООП, это, наверно, звучит сложно. Поэтому рассмотрим применение полиморфизма на примере.
Постановка задачи
Предположим, на сайте нужны три вида публикаций — новости, объявления и статьи. В чем-то они похожи — у всех них есть заголовок и текст, у новостей и объявлений есть дата. В чем-то они разные — у статей есть авторы, у новостей — источники, а у объявлений — дата, после которой оно становится не актуальным.Самые простые варианты, которые приходят в голову — написать три отдельных класса и работать с ними. Или написать один класс, в которым будут все свойства, присущие всем трем типам публикаций, а задействоваться будут только нужные. Но ведь для разных типов аналогичные по логике методы должны работать по-разному. Делать несколько однотипных методов для разных типов (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 {
// исключение или обработка ошибки
}
}
Вот и все. Легким движением руки брюки превращаются в элегантные шорты:-).
Основная выгода полиморфизма — легкость, с которой можно создавать новые классы, «ведущие себя» аналогично родственным, что, в свою очередь, позволяет достигнуть расширяемости и модифицируемости. В статье показан всего лишь примитивный пример, но даже в нем видно, насколько использование абстракций может облегчить разработку. Мы можем работать с новостями точно так, как с объявлениями или статьями, при этом нам даже не обязательно знать, с чем именно мы работаем! В реальных, намного более сложных приложениях, эта выгода еще ощутимей.
Немного теории
- Методы, которые требуют переопределения, называются абстрактными. Логично, что если класс содержит хотя бы один абстрактный метод, то он тоже является абстрактным.
- Очевидно, что обьект абстрактного класса невозможно создать, иначе он не был бы абстрактным.
- Производный класс имеет свойства и методы, принадлежащие базовому классу, и, кроме того, может иметь собственные методы и свойства.
- Метод, переопределяемый в производном классе, называется виртуальным. В базовом абстрактном классе об этом методе нет никакой информации.
- Суть абстрагирования в том, чтобы определять метод в том месте, где есть наиболее полная информация о том, как он должен работать.
Программирование - это процесс разработки решений «живых», динамичных задач в виде жёстких конструкций кода, данных, функций и алгоритмов. Процедура формирования строгого синтаксиса из неопределенной семантики. Реальные задачи - известная большая проблема алгоритмизации: чтобы достигнуть нужного решения, задачу нужно поместить в точные синтаксические конструкции.
ООП дважды делало попытку «сломать» эту древнюю концепцию программирования, но «оковы» классического стиля кодирования данных и алгоритмов все еще крепки.
Уровень и квалификация
Компьютерное дело началось с вычислений, но скорость, с какой нарастает ускорение движения в сферу обработки информации, еще недостаточно велика, чтобы классическое программирование стало невозможным и перестало существовать.
Объективно также и то, что разработчик не настаивает, а заказчик не требует реального решения реальных задач. Обе стороны привыкли ограничиваться доступными инструментами и привычными возможностями.
Формы полиморфизма ООП, идеи инкапсуляции кода и наследование свойств (методов) лежат в сфере программирования, но никак не в сфере решаемой задачи.
Показательный пример - библиотека PHPOffice/PHPWord. Для её использования нужна квалификация разработчика, нужно создавать собственную систему объектов, но текущий уровень заказчика (требования заказчика) - это тривиальная композиция, которую программист перекрывает своей разработкой (иначе требования не удовлетворить). Ситуация вроде такой:
В данном случае применение библиотеки - задача форматирования документов, например, диплом или диссертация должны быть оформлены по стандарту. Заказчик предъявил свои требования, а программист пошел своим путем гораздо дальше.
Выполнен полный разбор документа, его сборка в нужном формате, исполнена работа с таблицами любого уровня вложенности, слияние и разделение ячеек, печать в любом направлении и пр.
Полиморфизм и ООП
Лучшего определения для полиморфизма не придумать, как сослаться на историю развития идеи объектно-ориентированного программирования, столь популярную ныне, столь часто используемую, но нереализованную в сути своей до сих пор.
- инкапсуляция;
- полиморфизм;
- наследование.
Некоторые добавляют ещё: абстракция, и чаще всего именно этот, причем действительно основной момент, используют как фундамент для описания сущности ООП.
Итак, мнения об ООП полиморфны: описывают одно, сконструированы по-разному, или, наоборот, описывают разное, но базируются на четырех одинаковых позициях.
Демократическое начало не свойственно области информационных технологий, но следует отдать должное: сочетание и совместное существование множества мнений об одном и том же - это реальный полиморфизм в действии.
Популярные определения полиморфизма
ООП - очередной этап развития информационных технологий. С этим мало кто спорит, но его основные аксиомы и положения так разнятся в части семантики, что не заслуживают внимания вне их совокупности.
- Полиморфизм в программировании - это способность предоставлять один и тот же интерфейс для различных базовых форм (типов данных).
- Полиморфизм - возможность объектов иметь различную реализацию.
- Полиморфизмом называется способность функции...
- Классика (от создателя С/С++): «один интерфейс - много реализаций».
- Параметрический полиморфизм подразумевает...
- Полиморфизм - положение теории типов...
- Абстракция невозможна без инкапсуляции и наследования, как невозможен полиморфизм без наследования...
Можно согласиться, что всё это относится к одному и тому же: но форма выражения мысли, сущность и содержание - не подобны. Но что-то общее всё же есть.
Сущность: разработчик - заказчик
Классическая разработка программ предполагает наличие программиста и задачи (клиент, заказчик). Программист исследует задачу, формализует её и делает код, который приводит к решению. Заказчик отрицает всё предложенное или только его часть, указывая на недоработки, и программист делает свою работу вновь.
Такой круговорот процесса решения задачи наводит на мысль, что здесь явно совмещены две совершенно разные сущности:
- компьютер не может сам решить задачу;
- нужна программа, чтобы компьютер мог «понять» и «решить» задачу.
Задача - сфера компетенции заказчика, программа - это алгоритм «адаптации» задачи к возможностям компьютера - сфера компетенции программиста. Роль последнего заключается в «адаптации» компьютера к требованиям задачи, а это лишнее!
Предлагает абстрагироваться . Есть объекты - это сфера заказчика; есть реализация объектов - это сфера программиста. Никакой «технологической» связи между заказчиком и разработчиком. Идея кардинальная, не реализованная по сей день, но что-то уже стабильно работает.
Окна, кнопки и другие объекты
История 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 можно у нас на .