Полиморфизм (руководство по программированию на c#)polymorphism (c# programming guide)

Еще примеры полиморфизма

Например, у нас есть класс Animal, у которого есть метод sound(). Поскольку это универсальный класс, поэтому мы не можем дать ему такую реализацию, как: Мяу, Гав, Хрю-хрю и т. д. Мы должны были дать универсальное сообщение.


public class Animal{
   ...
   public void sound(){
      System.out.println("Animal is making a sound");   
   }
}

Теперь допустим, что мы два подкласса класса Animal: Horse и Cat, который расширяет(см. наследование) класс Animal. Мы можем предоставить реализацию тому же методу, например так:

public class Horse extends Animal{
...
    @Override
    public void sound(){
        System.out.println("Neigh");
    }
}

а также

public class Cat extends Animal{
...
    @Override
    public void sound(){
        System.out.println("Meow");
    }
}

Не имеет никакого смысла просто вызывать универсальный метод sound(), поскольку у каждого животного свой звук. Таким образом, мы можем сказать, что действие, которое выполняет этот метод, основано на типе объекта.

Другими словами, полиморфизм позволяет вам определять один интерфейс и иметь несколько реализаций. Как мы видели в приведенном выше примере, мы определили метод sound() и имеем несколько его реализаций в разных подклассах-2. Какой метод sound() будет вызван, определяется во время выполнения, поэтому приведенный выше пример является примером полиморфизма во время выполнения.

Абстракция

Преимущества:

  • Применяя абстракцию, мы можем отделить то, что может быть сгруппировано по какому-либо типу.
  • Часто изменяемые свойства и методы могут быть сгруппированы в отдельный тип, таким образом основной тип не будет подвергаться изменениям. Это усиливает принцип ООП: «Код должен быть открытым для Расширения, но закрытым для Изменений».
  • Абстракция упрощает представление доменных моделей.

Отличие между абстракцией и инкапсуляциейЧто такое абстрактный класс и абстрактный метод?Когда необходимо использовать абстрактный класс?Что такое интерфейс?

  1. Множественное наследование.
  2. Слабая связанность. Происходит абстракция операции, такая как разделение на уровни, а конкретной реализацией может быть что угодно: JDBC, JPA, JTA и т.д.
  3. Программа-интерфейс не реализуется.
  4. Полиморфизм с динамическим связыванием: раскрывается програмный интерфейс объекта без раскрытия его фактической реализации.
  5. Абстрактные уровни, разделение функциональностей.

Разница между интерфейсом и абстрактным классом.

  • Интерфейс — это договорные отношения с классами, которые этот интерфейс реализуют, о том, что реализация происходит путём, обозначенным интерфейсом. Это пустая оболочка с объявленными методами.
  • Абстрактный класс определяет некоторое общее поведение и просит свои подклассы определить нетипичное или конкретное поведение для своего класса.
  • Методы и члены абстрактного класса могут быть обозначены любым модификатором доступа, в свою очередь все методы интерфейса обязаны быть открытыми (public).
  • Когда происходит наследование абстрактного класса, класс-наследник должен определить абстрактные методы, в то время как интерфейс может наследовать другой интерфейс и при этом не обязательно определять его методы.
  • Класс-наследник может расширять только один абстрактный класс, а интерфейс может расширять или класс может реализовывать множество других интерфейсов.
  • Класс-наследник может определять абстрактные методы с тем же или менее ограниченным модификатором доступа, при этом класс, реализующий интерфейс, должен определять методы с тем же уровнем видимости.
  • Интерфейс не содержит конструкторы, в том время, как они есть в абстрактном классе.
  • Переменные, объявленные в Java-интерфейсе по умолчанию являются final. Абстрактный класс может содержать переменные, которые не являются final.
  • Все участники Java-интерфейса по умолчанию являются . Участники абстрактного класса могут позволить себе быть , и др.

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

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

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

Пример

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


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

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

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

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

Полиморфизм в патологии

Полиморфизм в патологии (греч. polymorphos многообразный) — многообразие структурных проявлений патологического процесса в органах, тканях и клетках.

В общей патологии Полиморфизм наблюдается при компенсаторно-приспособительных процессах, возникающих на различных этапах развития болезни. Компенсаторные процессы (см.) весьма разнообразны и обычно развиваются в отдельных системах, органах и тканях организма. Напр., при регенерации костной ткани в зоне перелома костная мозоль может быть представлена как волокнистой соединительной тканью, так и костно-хрящевыми структурами. Кроме того, П. отмечается при метаплазии тканей (см. Метаплазия) и в процессе организации (см.). В частной патологии П. проявляется в изменчивости морфологической картины ряда заболеваний (туберкулеза, крупозной пневмонии и др.) под влиянием естественных и индуцированных факторов (см. Патоморфоз). В частности, течение крупозной пневмонии может начинаться со стадии красного опеченения или серого опеченения, а в нек-рых случаях она носит мигрирующий характер. Чаще понятие «полиморфизм» используют для морфол, характеристики опухолевого роста.

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

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

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

Библиография

Полиморфизм в генетике

Алтухов Ю. П. и Рычков Ю. Г. Генетический мономорфизм видов и его возможное биологическое значение, Журн. общ. биол., т. 33, № 3, с. 281, 1972; Бочков Н. П. Генетика человека, М., 1978; Майр Э. Популяции, виды и эволюция, пер. с англ., М., 1974; Харрис Г. Основы биохимической генетики человека, пер. с англ., М., 1973; Эрлих П. и Холм Р. Процесс эволюции, пер. с англ., М., 1966; Сavаlli-Sfоrza L. L. a. Bodmer W. F. The genetics of human populations, San Francisco, 1971; Ford E. B. Polymorphism and taxonomy, в кн.: The new systematics, ed. by J. Huxley, p. 493, L., 1941.

Полиморфизм в патологии

Давыдовский И. В. Общая патология человека, с. 506, М., 1969; Струков А. И. и Серов В. В. Патологическая анатомия с. 159, М., 1979.

Полиморфизм в химии

Некрасов Б. В. Учебник общей химии, с. 382, М., 1981; Неницеску К. Общая химия, пер. с румын., с. 130, М., 1968.

Объяснение полиморфизма

У нас есть один родительский класс, «Счет» с функцией пополнения и снятия. Учетная запись имеет 2 дочерних класса.

Операции ввода и вывода одинаковы для Сберегательного и Чекового счетов. Таким образом, унаследованные методы из класса Account будут работать.

Изменение требований к программному обеспечению

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

Итак, метод вывода для привилегированных нужд должен быть реализован заново. Но вы не меняете проверенный кусок кода в Сберегательном и Чековом счете. Это преимущество ООП.

Шаг 1) Такой, что при вызове «изъятого» метода для сохранения учетной записи выполняется метод из класса родительской учетной записи.


