Polymorfismus (Příručka programování C#)
Polymorfismus je často označována jako třetího pilíře objektově orientované programování po zapouzdření a dědičnost.Polymorfismus je řecké slovo, které znamená "tvaru n" a má dva odlišné aspekty:
V době spuštění objekty odvozené třídy považovat objekty základní třídy v místech, jako jsou parametry metody a kolekcí nebo matice.V takovém případě je shodné s jeho typ spuštění již deklarovaný typ objektu.
Základní třídy mohou definovat a implementovat virtuálnímetody, a odvozené třídy lze potlačit je, což znamená poskytují vlastní vymezení a provádění.Při spuštění když klientský kód zavolá metodu, CLR vyhledá typ spuštění objektu a vyvolá override, že virtuální metody.Tedy ve zdrojovém kódu volání metody základní třídy a způsobit odvozené třídy verze metody, které mají být provedeny.
Virtuální metody umožňují práci s skupin souvisejících objektů jednotným způsobem.Předpokládejme například, že máte výkresu aplikace, která umožňuje uživateli vytvořit různé druhy obrazců na výkresu povrchu.Nevíte v době kompilace určité typy obrazců bude uživatel vytvořit.Aplikace má ke sledování různých typů obrazců, které jsou vytvořeny a je aktualizovat jako odezva na akce uživatele myš má.Polymorfismus můžete použít k vyřešení tohoto problému ve dvou základních kroků:
Vytvoření hierarchie třídy, ve které každý konkrétní obrazec Třída odvozuje od společné základní třídy.
Pomocí virtuální metody odpovídající metodu na všechny odvozené třídy přes jedno volání metody základní třídy.
Nejprve vytvořte základní třídy nazvané Shapea jako odvozené třídy Rectangle, Circle, a Triangle.Dát Shape třídy virtuální metodu s názvem Draw, a přepsat, v každé odvozené třídy nakreslete zvláštní obrazce Třída představuje.Vytvoření List<Shape> objektu a do ní přidat kruh, trojúhelník a obdélník.Aktualizace výkresu povrchu, použijte foreach a iterovat seznam a volání Draw metodu na každém Shape objekt v seznamu.I když má každý objekt v seznamu deklarovaný typ Shape, je typu run-time (verze Potlačená metoda odvozené třídy), která bude vyvolána.
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
*/
V jazyce C# je polymorfní každý typ, protože dědí všechny typy, včetně uživatelem definované typy Object.
Přehled polymorfismus
Virtuální členů
Když odvozená třída dědí ze základní třídy, získá všechny metody, polí, vlastnosti a události základní třídy.Návrhář odvozené třídy můžete zvolit, zda
přepsat virtuální členy v základní třídě
bez jeho potlačení dědí nejbližší metody základní třídy.
Definujte nové-virtuální provádění těm členům, kteří skrýt základní třídy implementace
Odvozené třídy můžete přepsat člen základní třídy pouze v případě, že člen základní třídy je deklarován jako virtuální neboabstraktní.Odvozené člen musí použít potlačit klíčové výslovně uvede, že metoda je určen k účasti na virtuální vyvolání.Následující kód obsahuje příklad:
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; }
}
}
Pole nemohou být virtuální; virtuální lze pouze metody, vlastnosti, události a indexování.Odvozené třídy potlačí virtuálního člena, člena se nazývá i v případě, že jako instance třídy base přístup instance dané třídy.Následující kód obsahuje příklad:
DerivedClass B = new DerivedClass();
B.DoWork(); // Calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // Also calls the new method.
Virtuální metody a vlastnosti povolit rozšíření základní třídy bez nutnosti použití provádění metody základní třídy odvozené třídy.Další informace naleznete v tématu Správa verzí s přepsat a nová klíčová slova (Příručka programování C#).Rozhraní poskytuje další možnost definovat metodu nebo sadu metod, jejichž provedení je ponechána na odvozené třídy.Další informace naleznete v tématu Rozhraní (Příručka programování C#).
Skrytí základní třídy členy nové členy
Pokud chcete, aby váš odvozené člen mít stejný název jako člen v základní třídě, ale nechcete účastnit virtuální vyvolání, můžete použít nové klíčové slovo.new Klíčové slovo je umístit před návratový typ člen třídy, který je nahrazován.Následující kód obsahuje příklad:
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; }
}
}
Základní třída skryté členy je stále přístupný z kódu klienta obsazení instance, odvozené třídy k instanci třídy base.Příklad:
DerivedClass B = new DerivedClass();
B.DoWork(); // Calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // Calls the old method.
Zabránit přepsání virtuální členové odvozené třídy
Virtuální Členové zůstávají virtuální neomezeně dlouho, ohledu byly prohlášeny za kolik tříd mezi virtuálního člena a třídy, které bylo původně deklarováno.Pokud třída a deklaruje virtuálního člena je odvozen od třídy b a třídy c je odvozen z B, C třída dědí virtuální členské a má možnost jej přepsat, bez ohledu zda třídy b deklarované lokálními daného člena.Následující kód obsahuje příklad:
public class A
{
public virtual void DoWork() { }
}
public class B : A
{
public override void DoWork() { }
}
Odvozené třídy můžete zastavit virtuální dědění prohlášením lokálními jako uzavřených.To vyžaduje uvedení sealed klíčové slovo před override klíčové slovo v deklaraci třídy člen.Následující kód obsahuje příklad:
public class C : B
{
public sealed override void DoWork() { }
}
V předchozím příkladu metoda DoWork již není virtuální žádné třídy odvozené od C.Je stále virtuální instance C, i pokud jsou jsou přetypovat na typ b nebo typu A.Uzavřených metody mohou být nahrazeny odvozené třídy pomocí new klíčové slovo, jak ukazuje následující příklad:
public class D : C
{
public new void DoWork() { }
}
V tomto případě Pokud DoWork je volána pomocí proměnné typu D, D nové DoWork se nazývá.Pokud je proměnná typu C, B nebo a slouží k přístupu k instanci d volání DoWork bude řídit pravidly virtuální dědičnosti, směrování volání provádění těchto DoWork třídy C.
Přístup k základní třídy virtuální členy z odvozených tříd
Metoda nebo vlastnost základní třídy základní klíčové slovo stále přístup odvozené třídy, který nahrazuje nebo potlačené metody nebo vlastnosti.Následující kód obsahuje příklad:
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();
}
}
Další informace naleznete v tématu základní.
[!POZNÁMKA]
Je vhodné, používat virtuální členové base volání základní třídy implementace tohoto člena v jejich provádění.Takže základní třídy chování dochází umožňuje odvozené třídy soustředit se na provádění chování specifické pro odvozené třídy.Provádění základní třída nebyla volána, je na odvozené třídy tak, aby jejich chování kompatibilní s chování základní třídy.
V tomto oddíle
Správa verzí s přepsat a nová klíčová slova (Příručka programování C#)
Víte, kdy použít přepsat a nová klíčová slova (C# Příručka programování)
Viz také
Referenční dokumentace
Dědičnost (Příručka programování C#)
Abstraktní a uzavřených tříd a členů tříd (Příručka programování C#)
Metody (Příručka programování C#)
Události (Příručka programování C#)
Vlastnosti (Příručka programování C#)
Indexování (Příručka programování C#)
Typy (Příručka programování C#)