Инкапсуляция, Наследование, Полиморфизм (Основы PHP - Урок из курса). Что такое полиморфизм в Java Полиморфизм понятие и примеры на с

Железо

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

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

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

В различных полиморфных модификациях существуют углерод, кремний, фосфор, железо и другие элементы. Физические свойства различных модификаций одного и того же вещества могут значительно отличаться. Например модификации углерода, кристаллизующиеся в виде алмаза (кубическая сингония) или в виде графита (гексагональная сингония), резко отличаются друг от друга по физическим свойствам, несмотря на идентичность состава. Если полиморфное превращение сопровождается незначительными изменениями структуры, физические свойства вещества изменяются несущественно. Полиморфных модификаций у каждого конкретного вещества должна быть две, три и более. Различные модификации принято обозначать греческими буквами α, β, γ и т.д., причем первые буквы, как правило, относятся к модификациям, устойчивым при более высоких температурах.

При превращении высокотемпературной модификации в более низкотемпературную обычно первоначальная внешняя форма кристаллов сохраняется, в то время как внутренняя структура вещества претерпевает изменения. Такое сохранение внешней формы, не отвечающей вновь образованной структуре кристаллической решетки, получило название параморфозы. В природе известны параморфозы β -кварца (тригональная симметрия) по α -кварца (гексагональная симметрия), кальцита СаСО 3 (тригональная симметрия) по арагониту (ромбическая симметрия) и др.

Независимо от характера структурных изменений, происходящих при полиморфных превращениях, различают две их разновидности˸ энантиотропные (обратимые) и монотропные (необратимые) превращения.

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

α ↔ β↔жидкость

т.е. перход α → β энантиотропен. Примерами энантиотропных полиморфных превращений являются превращения между полиморфными формами SiO 2 ˸

Полиморфизм - понятие и виды. Классификация и особенности категории "Полиморфизм" 2015, 2017-2018.

  • - Полиморфизм индивидов

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


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

  • - Внутривидовая дифференцировка человечества. Расы как выражение генетического полиморфизма человечества. Видовое единство человечества.

    ВНУТРИВИДОВАЯ ДИФФЕРЕНЦИАЦИЯ ЧЕЛОВЕЧЕСТВА: С момента возникновения Н. sapiens социальное в человеке стало его сущностью и биологическая эволюция видоизменялась, проявляясь в возникновении широкого генетического полиморфизма. Генетическое разнообразие на уровне... .


  • s_a_p 20 августа 2008 в 19:09

    Полиморфизм для начинающих

    • PHP

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

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

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

    Самые простые варианты, которые приходят в голову — написать три отдельных класса и работать с ними. Или написать один класс, в которым будут все свойства, присущие всем трем типам публикаций, а задействоваться будут только нужные. Но ведь для разных типов аналогичные по логике методы должны работать по-разному. Делать несколько однотипных методов для разных типов (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 — господа, это просто пример, причем пример по полиморфизму, в котором я не считаю нужным уделять значения этим вещам. Это тема для совсем других статей.

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

    Собственно, представим себе рядом стакан, кружку, чайник, кофемашину, велосипед и скейт. Что между ними всеми общего? Ну как минимум то, что они есть. То есть это - объекты, которые были созданы. Но как они были созданы? Скорее всего на заводе производителя по чертежам. Ок, чертежём назовём конструктор. Ну а класс? А что это такое? А его нет в нашей вселенной - эта сущность есть абстракция, что живёт лишь в наших мыслях. В реальном мире её нет и никогда не будет, такова уж физика - ей по барабану, что птицы и млекопитающие имеют дальних родственников - она лишь обеспечивает возможность естесственного отбора. А уж родственников друг другу находим мы, люди.

    С объектами и классами разобрались, а что же там с нашими стаканами и велосипедами. Мы уже поняли, что всё это объект, то есть грубо можно все объекты наследовать от какого-нибудь суперпредка, суперкласса, что и реализовано в некоторых языках. Но что другого общего между скейтом и стаканом, например? Конечно, можно углубляться и считать, что они все из молекул, и они все из твёрдых веществ. Однако это всё бред и СПГС , так что ответ прост - да ничего. То есть это совершенно разные объекты с совершенно разным функционалом. Более того - естесственно компьютерные модели и иерархии будут сильно отличатся от физик и химий. И это нормально, вопрос об адекватностях моделей ставиться лишь когда модель неадекватна, а до тех пор пилить можно что угодно, лишь бы работало.

    Вот. У нас есть супер-предок Object, от которого дефолтно наследуются все объекты. Допустим, то что объекты состоят из атомов и есть то, что наследуют все объекты. Но все дополнения и правки - полиморфизм. Так, из атомов мы слепили колёса и приделали на доску - ок, это скейт. На него можно встать и катиться, а сильно извернувшись и полетать в трёх метрах над землёй, прямо таки излучая своё яркое эго. В то время как стакан - это мы слепили из атомов плотную ёмкость, из которой вода не выливается под действием силы тяжести. И прямое применение стакана - налив воды опрокинуть его над ртом, чтобы вода вытекла прямо в желудок. Так делают настоящие пацаны, не заботясь об икоте или страхе утонуть, так что вот - полиморфизм.

    Однако что с остальным? У нас ещё абстракция, инкапсуляция и наследование. Ок, начнём с наследования, так оно наиболее близко. Вот что у нас общего между стаканом и кружкой? Ну в оба можно налить воду, но у кружки есть ручка чтобы держаться. То есть можно придумать некий общий класс - ёмкость. Однако что это за класс? Можно например за этот класс взять стакан, тогда все ёмкости по дефолту стаканы, а всё остальное - видоизменённые стаканы. Но кому-то больше нравяться кувшины, например некоторые чики насят их на голове, считая что это удобно. Ну и пусть носят, но как-то же решить надо, что главнее и идеальнее. Так вот - недостяжимый идеал и есть главный - это называется абстрактный класс. То есть ёмкость, что невозможно создать, для которого нет полного чертежа. А все чертежи, что дополнили до полного - есть наследованные классы от класса ёмкость.

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

    Но мы подошли к последнему пункту - инкапсуляция. Она неразрывна с абстракцией, и по сути благодаря ей она и работает. Инкапсуляция - это своеборазный клей (или синяя изолента), которым склеивают разные чертежи в один. То есть совмещение деталей для создания своей - это и есть инкапсуляция. Причём при совмещении мы можем не описывать детали этого совмещения (то есть члены класса могут быть приватными), таким образом помогая абстрагироваться тем, кто этот чертёж использует. Вот посмотрим на чайник - что это такое? Это стакан (или кружка) к которому снизу (а может внутри по середине?) приклеен нагревательный элемент. Пустив по нему ток, согласно инкапсулированному в нагревательный элемент закону Ома, будет выделяться тепло и нагреваться вода. А кофемашина? Это куда более сложное устройство, с множеством насосов, ёмкостей, шлюзов, измельчителей и чайников. И всё склееное клеем. А может синей изолентой. Это снова инкапсуляция.

    Таким образом, абстракция невозможна без инкапсуляции и наследовании, как невозможен полиморфизм без, собственно, наследования. Ну а полиморфизм невозможен ещё и без инкапсуляции, которая банально бесполезна без наследования и полиморфизма. Вот такие тут треугольники с пирогами. Жаль только про пирог наврали. И про день рожденье.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Пример

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

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

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

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

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

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

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

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

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

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

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

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

    Надеемся, наша статья была Вам полезна. Записаться на наши курсы по 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