Réimprimé de : MSDN
Articles similaires : Cliquez pour ouvrir le lien
Le polymorphisme (polymorphisme) est Mot grec signifiant « plusieurs formes », le polymorphisme présente deux aspects distincts :
Lorsque cela se produit, le type déclaré de l'objet est n'est plus le même que le type d'exécution.
Au moment de l'exécution, le code client appelle cette méthode, le CLR recherche le type d'exécution de l'objet et appelle le remplacement de la méthode méthode virtuelle. Ainsi, vous pouvez appeler une méthode de classe de base dans le code source, mais exécuter la version de classe dérivée de la méthode.
Le forçage entre une classe dérivée (sous-classe) et une classe de base (classe parent) ne fera pas perdre d'informations.
namespace PolymorphismTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ParentClass parent = new ParentClass(); SubClass sub = new SubClass(); parent = ((ParentClass)sub); //子类 父类 实例之间来回转换不会丢失信息 SubClass subNew = (SubClass)parent; } } public class SubClass : ParentClass { public new string name = "SubClass"; public int age = 20; } public class ParentClass { string name = "ParentClass"; } }
Exécuter vers
SubClass subNew = (SubClass)parent
Les résultats spécifiques sont les suivants :
Par exemple, supposons que vous disposiez d'une application de dessin qui permet aux utilisateurs de créer diverses formes sur la surface de dessin. Vous ne savez pas au moment de la compilation quels types spécifiques de formes l'utilisateur va créer. Mais l'application doit garder une trace de tous les types de formes créées et doit mettre à jour ces formes en réponse aux actions de la souris de l'utilisateur. Vous pouvez résoudre ce problème en utilisant le polymorphisme en deux étapes de base :
Créer une hiérarchie de classes où chaque classe de forme spécifique est dérivée d'un commun classe de base.
Utilisez des méthodes virtuelles pour appeler la méthode correspondante sur n'importe quelle classe dérivée avec un seul appel à la méthode de la classe de base.
fournit une méthode virtuelle nommée Draw pour la classe Shape, et dans Override cette méthode dans chaque classe dérivée pour dessiner la forme spécifique représentée par cette classe. Créez un objet List
C#
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 */
在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。
关注对象原则:调用子类还是父类的方法,取决于创建的对象是子类对象还是父类对象
多态性概述
虚成员
派生类的设计器可以选择是否
重写基类中的虚拟成员。
继承最接近的基类方法而不重写它
定义隐藏基类实现的成员的新非虚实现
派生成员必须使用 override 关键字显式指示该方法将参与虚调用。 以下代码提供了一个示例:
C#
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; } } }
当派生类重写某个虚拟成员时,即使该派生类的实例被当作基类的实例访问,也会调用该成员。 以下代码提供了一个示例:
C#
DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method.BaseClass A = (BaseClass)B; A.DoWork(); // Also calls the new method.
有关详细信息,请参阅使用 Override 和 New 关键字进行版本控制(C# 编程指南)。 接口提供另一种方式来定义将实现留给派生类的方法或方法集。 有关详细信息,请参阅接口(C# 编程指南)。
使用新成员隐藏基类成员
new 关键字放置在要替换的类成员的返回类型之前。 以下代码提供了一个示例:
C#
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; } } }
例如:
C#
DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method.BaseClass A = (BaseClass)B; A.DoWork(); // Calls the old method.
阻止派生类重写虚拟成员
如果类 A 声明了一个虚拟成员,类 B 从 A 派生,类 C 从类 B 派生,则类 C 继承该虚拟成员,并且可以选择重写它,而不管类 B 是否为该成员声明了重写。 以下代码提供了一个示例:
C#
public class A { public virtual void DoWork() { } }public class B : A { public override void DoWork() { } }
这需要在类成员声明中的 override 关键字前面放置 sealed 关键字。 以下代码提供了一个示例:
C#
public class C : B { public sealed override void DoWork() { } }
即使它们转换为类型 B 或类型 A,它对于 C 的实例仍然是虚拟的。 通过使用 new 关键字,密封的方法可以由派生类替换,如下面的示例所示:
C#
public class D : C { public new void DoWork() { } }
如果使用类型为 C、B 或 A 的变量访问 D 的实例,对 DoWork 的调用将遵循虚拟继承的规则,即把这些调用传送到类 C 的 DoWork 实现。
从派生类访问基类虚拟成员
以下代码提供了一个示例:
C#
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(); } }
有关详细信息,请参阅 base。
Polymorphisme C# |
---|
允许基类行为发生使得派生类能够集中精力实现特定于派生类的行为。 未调用基类实现时,由派生类负责使它们的行为与基类的行为兼容。 |
以上就是C# 多态性的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!