CSharp之new、override、base

一、new關鍵字表示隱藏,是指加上new關鍵字的屬性或函數將對本類和繼承類隱藏基類的同名屬性或函數,派生類中new修飾的屬性或方法,父類看不到new的新方法,子類看不到被new的父類方法

//定義兩個類:ClassA類,並在ClassA類中定義方法:ClassA_Method,
//ClassB類繼承ClassA,並隱藏(new)方法ClassA_Method

namespace NewIntro
{
    public class ClassA
    {
        public virtual void ClassA_Method()
        {
            Console.WriteLine("ClassA_Method() in ClassA.\r\n");
        }
    }
    public class ClassB:ClassA
    {
        //隱藏ClassA中的方法ClassA_Method
        public new void ClassA_Method()
        {
            Console.WriteLine("ClassA_Method() in ClassB.\r\n");
        }
    }
}

//控制檯程序調用如下:
namespace NewIntro
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("ClassB實例賦給ClassA類型變量,運行結果:");
            ClassA a = new ClassB();
            a.ClassA_Method();

            Console.WriteLine("ClassB實例賦給ClassB類型變量:");
            ClassB b = new ClassB();
            b.ClassA_Method();
            Console.ReadLine();
        }
    }
}

運行結果:

二、派生類中override的屬性或方法,父類和子類看到的都是派生類override後的方法

//定義兩個類:ClassA類,並在ClassA類中定義方法:ClassA_Method,
//ClassB類繼承ClassA,並重載(override)方法ClassA_Method
namespace OverrideIntro
{
    public class ClassA
    {
        public virtual void ClassA_Method()
        {
            Console.WriteLine("ClassA_Method() in ClassA.\r\n");
        }
    }
    public class ClassB : ClassA
    {
        //隱藏ClassA中的方法ClassA_Method
        public override void ClassA_Method()
        {
            Console.WriteLine("ClassA_Method() in ClassB.\r\n");
        }
    }
}

//控制檯程序調用如下:
namespace OverrideIntro
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\r\nClassB實例賦給ClassA類型變量,運行結果:");
            ClassA a = new ClassB();
            a.ClassA_Method();

            Console.WriteLine("ClassB實例賦給ClassB類型變量,運行結果:");
            ClassB b = new ClassB();
            b.ClassA_Method();
            Console.ReadLine();
        }
    }
}

運行結果:

三、在派生類中如果base.父類方法方式調用了基類的方法或屬性,則調用的是基類方法

//定義兩個類:ClassA類,並在ClassA類中定義方法:ClassA_Method,
//ClassB類繼承ClassA,並重載(override)方法ClassA_Method,調用父類:base.ClassA_Method()
namespace BaseIntro
{
    public class ClassA
    {
        public virtual void ClassA_Method()
        {
            Console.WriteLine("ClassA_Method() in ClassA.\r\n");
        }
    }
    public class ClassB : ClassA
    {
        //隱藏ClassA中的方法ClassA_Method
        public override void ClassA_Method()
        {
            base.ClassA_Method() ;
        }
    }
}
//控制檯程序調用:
namespace BaseIntro
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\r\nClassB實例賦給ClassA類型變量,運行結果:");
            ClassA a = new ClassB();
            a.ClassA_Method();

            Console.WriteLine("ClassB實例賦給ClassB類型變量,運行結果:");
            ClassB b = new ClassB();
            b.ClassA_Method();
            Console.ReadLine();
        }
    }
}

運行結果:

四、接口在相互繼承的時候也會隱藏基接口的同名屬性或函數,但是對於接口來說很特殊,隱藏對於基接口來說是不起作用的,接口內部的屬性和函數都只是聲明,它們都指向實現接口的類中的同名實現函數,通過接口調用接口的屬性和函數的時候都會去調用實現類中從上到下最先可見的同名函數和同名屬性

//定義InterfaceA接口,在此接口聲明方法InterfaceA_Method(),定義InterfaceB,繼承自Interface_A,
//並在此接口隱藏聲明方法InterfaceA_Method(),IClass類實現接口InterfaceB的方法
//InterfaceB_Method,在IClass的子類ISubClass中再次隱藏聲明InterfaceA_Method().
namespace InterfaceIntro
{
    public interface InterfaceA
    {
        void InterfaceA_Method();
    }

    public interface InterfaceB:InterfaceA
    {
        new void InterfaceA_Method();
    }

    public class IClass:InterfaceB
    {
        public void InterfaceA_Method()
        {
            Console.WriteLine("InterfaceA_Method in IClass.");
        }
    }

    public class ISubClass:IClass
    {
        public new void InterfaceA_Method()
        {
            Console.WriteLine("InterfaceA_Method in ISubClass.");
        }
    }
}

//控制檯程序調用:
namespace InterfaceIntro
{
    class Program
    {
        static void Main(string[] args)
        {
            InterfaceA ia = new ISubClass();
            ia.InterfaceA_Method();
            Console.ReadLine();
        }
    }
}

運行結果:

可以看出來,因爲對於ia來說在繼承鏈中最先見到的同名實現函數是類IClass的Method函數,InterfaceB中雖然也隱藏了InerfaceA_Method() 方法,但隱藏無效,因此最先顯示IClass中內容。

如果在ISubClass中重載 (override)呢,代碼如下:

namespace InterfaceOverIntro
{
    public interface InterfaceA
    {
         void  InterfaceA_Method();
    }

    public interface InterfaceB : InterfaceA
    {
        new void InterfaceA_Method();
    }

    public class IClass : InterfaceB
    {
        public virtual void InterfaceA_Method()
        {
            Console.WriteLine("InterfaceA_Method in IClass.");
        }
    }

    public class ISubClass : IClass
    {
        public override void InterfaceA_Method()
        {
            Console.WriteLine("InterfaceA_Method in ISubClass.");
        }
    }
}

//控制檯程序調用:
namespace InterfaceOverIntro
{
    public interface InterfaceA
    {
         void  InterfaceA_Method();
    }

    public interface InterfaceB : InterfaceA
    {
        new void InterfaceA_Method();
    }

    public class IClass : InterfaceB
    {
        public virtual void InterfaceA_Method()
        {
            Console.WriteLine("InterfaceA_Method in IClass.");
        }
    }

    public class ISubClass : IClass
    {
        public override void InterfaceA_Method()
        {
            Console.WriteLine("InterfaceA_Method in ISubClass.");
        }
    }
}

運行結果:

輸出InterfaceA_Method in ISubClass,因爲繼承鏈中的InterfaceA_Method() 方法都被ISubClass的InterfaceA_Method覆蓋了,所以對於ia來說在繼承鏈中最先見到的同名實現函數是類ISubClass的InterfaceA_Method方法。

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