Что такое полиморфизм, для чего он нужен и как он используется?

Вы не можете изменить подпись своего класса, переопределив его. Однако вы можете возвращать производный тип:

Public Overrides Property OrderItem() as OrderItemBase
    Get
        Return New WebOrderItem()
    End Get
End Property

Public Sub Whatever()
    Dim item As WebOrderItem = DirectCast(OrderItem, WebOrderItem)
End Sub

В качестве альтернативы, если вы хотите строго придерживаться типов более строго, используйте generics с ограничениями общего типа, как показано ниже:

Public MustInherit Class OrderBase(Of T As OrderItemBase)
    Public MustOverride ReadOnly Property OrderItem() As T
End Class

Public Class OrderItemBase
End Class

Public Class WebOrder(Of T As WebOrderItem)
    Inherits OrderBase(Of T)

    Public Overrides ReadOnly Property OrderItem() As T
        Get
            Return New WebOrderItem()
        End Get
    End Property
End Class

Public Class WebOrderItem
    Inherits OrderItemBase
End Class

Или сделайте это, если вы не хотите, чтобы WebOrder также был родовым классом:

Public Class WebOrder
    Inherits OrderBase(Of WebOrderItem)

    Public Overrides ReadOnly Property OrderItem() As WebOrderItem
        Get
            Return New WebOrderItem()
        End Get
    End Property
End Class
521
задан UnkwnTech 22 March 2019 в 15:22
поделиться

12 ответов

Если вы подумаете о греческих корнях этого термина, это должно стать очевидным.

  • Многоугольник = много: многоугольник = многогранный, полистирол = много стиролов (a) , полиглот = множество языков и т. Д.
  • Морф = изменение или форма: морфология = изучение биологической формы, Морфеус = греческий бог снов, способный принимать любую форму.

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

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

Но, таким же образом, такой класс, как BigDecimal или Rational или Imaginary , также может предоставлять эти операции, даже если они работают с разными типами данных.

Классическим примером является Класс Shape и все классы, которые могут наследовать от него (квадрат, круг, додекаэдр, неправильный многоугольник, знак знака и т. Д.).

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

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

shape.Draw()

, чтобы получить правильное поведение для любой формы.

Это контрастирует со старым способом работы. в котором код был отделен от данных, и у вас были бы такие функции, как drawSquare () и drawCircle () .

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


(a) Изначально я написал это как шутку, но оказалось, что это правильно и, следовательно, не так уж смешно.

525
ответ дан 22 November 2019 в 22:23
поделиться

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

Полиморфизм является способностью к:

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

  • Определяют несколько методов, имеющих имя сохранения, но имеющих differents параметры: это статический полиморфизм .

первое, если историческое определение и самое важное.

, Для чего используется полиморфизм?

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

Строгий контроль типов и слабый контроль типов

Образец

Вот является некоторыми Формами как Точка, Строка, Прямоугольник и Круг, начинающий операцию, Тянут () берущий или ничто или любого параметр для установки тайм-аута для стирания его.

public class Shape
{
 public virtual void Draw()
 {
   DoNothing();
 }
 public virtual void Draw(int timeout)
 {
   DoNothing();
 }
}

public class Point : Shape
{
 int X, Y;
 public override void Draw()
 {
   DrawThePoint();
 }
}

public class Line : Point
{
 int Xend, Yend;
 public override Draw()
 {
   DrawTheLine();
 }
}

public class Rectangle : Line
{
 public override Draw()
 {
   DrawTheRectangle();
 }
}

var shapes = new List<Shape> { new Point(0,0), new Line(0,0,10,10), new rectangle(50,50,100,100) };

foreach ( var shape in shapes )
  shape.Draw();

Здесь класс Формы и Форма. Потяните (), методы должны быть отмечены как краткий обзор.

Они не для сделать, понимают.

Explaination

