Cδにおける多形


多形は、オブジェクト指向プログラミングの非常に重要な柱です.ギリシャ語の意味“多形”は、この柱は、オブジェクトの複数のフォームを取ることができます.これは実際よりも複雑に聞こえるので、いくつかの例に飛び込むことができます.
私はクラスですA とクラスB . B 相続するA . インMain() , これにより、いくつかの興味深い動作が可能になります.
class A { } 

class B : A { }

public class Program
{
    public static void Main(string[] args)
    {
        A a = new B(); //No error?!
    }
}
どのようにエラーがスローされますか?私は明らかに変数に不正な型を割り当てるしようとしている!私はそうではない.時B 相続するA , それはAの形になり、それはA 必要に応じて.
より多くの例を見てみましょう.
using System;

public class Program
{
    public static void Main(string[] args)
    {
        DoSomething(new A());
        DoSomething(new B());
    }
    static void DoSomething(A obj)
    {
        Console.WriteLine($"Object Type: {obj.GetType()}");
    }
}
出力:
Object Type: A
Object Type: B
別の例
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main(string[] args)
    {
        List<A> objs = new List<A>();
        objs.Add(new A());
        objs.Add(new B());
        foreach (A obj in objs)
        {
            Console.WriteLine($"Object Type: {obj.GetType()}");
        }
    }
}
出力:
Object Type: A
Object Type: B
私は、あなたのすべてがあなたの席の端にあるということを知っています、しかし、私はあなたに多義性のもう一つの狂った使用を知らせさせます:オーバーライド方法.「でもそれだけの遺産じゃないの?」聞いてね.そして、あなたは技術的に正しいでしょう.オブジェクト指向プログラミングのすべての柱のように、継承と多面的な手で手を仕事に最適な機能を提供する.
さて、メソッドのオーバーライドは2つの驚くべきキーワードで行うことができます.virtual and override . virtual 基本的に、メソッド/フィールドは、クラスの形式でオーバーライドされるように、その手を上げます.override 教師はメソッド/フィールドを呼び出してクラスの形式でオーバーライドします.
アクションでこれらのキーワードを見ましょう
using System;

public class Program
{
    public static void Main(string[] args)
    {
        DoStuff(new A());
        DoStuff(new B());
    }
    static void DoStuff(A obj)
    {
        obj.DoSomething();
    }
}

class A
{
    public virtual void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}
出力:
I did something in A's method!
I did something in B's method!
両方のオブジェクトはA , しかし、同じ方法の異なる実装を持っていた!
それを紹介する時間ですsealed キーワード.使用するならvirtual あなたの手を上げるようなものを使用してsealed あなたの手を保つことと同等です.そして、クラス全体に従事しようとしているその教師とは異なり、C言語のコンパイラでは、クラスの形式でそのメソッド/フィールドをオーバーライドすることはできません.
もう一つの高いオクタンの例は、我々にクラスを導入しますC :
class A
{
    public virtual void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public sealed override void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}

class C : B
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something in C's method!");
    }
}
出力:
error CS0239: 'C.DoSomething()': cannot override inherited member 'B.DoSomething()'
それで、我々はそれを見ることができますsealed オーバーライドメソッドのチェーンを切断します.
私は、あなたがちょうど使用方法を学んだ驚くべきキーワードからコード誘導昏睡状態にあるこの時点で知っているが、私は杭の1つの最後のキーワードをこっそり聞かせてください.教室類推を続けるnew キーワードは、彼らの手を上げて、彼らの後ろにもう一人の学生をブロックしているその1つの過度に熱心な学生に似ています.これは生徒が後ろに学生ではなく前に学生を呼んでいる結果になります.そして、あなたがフリークアウトする前に、私も非常に驚いたnew キーワードは、オブジェクトを初期化するより、もう一つの使用をします.
注意:クラスのフォームを基底クラスとして使用する場合、new メソッド/フィールドは、元のものを隠して動作しません.
例:
using System;

public class Program
{
    public static void Main(string[] args)
    {
        DoStuff(new A());
        DoStuff(new B());
    }
    static void DoStuff(A obj)
    {
        obj.DoSomething();
    }
}

class A
{
    public void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public new void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}
出力:
I did something in A's method!
I did something in A's method!
The new 合格したキーワードB としてA . これが理由ですoverride !!)例new 作業
using System;

public class Program
{
    public static void Main(string[] args)
    {
        new A().DoSomething();
        new B().DoSomething();
    }
}

class A
{
    public void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public new void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
    }
}
出力:
I did something in A's method!
I did something in B's method!
今、それはあなたを傷つける限り、これは私を傷つけるが、私は1つの最後のキーワードを導入する必要があります.私は知っているnew が最後になるだろうが、これはあなたがCの経度開発者を信頼するときに起こることです!とにかく、あなたが知る必要がある最後の重要なキーワードはbase . The base キーワードは、新しいクラスを作成する必要はありませんが、基本クラスのメソッドとフィールドのフォームからアクセスすることができます.それは音と同じくらい便利です.
例:
using System;

public class Program
{
    public static void Main(string[] args)
    {
        new B().DoSomething();
    }
}

class A
{
    public virtual void DoSomething()
    {
        Console.WriteLine("I did something in A's method!");
    }
}

class B : A
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something in B's method!");
        base.DoSomething();
    }
}
出力:
I did something in B's method!
I did something in A's method!
場合は、Cの経度で多型を使用する可能性のすべてを学びたい場合は、私はさらに調査を提案するthis Microsoft article .
読書ありがとう!
( Cover image source )