sealed,new,virtual,abstract與override

1.sealed---“斷子絕孫”

密封類不能被繼承,不會有子類。密封方法可以重寫基類中的方法。

2.new---“你是你的,我是我的”

new關鍵字用於顯式隱藏從基類繼承的成員,也就是說在使用派生類時調用的方法是new關鍵字新定義出來的方法,而不是基類的方法。在不使用new修飾符的情況下隱藏成員是允許的,但會生成警告。使用new顯式隱藏成員會取消此警告,並使用派生類新定義的方法。即:好比是不用祖宗的東西,而是用自己創造的東西。

using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Child c = new Child();
            c.SayHello();   //顯示我是子類
            ((Parent)c).SayHello(); //顯示我是父類
        }
    }

    class Parent
    {
        public void SayHello()
        {
            Console.Write("我是父類");
        }
    }
    class Child:Parent
    {
        public new void SayHello()
        {
            Console.Write("我是子類");
        }
    }
}

3.virtual---"爲了子孫後代"

用於修改方法或屬性的聲明,修改後的方法或屬性稱作虛成員。默認情況下方法是非虛擬的。不能將virtual修飾符和static,abstract,override一起使用。調用虛方法時將爲重寫成員檢查該對象的運行時的類型,如果沒有派生類重寫該成員,則它可能是原始成員。

  • 在靜態屬性上使用virtual是錯誤的
  • 通過使用override修飾符的屬性聲明,在派生類中重寫虛擬繼承屬性。

4.abstract---“我是上帝”

abstract修飾符可以和類,方法,屬性,索引器及事件一起使用。

在類聲明中使用abstract修飾符,以指示該類只能是其他類的基類。標記爲抽象或包含在抽象類中的成員必須通過從抽象派生的類來實現。

抽象類具有以下特性:

  • 抽象類不能實例化
  • 抽象類可以包含抽象方法和抽象訪問器
  • 不能用sealed修飾符修改抽象類,這意味着該類不能被繼承。
  • 從抽象類派生的非抽象類必須包括繼承的所有抽象方法和抽象訪問器的實現。
  • 在方法或屬性中使用abstract指示此方法或屬性不包含實現
抽象方法具有以下特性:
  • 抽象方法是隱式的virtual方法。
  • 抽象方法不提供實際的實現,所以沒有方法體。並且在聲明後沒有大括號”}“
  • 實現由override提供,他是非抽象類成員
  • 在靜態屬性使用abstract修飾符是錯誤的
abstract是一種抽象,好比上帝,是人們對神的抽象,看似什麼都能幹,其實什麼都幹不了、

5.override---一手遮天

使用override修飾符來修改方法,屬性,索引器,或事件。主要是提供派生類對基類方法的新實現。覆蓋上面的abstract,virtual兩種關鍵字修飾的成員。

不能重寫非虛擬方法或者靜態方法。

new和override的區別:

  • 用override的基類的方法必須要用virtual,而new不必要。
  • 用一個基類的對象調用基類的virtual方法時,override重寫的派生類的方法全被訪問,而new重寫的派生類中的方法不會被訪問。

using System;

namespace ConsoleApplication1
{
    public class BaseClass
    {
        public BaseClass()
        {
            Console.WriteLine("基類構造");
        }
        //使用virtual纔可以在子類中使用override,而new不要
        public virtual void Method()
        {
            Console.WriteLine("基類.Method()");
        }
    }
    public class DeriveClassA : BaseClass
    {
        public DeriveClassA()
        {
            Console.WriteLine("類A.構造");
        }
        public override void Method()
        {
            //base.Method();
            Console.WriteLine("類A.Method() in override");
        }
    }

    public class DeriveClassB : BaseClass
    {
        public DeriveClassB()
        {
            Console.WriteLine("類B.構造");

        }
        public new void Method()
        {
            //base.Method();
            Console.WriteLine("類B.Method() in new");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass ba1 = (BaseClass)new DeriveClassA();//類型轉換
            //用override重寫方法,是基類的一個派生,所以這裏通過基類的虛函數,會訪問到派生類的方法
            ba1.Method();
            Console.WriteLine("==========");
            BaseClass ba2 = (BaseClass)new DeriveClassB();
            //用new重寫方法,是基類的一個派生,所以這裏基類調用的時候,訪問基類的方法
            ba2.Method();
            Console.WriteLine("==========");

            DeriveClassA a1 = new DeriveClassA();
            a1.Method();
            Console.WriteLine("==========");

            DeriveClassB b2 = new DeriveClassB();
            b2.Method();
            Console.WriteLine("==========");
            Console.Read();
        }
    }
}

運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章