Без полиморфизма, с помощью абстрактного виртуального переопределения, при парсинге форм, это - только Spahe. Нарисуйте () метод, который называют, поскольку CLR не знает что метод звонить. Таким образом, это называет метод типа, на который мы действуем, и здесь тип является Формой из-за объявления списка. Так код не делают ничего вообще.

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

[еще 1113] чтения

C# - Полиморфизм (Уровень 1)

Полиморфизм в Java (Уровень 2)

Полиморфизм (Руководство по программированию C#)

Таблица виртуальных методов

0
ответ дан Olivier Rogier 4 October 2019 в 09:25
поделиться

В объектно-ориентированных языках полиморфизм позволяет обрабатывать и обрабатывать разные типы данных через один и тот же интерфейс. Например, рассмотрим наследование в C ++: Класс B является производным от класса A. Указатель типа A * (указатель на класс A) может использоваться для обработки как объекта класса A, так и объекта класса B.

0
ответ дан 22 November 2019 в 22:23
поделиться

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

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

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

  • Шаблоны: особенность некоторых объектно-ориентированных языков, посредством которой функция, класс и т. д. могут параметризоваться типом. Например, вы можете определить общий шаблонный класс «список», а затем создать его экземпляр как «список целых чисел», «список строк», может быть, даже «список списков строк» ​​или тому подобное. Обычно вы пишете код один раз для структуры данных произвольного типа элемента, а компилятор генерирует его версии для различных типов элементов.

5
ответ дан 22 November 2019 в 22:23
поделиться

Обычно это относится к способности объекта типа A вести себя как объект типа B. В объектно-ориентированном программировании это обычно достигается путем наследования. Некоторые ссылки в Википедии, чтобы узнать больше:

РЕДАКТИРОВАТЬ: исправлены неработающие ссылки.

12
ответ дан 22 November 2019 в 22:23
поделиться

Термин полиморфизм происходит от:

поли = многие

морфизм = способность изменяться

В программировании полиморфизм - это «метод», который позволяет вам «смотреть» на объект как более одного типа вещей. Например:

Объект ученика также является объектом человека. Если вы «посмотрите» (то есть бросите) на студента, вы, вероятно, сможете попросить студенческий билет. Вы не всегда можете так поступать с человеком, верно? (человек не обязательно является студентом, поэтому может не иметь студенческого билета). Однако у человека наверняка есть имя. Студент тоже.

В итоге, «взгляд» на один и тот же объект под разными «углами» может дать вам разные «перспективы» (т.е. разные свойства или методы).

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

Почему мы используем полиморфизм? Для начала ... абстракция. На данный момент должно быть достаточно информации :)

4
ответ дан 22 November 2019 в 22:23
поделиться

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

//  Class definitions

class Fraction
{
    public $numerator;
    public $denominator;

    public function __construct($n, $d)
    {
        //  In real life, you'd do some type checking, making sure $d != 0, etc.
        $this->numerator = $n;
        $this->denominator = $d;
    }

    public function display()
    {
        echo $this->numerator . '/' . $this->denominator;
    }
}

class ComplexNumber
{
    public $real;
    public $imaginary;

    public function __construct($a, $b)
    {
        $this->real = $a;
        $this->imaginary = $b;
    }

    public function display()
    {
        echo $this->real . '+' . $this->imaginary . 'i';
    }
}


//  Main program

$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);

echo 'This is a fraction: '
$fraction->display();
echo "\n";

echo 'This is a complex number: '
$complex->display();
echo "\n";

Выходы:

This is a fraction: 1/2
This is a complex number: 1 + 2i

Некоторые другие ответы, похоже, подразумевают, что полиморфизм используется только в сочетании с наследованием; например, возможно, Fraction и ComplexNumber реализуют абстрактный класс с именем Number , который имеет метод display () , which Fraction и ComplexNumber затем обязаны реализовать. Но вам не требуется наследование, чтобы воспользоваться преимуществами полиморфизма.

По крайней мере, в языках с динамической типизацией, таких как PHP (я не знаю о C ++ или Java), полиморфизм позволяет разработчику вызывать метод, не обязательно заранее зная тип объекта и не зная, что будет вызвана правильная реализация метода. Например, предположим, что пользователь выбирает тип Number created:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

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

