Это от моего ответ от similiar вопроса. Вот пример полиморфизма в pseudo-C#/Java:
class Animal
{
abstract string MakeNoise ();
}
class Cat : Animal {
string MakeNoise () {
return "Meow";
}
}
class Dog : Animal {
string MakeNoise () {
return "Bark";
}
}
Main () {
Animal animal = Zoo.GetAnimal ();
Console.WriteLine (animal.MakeNoise ());
}
Основное () метод не знает тип животного и зависит от поведения конкретной реализации MakeNoise () метод.
Полиморфизм является Объектно-ориентированным решением проблемы передачи функции к другой функции. В C можно сделать
void h() { float x=3.0; printf("%f", x); }
void k() { int y=5; printf("%i", y); }
void g(void (*f)()) { f(); }
g(h); // output 3.0
g(k); // output 5
В вещах C, являются сложными, если функция зависит от дополнительных параметров. Если функции h и k зависят от различных типов параметров, Вы в беде, и необходимо использовать кастинг. Необходимо сохранить те параметры в структуре данных и передать указатель на ту структуру данных к g, который передает ее h или k. h, и k бросают указатель в указатель на надлежащую структуру и распаковывают данные. Очень грязный и очень небезопасный из-за возможных ошибок кастинга:
void h(void *a) { float* x=(float*)a; printf("%f",*x); }
void k(void *a) { int* y=(int*)a; printf("%i",*y); }
void g(void (*f)(void *a),void *a) { f(a); }
float x=3.0;
int y=5;
g(h,&x); // output x
g(k,&y); // output y
, Таким образом, они изобрели полиморфизм. h и k продвинуты на классы и фактические функции к методам, параметры являются членскими переменными соответствующего класса, h или k. Вместо того, чтобы раздать функцию, Вы передаете экземпляр класса, который содержит функцию, которую Вы хотите. Экземпляр содержит свои собственные параметры.
class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x
Способность объекта некоторого типа (например, автомобиль) для действия (например, тормоз) как один из другого типа (например, механизм), который обычно предлагает общую родословную (например, автомобиль подтип механизма), однажды в иерархии типа.
Это - просто способ заставить старый холод называть новый код. Вы пишете некоторое приложение, которое принимает некоторый интерфейс "Shape" с методами, которые другие должны реализовать (пример - getArea). Если кто-то придумывает новый удар свиста способ реализовать тот интерфейс, Ваш старый код может назвать тот новый код через getArea метод.
Это - способ рассматривать разные вещи, которые могут сделать что-то что-то подобное таким же образом, не заботясь, как они делают это.
Скажем, у Вас есть игра с набором различных типов управления Механизмов вокруг такого как Автомобиль, Грузовик, Скейтборд, Самолет, и т.д... Они все могут Остановиться, но каждый Механизм остановки по-другому. Некоторые Механизмы, возможно, должны переключить вниз скорости, и некоторые могут быть в состоянии приехать в холодную остановку. Polymophism позволяет Вам сделать это
foreach (Vehicle v in Game.Vehicles)
{
v.Stop();
}
способ, которым реализована остановка, задерживается к различным Механизмам, таким образом, Ваша программа не должна заботиться об этом.
Способность, которая объекты должны ответить на то же сообщение по-разному.
, Например, на языках, таких как smalltalk, Ruby, Objective C, просто необходимо отправить сообщение, и они ответят.
dao = XmlDao.createNewInstance() #obj 1
dao.save( data )
dao = RdbDao.createNewnewInstance() #obj 2
dao.save( data )
В этом примере два различных объекта, на которые отвечают по-разному те же сообщения: "createNewInstance () и сохраняют (obj)",
Они действуют по-разному к тому же сообщению. На вышеупомянутых языках классы даже не могли бы быть в той же иерархии классов, это достаточно, что они отвечают на сообщение.
На языках, таких как Java, C++, C# и т.д. для присвоения объекта ссылке на объект, они должны совместно использовать ту же иерархию типа или путем реализации интерфейса или будучи подклассом общего класса.
легкий.. и простой.
Полиморфизм безусловно, самая важная и соответствующая функция объектно-ориентированного программирования.
Путем я пытаюсь думать о нем, что-то, что выглядит одинаково, но может иметь различную функциональность в зависимости от экземпляра. Таким образом, у Вас может быть тип
interface IJobLoader
, но в зависимости от то, как он используется, может иметь различную функциональность, все еще выглядя одинаково. У Вас могут быть экземпляры для BatchJobLoader, NightlyJobLoader и т.д.
, Возможно, я - путь прочь.
Термин полиморфизм может также относиться к перегрузке функций. Например,
string MyFunc(ClassA anA);
string MyFunc(ClassB aB);
необъектно-ориентированный пример полиморфизма.
Полиморфизм является способностью рассматривать отличающийся вещи, как будто они были тот же вещь путем установления общих идентификационных данных между ними тогда использование его.
Полиморфизм - то, что Вы получаете, когда тот же метод относится к нескольким классам. Например, и Строка и Список могли бы иметь "Обратные" методы. Оба метода имеют то же имя ("Реверс"). Оба метода делают что-то очень похожее (инвертируйте все символы или инвертируйте порядок элементов в списке). Но реализация каждого "Обратного" метода отличается и характерна для своего класса. (Другими словами, Строка инвертирует себя как строка, и Список инвертирует себя как список.)
Для использования метафоры Вы могли сказать, "Делают Ужин" французскому шеф-повару или японскому шеф-повару. Каждый работал бы, "делают ужин" их собственным характерным способом.
практический результат состоит в том, что Вы могли создать "Реверсивный Механизм", который принимает объект и называет "Реверс" на нем. Пока объект имеет Обратный метод, Ваш Реверсивный Механизм будет работать.
Для расширения аналогии шеф-повара Вы могли создать "Waiterbot", который говорит шеф-поварам "Делать Ужин". Waiterbot не должен знать, какой ужин будет сделанным. Это не должно даже удостоверяться, что говорит с шеф-поваром. Все, что имеет значение, - то, что "шеф-повар" (или пожарный, или торговый автомат или фармацевт корма для животных) знает, что сделать, когда ему говорят "Сделать Ужин".
, Что это покупает Вас, поскольку программист является меньшим количеством строк кода и или безопасность типов или позднее связывание. Например, вот пример с безопасностью типов и ранним связыванием (в подобном языку C, которое я составляю, когда я иду):
class BankAccount {
void SubtractMonthlyFee
}
class CheckingAccount : BankAccount {}
class SavingsAccount : BankAccount {}
AssessFee(BankAccount acct) {
// This will work for any class derived from
// BankAccount; even classes that don't exist yet
acct.SubtractMonthlyFee
}
main() {
CheckingAccount chkAcct;
SavingsAccount saveAcct;
// both lines will compile, because both accounts
// derive from "BankAccount". If you try to pass in
// an object that doesn't, it won't compile, EVEN
// if the object has a "SubtractMonthlyFee" method.
AssessFee(chkAcct);
AssessFee(saveAcct);
}
Вот пример без безопасности типов, но с поздним связыванием:
class DatabaseConnection {
void ReleaseResources
}
class FileHandle {
void ReleaseResources
}
FreeMemory(Object obj) {
// This will work for any class that has a
// "ReleaseResources" method (assuming all
// classes are ultimately derived from Object.
obj.ReleaseResources
}
main() {
DatabaseConnection dbConn;
FileHandle fh;
// You can pass in anything at all and it will
// compile just fine. But if you pass in an
// object that doesn't have a "ReleaseResources"
// method you'll get a run-time error.
FreeMemory(dbConn);
FreeMemory(fh);
FreeMemory(acct); //FAIL! (but not until run-time)
}
Для превосходного примера, посмотрите на.NET ToString () метод. Все классы имеют его, потому что все классы получены из Класса объекта. Но каждый класс может реализовать ToString () способом, который имеет смысл для себя.
РЕДАКТИРОВАНИЕ: Простой! = короткий, по моему скромному мнению
Полиморфизм является хранением значений больше чем одного типа в месте единственного типа.
Примечание, что большинство других ответов на этот вопрос, во время моей записи, на самом деле описывает динамическую отправку, не полиморфизм.
Динамическая отправка требует полиморфизма, но реверс не верен. Можно было вообразить язык очень похожим на Java или C#, но чья Система. Объект не имел никаких участников; преобразование типа было бы необходимо прежде, чем сделать что-либо со значением. На этом отвлеченном языке был бы полиморфизм, но не обязательно виртуальные методы или любые другие динамические механизмы отправки.
Динамическая отправка является связанным, но отличным понятием, достаточно хорошо описанным в большинстве других ответов. Однако способом, которым это обычно работает на объектно-ориентированных языках (выбирающий функцию на основе первого ('это' или 'Сам') тип аргумента) не является единственный способ, которым это может работать. Несколько диспетчеризируют , также возможно, где выбор применяется через типы всех аргументов.
Точно так же разрешение перегрузки и который несколько диспетчеризируют, является точными аналогами друг друга; разрешение перегрузки, несколько диспетчеризируют относившийся статические типы, в то время как несколько диспетчеризируют, разрешение перегрузки, относился к типам выполнения, сохраненным в полиморфных местоположениях.
Полиморфизм делит мир на поля на основе общей собственности и рассматривает объекты в данном поле как взаимозаменяемые, когда Вы только хотите использовать эту общую собственность.
Самый простой способ описать его: глагол, который может относиться больше чем к одному виду объекта.
Все остальное, как Hillel заявил, является просто комментарием.
Это - лучшая статья на самом деле
, Полиморфизм позволяет Объектам "Посмотреть" то же, но вести себя по-разному. Обычный пример должен посещать базовый урок животных с Тем, чтобы говорить () Метод, подкласс собаки испустил бы Кору, тогда как подкласс Свиньи испустит хрюканье.
5 вторых коротких ответов большая часть использования людей так другие разработчики могут добраться, их голова вокруг Полиморфизма перегружает и переопределяет
Если это идет как утка и шарлатаны как утка, то можно рассматривать его как утка где угодно, Вам нужна утка.
Яблоки и апельсины являются оба фруктами. Фрукты можно съесть. Следовательно, и яблоки и апельсины можно съесть.
строка над заголовком? Вы едите их по-другому! Вы очищаете апельсины, но не яблоки.
, Таким образом, реализация отличается, но конечным результатом является то же, Вы едите фрукты .
Агент по сравнению с символом (или роль)
Самое простое описание полиморфизма - то, что это - способ уменьшить если/операторы переключения .
Это также обладает преимуществом разрешения Вам расширить Ваш если/операторы переключения (или других людей), не изменяя существующие классы.
, Например, рассматривают Stream
класс в.NET. Без полиморфизма это был бы единственный крупный класс, где каждый метод реализует оператор переключения что-то как:
public class Stream
{
public int Read(byte[] buffer, int offset, int count)
{
if (this.mode == "file")
{
// behave like a file stream
}
else if (this.mode == "network")
{
// behave like a network stream
}
else // etc.
}
}
Вместо этого мы позволяем времени выполнения делать переключение для нас более эффективным способом, путем автоматического выбора реализации на основе конкретного типа (FileStream
, NetworkStream
), например,
public class FileStream : Stream
{
public override int Read(byte[] buffer, int offset, int count)
{
// behave like a file stream
}
}
public class NetworkStream : Stream
{
public override int Read(byte[] buffer, int offset, int count)
{
// behave like a network stream
}
}
Каждая Банка с простой поп-крышкой открывает тот же путь.
Как человек, Вы знаете, что можно Открыть () любой такой, может Вы находить.
, Когда открыто, не все банки ведут себя тот же путь.
Некоторые содержат гайки, некоторые содержат поддельных змей, настолько всплывающих.
результат зависит от того, какой может, если банка была "CanOfNuts" или "CanOfSnakes", но это не имеет никакого влияния, КАК Вы открываете его. Вы просто знаете, что можно открыться, любой Может, и получать своего рода результат, который решен на основе того, какой Может, случалось так, что Вы открылись.
pUnlabledCan-> Открытый ();//мог бы дать гайки, мог бы дать змей. Мы не знаем, пока мы не звоним, это
Открытый () имеет универсальный тип возврата "Содержания" (или мы не могли бы решить тип возврата), так, чтобы открытый всегда имел ту же функциональную подпись.
Вы, человек, являетесь пользователем/вызывающей стороной.
Открытый () виртуальная / полиморфная функция.
"Банка" является абстрактным базовым классом.
CanOfNuts и CanOfSnakes являются полиморфными детьми класса "Банки".
Каждая Банка может быть открыта, но что конкретно она делает и какой определенный tye содержание , который она возвращает, определяется тем, каким может он быть.
Все, что Вы знаете, когда Вы видите, pUnlabledCan - то, что можно Открыть () его, и это возвратит содержание. Любые другие поведения (такие как появляющиеся змеи в Вашей поверхности) решены определенной Банкой.
Два объекта отвечают на то же сообщение с различными поведениями; отправитель не должен заботиться.
Полиморфизм рассматривает вещи абстрактно путем доверия знанию общего "родителя" (думайте иерархии как Животное как родитель Собак и Кошек).
, Например, все Животные могут вдохнуть кислород, и в то время как они могут каждый сделать это по-другому, Вы могли разработать средство, которое предоставляет кислород Животным для дыхания, поддерживая и Собак и Кошек.
Как немного дополнительный, можно сделать это даже при том, что Животное является "абстрактным" идентификатором (нет никакой реальной вещи "Животных", просто типы Животных).