C# ポリモーフィズム

黄舟
リリース: 2017-02-16 11:12:43
オリジナル
1589 人が閲覧しました


転載元: MSDN

類似記事: クリックしてリンクを開きます

ポリモーフィズム (ポリモーフィズム) は、「多くの形式」を意味するギリシャ語です。ポリモーフィズムには 2 つの異なる側面があります。 これが発生すると、オブジェクトの宣言された型は実行時の型と同じではなくなります。

  • 実行時に、クライアント コードはこのメソッドを呼び出し、CLR はオブジェクトのランタイム型を検索し、仮想メソッドのオーバーライドされたメソッドを呼び出します。

  • つまり、ソース コードで基本クラスのメソッドを呼び出すことができますが、そのメソッドの派生クラス バージョンを実行できます。
  • 派生クラス (サブクラス) と基本クラス (親クラス) の間で強制的に情報が失われることはありません。

  • 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"; 
        }
    }
    ログイン後にコピー

  • SubClass subNew = (SubClass)parent
    ログイン後にコピー
  • に対して実行すると、具体的な結果は以下の通りです。

    たとえば、次のような描画アプリケーションがあるとします。ユーザーは描画面上にさまざまな形状を作成できます。

    コンパイル時には、ユーザーがどのような具体的な種類の図形を作成するかわかりません。

    ただし、アプリケーションは作成されたすべての種類の図形を追跡し、ユーザーのマウス操作に応じてこれらの図形を更新する必要があります。


    ポリモーフィズムを使用すると、次の 2 つの基本的な手順でこの問題を解決できます。

  • それぞれの特定の形状クラスが共通の基本クラスから派生するクラス階層を作成します。

仮想メソッドを使用して、基本クラスのメソッドを 1 回呼び出すだけで、任意の派生クラスの対応するメソッドを呼び出します。 Shape クラスに

Draw
    という名前の仮想メソッドを提供し、各派生クラスでそのメソッドをオーバーライドして、そのクラスによって表される特定の形状を描画します。
  1. List オブジェクトを作成し、それに円、三角形、四角形を追加します。

  2. 描画面を更新するには、foreach ループを使用してリストを反復処理し、その中の各
  3. Shape

    オブジェクトの Draw メソッドを呼び出します。

  4. リスト内の各オブジェクトには宣言された型
Shape

がありますが、呼び出されるのは実行時型 (各派生クラスでこのメソッドのオーバーライドされたバージョン) になります。



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&#39;s work here 
        //... 
        // Call DoWork on base class 
        base.DoWork();
    }
}
ログイン後にコピー

有关详细信息,请参阅 base。

C# ポリモーフィズム C# ポリモーフィズム

 允许基类行为发生使得派生类能够集中精力实现特定于派生类的行为。 未调用基类实现时,由派生类负责使它们的行为与基类的行为兼容。

 以上就是C#  多态性的内容,更多相关内容请关注PHP中文网(www.php.cn)!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート