香蕉视频app

Keep on going never give up.

Let's Go

C# 學習筆記(41)面向對象三大特性之多態

C#Lonely2019-05-16 23:25:3748次0條

多態的概念: 香蕉视频app讓一個對象能夠表現出多種狀態(類型),即相同類型的對象調用相同的方法卻表現出不同行為的現象。

由于可以繼承基類的所有成員,子類就都有了相同的行為,但是有時子類的某些行為需要相互區別,子類需要覆寫父類中的方法來實現子類特有的行為,這樣的技術在面向對象的編程中就是多態。

通常實現多態有三種手段:(1)、虛方法(2)、抽象類(3)、接口

虛方法

虛方法就是使用virtual關鍵字修飾的方法。只有父類成員聲明為virtualabstract時,才能被子類重寫,如果子類想改變虛方法的實現行為(也就是重寫虛方法)時,則必須使用override關鍵字來修飾。

當在已知條件中,可以找到一個父類并且父類知道該怎么去實現行為的時候,我們可以使用虛方法,來實現多態,當父類不知道該怎么去實現行為的時候我們可以用抽象類,來實現多態。

代碼示例:

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //用虛方法來實現  真的鴨子嘎嘎叫  木頭鴨子吱吱叫   橡皮鴨子唧唧叫
            RealDuck rd = new RealDuck(); //真鴨子
            MuDuck md = new MuDuck(); //木頭鴨子
            XPDuck xd = new XPDuck(); //橡皮鴨子
            
            RealDuck[] arr = new RealDuck[3] { rd, md, xd };
            for (int i = 0; i < arr.Length; i++)
            {
                //相同類型的對象調用相同的方法表現出不同的行為
                arr[i].Bark();
            }
            Console.ReadKey();
        }
    }

    /// <summary>
    /// 真鴨子(父類)
    /// </summary>
    public class RealDuck
    {
        public virtual void Bark() //虛方法
        {
            Console.WriteLine("真的鴨子嘎嘎叫");
        }
    }
    
    /// <summary>
    /// 木頭鴨子(子類)
    /// </summary>
    public class MuDuck : RealDuck
    {
        //子類應該重寫父類的方法,以實現自己特有的行為
        public override void Bark()
        {
            Console.WriteLine("木頭鴨子吱吱叫");
        }
    }
    
    /// <summary>
    /// 橡皮鴨子(子類)
    /// </summary>
    public class XPDuck : RealDuck
    {
        //重寫父類方法
        public override void Bark()
        {
            Console.WriteLine("橡皮鴨子唧唧叫");
        }
    }

}

上面代碼父類在需要通過子類中表現不同行為的方法,使用virtual關鍵字將其定義為虛方法,然后在子類中使用override關鍵字對父類方法進行重寫。這樣,每個父類對象在調用相同的方法時將表現出不同的行為,這段代碼正是多態虛方法的實現。

如果子類還想繼續訪問父類定義的方法,則可以使用base關鍵字來完成調用,例如:base.Bark(); //調用父類的方法。

運行結果:

image.png

從上面的運行結果可以看出,相同類型的對象調用相同的方法確實表現出了不同的行為,這就是多態精髓的所在。

阻止派生類重寫虛成員

sealed關鍵字可以防止一個類被其他類繼承,同樣,也可以使用sealed關鍵字來阻止派生類重寫虛成員。例如:我們希望MuDuck的繼承類不再具有擴展Bark方法的行為,則可以使用sealed關鍵字來停止虛擬繼承,如以下代碼所示:

/// <summary>
/// 木頭鴨子(子類)
/// </summary>
public class MuDuck : RealDuck
{      
    public sealed override void Bark()
    {
        Console.WriteLine("木頭鴨子吱吱叫");
    }
}

香蕉视频app 如果按下面的代碼,嘗試在MuDuck的派生類中重寫Bark方法,則會收到“無法對密封成員進行復寫”的錯誤信息。

/// <summary>
/// 紅木鴨子
/// </summary>
public class RedMuDuck : MuDuck
{
    //編譯時錯誤,因為此時Bark在父類MuDuck中被sealed修飾,定位為密封。
    public override void Bark()
    {
        Console.WriteLine("紅木鴨子嘎吱叫");
    }
}

抽象類

● 抽象類與抽象方法由abstract關鍵字修飾。

abstract關鍵字的使用注意

1、抽象成員必須標記為abstract,并且不能有任何實現。

香蕉视频app 2、抽象成員必須在抽象類中。

3、抽象類不能被實例化。

4、子類繼承抽象類后,必須把父類中的所有抽象成員都重寫(實現抽象方法體),除非子類也是一個抽象類,則可以不進行重寫。

5、抽象成員的訪問修飾符不能是private

6、抽象類中可以包含實例成員,并且抽象類的實例成員可以不被子類實現。

香蕉视频app 7、抽象類是有構造函數的,雖然不能被實例化。

8、如果父類的抽象方法中有參數,那么繼承這個抽象父類的子類在重寫父類的方法的時候必須傳入對應的參數。如果抽象父類的抽象方法中有返回值,那么子類在重寫這個抽象方法的時候,也必須傳入返回值。

問:香蕉视频app什么時候應該用虛方法或抽象類?

答:如果父類中的方法有默認的實現,并且父類需要被實例化的時候,可以考慮將父類定義成普通類,使用虛方法來實現多態。如果父類中的方法沒有默認實現,父類也不需要被實例化的時候,則可以將該類定義抽象類來實現多態。

代碼示例:

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用抽象類來實現多態的示例:
            //狗狗會叫   貓咪也會叫   小羊也會叫
            Animal[] arr = { new Dog(), new Cat(), new sheep() };
            for (int i = 0; i < arr.Length; i++)
            {
                //相同類型的對象調用相同的方法表現出不同的行為
                arr[i].Voice();
            }
            Console.ReadKey(); 
        }
    }

    /// <summary>
    /// 動物基類
    /// </summary>
    public abstract class Animal //抽象類
    {
        public abstract void Voice(); //抽象方法不能寫方法體,大括號也不能有。
    }

    /// <summary>
    /// 狗(子類)
    /// </summary>
    public class Dog: Animal
    {
        //子類應該重寫父類的方法,以實現自己特有的行為
        public override void Voice()
        {
            Console.WriteLine("小狗汪汪叫~");
        }
    }

    /// <summary>
    /// 貓(子類)
    /// </summary>
    public class Cat : Animal
    {
        public override void Voice() //重寫父類方法
        {
            Console.WriteLine("小貓喵喵叫~");
        }
    }

    /// <summary>
    /// 羊(子類)
    /// </summary>
    public class sheep : Animal
    {
        public override void Voice() //重寫父類方法
        {
            Console.WriteLine("小羊咩咩叫~");
        }
    }

}

運行結果:

image.png


暗錨,解決錨點偏移

文章評論

    嘿,來試試登錄吧!