C#繼承的執行順序


  自己對多態中構造函數、函數重載執行順序和過程一直有些不理解,經過測試,對其中的運行順序有了一定的了解,希望對初學者有些幫助。

eg1:

public  class A
    {
        public A()
        { 
            Console.WriteLine('A'); 
        }
        public virtual void Fun()
        {
            Console.WriteLine("A.Fun()"); 
        }
    }

    public class B : A
    {
        public B()
        { 
            Console.WriteLine('B');
        }
        public void Fun()
        { 
            Console.WriteLine("B.Fun()"); 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            a.Fun();
            Console.ReadLine();
        }
    }
View Code

上述Main方法中在new A對象時,程序首先進入class A中,執行class A的構造函數A(),然后執行class A中的Fun()方法,故運行結果為:

eg2:

 public  class A
    {
        public A()
        { 
            Console.WriteLine('A'); 
        }
        public void Fun()
        {
            Console.WriteLine("A.Fun()"); 
        }
    }

    public class B : A
    {
        public B()
        { 
            Console.WriteLine('B');
        }
        public void Fun()
        { 
            Console.WriteLine("B.Fun()"); 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.Fun();
            Console.ReadLine();
        }
    }
View Code

上述Main方法中在new B對象時,由於B:A先執行父類的構造函數,所以先執行A中的構造函數A(),然后在執行B中的構造函數B(),故運行結果為:

eg3:

 public  class A
    {
        public A()
        { 
            Console.WriteLine('A'); 
        }
        public void Fun()
        {
            Console.WriteLine("A.Fun()"); 
        }
    }

    public class B : A
    {
        public B()
        { 
            Console.WriteLine('B');
        }
        public void Fun()
        { 
            Console.WriteLine("B.Fun()"); 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            /*   B b = new A();  錯誤
             * A是父類,不能new一個父類對象指向子類,例:中國人是人類的對象,人類的對象不一定是中國人*/
            A a = new B();
            a.Fun();
            Console.ReadLine();
        }
    }
View Code

上述Main方法中先new B對象,先執行A中的構造函數A(),然后在執行B中的構造函數B(),最后調用class A的Fun()方法,故運行結果為:

 eg4:

public  class A
    {
        public A()
        { 
            Console.WriteLine('A'); 
        }
        public virtual void Fun()
        {
            Console.WriteLine("A.Fun()"); 
        }
    }

    public class B : A
    {
        public B()
        { 
            Console.WriteLine('B');
        }
        public override void Fun()
        { 
            Console.WriteLine("B.Fun()"); 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new B();
            a.Fun();
            Console.ReadLine();
        }
    }
View Code

上述Main方法同樣是先new B對象,先執行A中的構造函數A(),然后在執行B中的構造函數B(),但是子方法中使用了override關鍵字“覆蓋”,使得子類中方法覆蓋了父類中的方法,無法再訪問父類中原始方法。(要重寫方法,父類方法必須有virtual關鍵字),所以其運行結果為:

eg5:

public  class A
    {
        public A()
        { 
            Console.WriteLine('A'); 
        }
        public virtual void Fun()
        {
            Console.WriteLine("A.Fun()"); 
        }
    }

    public class B : A
    {
        public B()
        { 
            Console.WriteLine('B');
        }
        public new void Fun()
        { 
            Console.WriteLine("B.Fun()"); 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new B();
            a.Fun();
            Console.ReadLine();
        }
    }
View Code

上述Main方法同樣是先new B對象,先執行A中的構造函數A(),然后在執行B中的構造函數B(),但是子方法中使用了new關鍵字,由於其仍是a是A類型對象,所以仍然調用A中的方法,其運行結果如下:

1.B繼承A,請問a是A的實例還是B的實例啊? 
答:B的實例
2.對象a可以調用A類中的方法嗎?可以調用B的方法嗎? 
答:不一定,如果是虛擬方法,並且在B類重載了A的虛擬方法,a將會調用B的同名方法,普通方法會調用A的方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM