Polimorfizm (Przewodnik programowania w języku C#)

Polimorfizm jest często określany jako trzeci słupka z programowanie zorientowane obiektowo, po hermetyzacji i dziedziczenia.Polimorfizm to słowo greckim, które oznacza "wielu kształcie" i ma dwa różne aspekty:

  • W czasie wykonywania obiektów klasy pochodnej może być traktowana jako obiektów klasy bazowej w miejscach, takie jak parametry metody i kolekcje lub tablic.W takim przypadku zadeklarowanym typem obiektu nie jest już identyczne typów w czasie wykonywania.

  • Base classes may define and implement virtualmethods, and derived classes can override them, which means they provide their own definition and implementation.W czasie wykonywania gdy klient kod wywołuje metodę, środowiska CLR wyszukuje wykonywania typ obiektu i wywołuje ten zastąpienie metody wirtualnego.W związku z tym w kodu źródłowego wywołania metody w klasie podstawowej i spowodować, że wersja metody do wykonania w klasie pochodnej.

Wirtualne metody umożliwiają pracę z grupami powiązanych obiektów ujednolicone.Na przykład załóżmy, że masz aplikacji do rysowania, który umożliwia użytkownikowi tworzenie różne rodzaje kształtów na powierzchni rysowania.Nie jest znany w czasie kompilacji określonych rodzajów kształtów utworzy użytkownika.Jednak aplikacja ma być śledzone wszystkie różne rodzaje kształtów, które zostały utworzone i ma je zaktualizować w odpowiedzi na akcje myszy użytkownika.Aby rozwiązać ten problem w dwóch podstawowe kroki można użyć polimorfizmu:

  1. Tworzenie hierarchii klasy, w którym każdej klasy określonego kształtu pochodzi od klasy wspólna klasa podstawowa.

  2. Metoda wirtualnych do wywołania odpowiednią metodę na każdej klasy pochodnej za pośrednictwem jednego połączenia do metody klasy bazowej.

Najpierw należy utworzyć klasę podstawową o nazwie Shapei klasy pochodne, takich jak Rectangle, Circle, i Triangle.Nadaj Shape klasy wywołana metoda wirtualna Draw, i reprezentuje zastąpienie jej w każdej klasy pochodnej do rysowania danej kształtu, który klasy.Utwórz List<Shape> object i dodać do niego koła, trójkąt i prostokąta.Aby zaktualizować powierzchnię, użyj foreach pętli do iterowania po liście, a następnie wywołać Draw metody na każdym Shape obiektu na liście.Mimo że każdy obiekt na liście ma zadeklarowany typ Shape, jest typ wykonywania (zastąpiona wersja metody w każdej klasy pochodnej), który zostanie wywołany.

public class Shape
{
    // A few example members 
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }

    // Virtual method 
    public virtual void Draw()
    {
        Console.WriteLine("Performing base class drawing tasks");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        // Code to draw a circle...
        Console.WriteLine("Drawing a circle");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        // Code to draw a rectangle...
        Console.WriteLine("Drawing a rectangle");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        // Code to draw a triangle...
        Console.WriteLine("Drawing a triangle");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Polymorphism at work #1: a Rectangle, Triangle and Circle 
        // can all be used whereever a Shape is expected. No cast is 
        // required because an implicit conversion exists from a derived  
        // class to its base class.
        System.Collections.Generic.List<Shape> shapes = new System.Collections.Generic.List<Shape>();
        shapes.Add(new Rectangle());
        shapes.Add(new Triangle());
        shapes.Add(new Circle());

        // Polymorphism at work #2: the virtual method Draw is 
        // invoked on each of the derived classes, not the base class. 
        foreach (Shape s in shapes)
        {
            s.Draw();
        }

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }

}

/* Output:
    Drawing a rectangle
    Performing base class drawing tasks
    Drawing a triangle
    Performing base class drawing tasks
    Drawing a circle
    Performing base class drawing tasks
 */

W języku C#, każdego typu jest polimorficzny, ponieważ wszystkie typy, w tym typy zdefiniowane przez użytkownika, dziedziczą z Object.

Omówienie polimorfizm

Członkowie wirtualnego

Klasy pochodnej dziedziczy po klasie podstawowej, uzyskuje się wszystkie metody, pola, właściwości i zdarzeń klasy bazowej.Projektant klasy pochodnej można wybrać opcję

  • Zastąp wirtualnych elementów członkowskich w klasie podstawowej

  • Dziedzicz najbliższego metody klasy podstawowej bez przesłanianie go

  • Definiowanie nowych niewirtualnego realizacji tych elementów członkowskich, które Ukryj implementacji klasy podstawowej

Klasy pochodne mogą przesłaniać członek klasy podstawowej tylko wtedy, gdy element członkowski klasa podstawowa jest zadeklarowany jako wirtualnego lub ogólna.Element członkowski pochodne muszą mieć zastąpić słowo kluczowe, aby jawnie wskazać, że metoda jest przeznaczona do uczestnictwa w wirtualnych wywołania.Poniższy kod zawiera przykładowy:

public class BaseClass
{
    public virtual void DoWork() { }
    public virtual int WorkProperty
    {
        get { return 0; }
    }
}
public class DerivedClass : BaseClass
{
    public override void DoWork() { }
    public override int WorkProperty
    {
        get { return 0; }
    }
}

Pola nie może być wirtualnych; tylko metody, właściwości i zdarzeń oraz indeksatory może być wirtualnego.Po klasie pochodnej zastępuje członka wirtualnego, ten element członkowski jest wywoływana nawet w przypadku wystąpienia tej klasy jest dostępny jako wystąpienie klasy bazowej.Poniższy kod zawiera przykładowy:

DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Also calls the new method.

Wirtualne metody i właściwości Włącz klasy pochodne rozszerzyć klasę podstawową bez konieczności użycia klasy podstawowej implementacji metody.Aby uzyskać więcej informacji, zobacz Przechowywanie wersji zastępowania i nowych słów kluczowych (Przewodnik programowania w języku C#).Interfejs umożliwia innym definicji metody lub zestaw metod, których wykonanie pozostanie na klasy pochodnej.Aby uzyskać więcej informacji, zobacz Interfejsy (Przewodnik programowania w języku C#).

Ukrywanie elementów członkowskich klasa podstawowa dla nowych członków

Jeśli chcesz, aby Twój pochodnej element ma taką samą nazwę jak element członkowski w klasie podstawowej, ale nie chcesz brać udziału w wywołania wirtualnego, można użyć nowy słowo kluczowe.new Słowo kluczowe jest umieszczany przed zwracany typ elementu członkowskiego klasy zastępowanej figury geometrycznej.Poniższy kod zawiera przykładowy:

public class BaseClass
{
    public void DoWork() { WorkField++; }
    public int WorkField;
    public int WorkProperty
    {
        get { return 0; }
    }
}

public class DerivedClass : BaseClass
{
    public new void DoWork() { WorkField++; }
    public new int WorkField;
    public new int WorkProperty
    {
        get { return 0; }
    }
}

Nadal można uzyskać dostęp ukryty klasa podstawowa członków z klienta kodu przez rzutowanie wystąpienie klasy pochodnej do wystąpienia klasy bazowej.Na przykład:

DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Calls the old method.

Klasy pochodne uniemożliwia zastąpienie wirtualnych elementów członkowskich

Członkowie wirtualnego nadal wirtualnego, niezależnie od tego, jak wiele klas zostały zgłoszone między członkiem wirtualnym i klasę, która pierwotnie został zadeklarowany.Jeśli klasa A deklaruje wirtualnego elementu członkowskiego, klasa B pochodzi od A i Klasa C pochodzi z B, klasy C dziedziczy członkiem wirtualnym i jest dostępna opcja Zastąp go, bez względu na to czy klasy B podana zastąpienia dla tego elementu członkowskiego.Poniższy kod zawiera przykładowy:

public class A
{
    public virtual void DoWork() { }
}
public class B : A
{
    public override void DoWork() { }
}

Klasy pochodnej można przerwać dziedziczenia wirtualnych poprzez zastąpienie jako zgłoszenie zapieczętowanego.Wymagane jest, bo sealed przed override słowo kluczowe w deklaracji elementu członkowskiego.Poniższy kod zawiera przykładowy:

public class C : B
{
    public sealed override void DoWork() { }
}

W poprzednim przykładzie metoda DoWork nie jest już wirtualnych dla każdej klasy pochodne C.Jest nadal wirtualnych dla wystąpienia klasy C, nawet jeśli są one rzutować na typ B lub wpisz A.Zapieczętowanego metody może zostać zastąpione klasy pochodne przy użyciu new słowo kluczowe, jak pokazano w następującym przykładzie:

public class D : C
{
    public new void DoWork() { }
}

W tym przypadku jeśli DoWork jest wywoływana w D przy użyciu zmiennej typu D, nowy DoWork jest wywoływana.Jeśli zmienna typu C, B lub obiekt są używane do uzyskać dostęp do wystąpienia D, po wywołaniu DoWork będzie zgodna z zasadami wirtualnego dziedziczenia, routing wywołań do implementacji DoWork klasy C.

Dostęp do elementów członkowskich wirtualnego klasa podstawowa z klasy pochodne

Klasy pochodnej, który został zastąpiony lub zastąpić metodę lub właściwość nadal dostępny metodę lub właściwość po klasę podstawową przy użyciu słowa kluczowego podstawowy.Poniższy kod zawiera przykładowy:

public class Base
{
    public virtual void DoWork() {/*...*/ }
}
public class Derived : Base
{
    public override void DoWork()
    {
        //Perform Derived's work here 
        //... 
        // Call DoWork on base class 
        base.DoWork();
    }
}

Aby uzyskać więcej informacji, zobacz podstawową.

[!UWAGA]

Zaleca się, że Członkowie wirtualnego używać base można odwoływać się do implementacji klasy podstawowej tego elementu członkowskiego w ich własnych implementacji.Czekać na zachowanie klasa podstawowa wystąpienia klasy pochodnej w celu koncentrować się na umożliwia implementowania zachowanie specyficzne dla klasy pochodnej.Jeśli nie zostanie wywołany Implementacja klasy podstawowej, jest klasy pochodnej, aby zapewnić zgodność z zachowaniem klasę podstawową ich działanie.

W tej sekcji

Zobacz też

Informacje

Dziedziczenie (Przewodnik programowania w języku C#)

Klasy abstrakcyjne i zapieczętowane oraz członkowie klas (Przewodnik programowania w języku C#)

Metody (Przewodnik programowania w języku C#)

Zdarzenia (Przewodnik programowania w języku C#)

Właściwości (Przewodnik programowania w języku C#)

Indeksatory (Przewodnik programowania w języku C#)

Typy (Przewodnik programowania w języku C#)

Koncepcje

Przewodnik programowania w języku C#

Przewodnik programowania w języku C#