Шаг 2) Но когда вызывается метод «Снять» для привилегированной учетной записи (средство овердрафта), выполняется метод вывода, определенный в привилегированном классе. Это полиморфизм.

Использование методов

Чтобы вызвать метод объекта, воспользуйтесь оператором ->, с которым вы уже успели подружиться.

$object->methodName()

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

Мы добавили некоторые методы в наш класс, теперь давайте попробуем их применить для чего-то:

<?php
 
class Member
{
  public $username = "";
  private $loggedIn = false;
 
  public function login() {
    $this->loggedIn = true;
  }
 
  public function logout() {
    $this->loggedIn = false;
  }
 
  public function isLoggedIn() {
    return $this->loggedIn;
  }
}
 
$member = new Member();
$member->username = "Fred";
echo $member->username . " is " . ( $member->isLoggedIn() ? "logged in" : "logged out" ) . "<br>";
$member->login();
echo $member->username . " is " . ( $member->isLoggedIn() ? "logged in" : "logged out" ) . "<br>";
$member->logout();
echo $member->username . " is " . ( $member->isLoggedIn() ? "logged in" : "logged out" ) . "<br>";
 
?>

Данный скрипт отобразит следующее:

Fred is logged out
Fred is logged in
Fred is logged out

Вот, как он работает:

  1. После описания класса Member мы создали его объект и сохранили в переменной $member. Также мы дали переменной класса $username данного объекта значение “Fred”.
  2. Затем мы вызвали метод $member->isLoggedIn() для того, чтобы определить, залогинился ли пользователь или нет. Данный метод просто-напросто возвращает значение переменной класса $loggedIn. Так как значение по умолчанию этой переменной класса — false, значит результатом вызова $member->isLoggedIn() будет ложь, поэтому отобразится сообщение «Fred is logged out».
  3. Затем вызовем метод login(). Он установит в true значение переменной класса $loggedIn.
  4. Теперь, при вызове метода $member->isLoggedIn() вернется истина, и выведется сообщение «Fred is logged in».
  5. Вызовем метод logout(), который устанавливает в false значение свойства $loggedIn.
  6. В третий раз вызовем метод $member->isLoggedIn(). Сейчас он вернет false, потому что значение свойства $loggedIn опять установлено в ложь. Так, снова выведется сообщение «Fred is logged out».

На заметку: на случай, если вы в первые увидели такое: ?:, — это тернарный оператор. Это упрощенная версия блоков if … else. Узнать о такого рода операторах можно здесь.

Шаг 1: Определите задачу

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

PHP

class poly_base_Article { public $title; public $author; public $date; public $category; public function __construct($title, $author, $date, $category = 0) { $this->title = $title; $this->author = $author; $this->date = $date; $this->category = $category; } }

1 2 3 4 5 6 7 8 9 10 11 12 13

classpoly_base_Article{

public$title;

public$author;

public$date;

public$category;


publicfunction__construct($title,$author,$date,$category=){

$this->title=$title;

$this->author=$author;

$this->date=$date;

$this->category=$category;

}

}

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

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

PHP

class poly_base_Article { //… public function write($type) { $ret = »; switch($type) { case ‘XML’: $ret = ‘<article>’; $ret .= ‘<title>’ . $obj->title . ‘</title>’; $ret .= ‘<author>’ . $obj->author . ‘</author>’; $ret .= ‘<date>’ . $obj->date . ‘</date>’; $ret .= ‘<category>’ . $obj->category . ‘</category>’; $ret .= ‘</article>’; break; case ‘JSON’: $array = array(‘article’ => $obj); $ret = json_encode($array); break; } return $ret; } }

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

classpoly_base_Article{

//…  

publicfunctionwrite($type){

$ret=»;

switch($type){

case’XML’

$ret='<article>’;

$ret.='<title>’.$obj->title.'</title>’;

$ret.='<author>’.$obj->author.'</author>’;

$ret.='<date>’.$obj->date.'</date>’;

$ret.='<category>’.$obj->category.'</category>’;

$ret.='</article>’;

break;

case’JSON’

$array=array(‘article’=>$obj);

$ret=json_encode($array);

break;

}

return$ret;

}

}

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

Это довольно неуклюжее решение, но оно работает — пока. Спросите себя, однако, что произойдет в будущем, когда нам нужно будет еще добавить форматы? Можно продолжить изменять класс, добавляя все больше условий, но так вы только его усложняете.

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

Вот тут и вступает в дело полиморфизм

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

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


С этим читают