t необходимо наследование, чтобы воспользоваться преимуществами полиморфизма.

По крайней мере, в языках с динамической типизацией, таких как PHP (я не знаю о C ++ или Java), полиморфизм позволяет разработчику вызывать метод, не обязательно зная тип объекта заранее и уверенность в том, что будет вызвана правильная реализация метода. Например, предположим, что пользователь выбирает тип Number created:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

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

t необходимо наследование, чтобы воспользоваться преимуществами полиморфизма.

По крайней мере, в языках с динамической типизацией, таких как PHP (я не знаю о C ++ или Java), полиморфизм позволяет разработчику вызывать метод, не обязательно зная тип объекта заранее и уверенность в том, что будет вызвана правильная реализация метода. Например, предположим, что пользователь выбирает тип Number created:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

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

и веря, что будет вызвана правильная реализация метода. Например, предположим, что пользователь выбирает тип Number created:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

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

и веря, что будет вызвана правильная реализация метода. Например, предположим, что пользователь выбирает тип Number created:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

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

2
ответ дан 22 November 2019 в 22:23
поделиться

Полиморфизм - это способность рассматривать класс объекта как если это родительский класс.

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

Dog* dog = new Dog;
Animal* animal = dog;
24
ответ дан 22 November 2019 в 22:23
поделиться

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

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

Если вы слушаете музыкальное произведение, у вас есть ссылка на сценарий, например, «Фуга и токата» Баха, и каждый музыкант, который его исполняет, полиморфно делает это по-своему.

Это всего лишь пример того, как это делать. возможный дизайн (на Java):

public interface Musician {
  public void play(Work work);
}

public interface Work {
  public String getScript();
}

public class FugaAndToccata implements Work {
  public String getScript() {
    return Bach.getFugaAndToccataScript();
  }
}

public class AnnHalloway implements Musician {
  public void play(Work work) {
    // plays in her own style, strict, disciplined
    String script = work.getScript()
  }
}

public class VictorBorga implements Musician {
  public void play(Work work) {
    // goofing while playing with superb style
    String script = work.getScript()
  }
}

public class Listener {
  public void main(String[] args) {
    Musician musician;
    if (args!=null && args.length > 0 && args[0].equals("C")) {
      musician = new AnnHalloway();
    } else {
      musician = new TerryGilliam();
    }
    musician.play(new FugaAndToccata());
}
3
ответ дан 22 November 2019 в 22:23
поделиться

Полиморфизм в терминах кодирования - это когда ваш объект может существовать как несколько типов посредством наследования и т. д. Если вы создаете класс с именем «Shape», который определяет количество сторон вашего объекта, тогда вы можете создать новый класс, который наследует его, например «Square». Когда вы впоследствии создадите экземпляр «Квадрата», вы можете затем отбрасывать его назад и вперед от «Формы» к «Квадрату» по мере необходимости.

0
ответ дан 22 November 2019 в 22:23
поделиться

Полиморфизм заключается в следующем:

class Cup {
   int capacity
}

class TeaCup : Cup {
   string flavour
}

class CoffeeCup : Cup {
   string brand
}

Cup c = new CoffeeCup();

public int measure(Cup c) {
    return c.capacity
}

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

9
ответ дан 22 November 2019 в 22:23
поделиться

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

Вот пример на языке C#. Создайте четыре класса в консольном приложении:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

Теперь создайте следующее в Main() модуля для консольного приложения:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

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

Затем мы добавляем в список Велосипед, Автомобиль и Грузовик.

Далее мы можем просмотреть каждый автомобиль в списке и обработать их все одинаково, однако когда мы обращаемся к свойству 'Wheels' каждого автомобиля, класс Vehicle делегирует выполнение этого кода соответствующему подклассу.

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

Надеюсь, это вам поможет.

237
ответ дан 22 November 2019 в 22:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: