程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中的繼承、重寫、覆蓋、多態、virtual override 以及其他

C#中的繼承、重寫、覆蓋、多態、virtual override 以及其他

編輯:C#入門知識

例子:

    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

    public class BaseClass    {
        public virtual void displayName()
        {
            Console.WriteLine("BaseClass");
        }
    }

    public class DerivedClass : BaseClass
    {
        public virtual void displayName()
        {
            Console.WriteLine("DerivedClass");
        }     
    }

    public class SubDerivedClass:DerivedClass
    {
        public override void displayName()
        {
            Console.WriteLine("SubDerivedClass");
        }   
    }

    public class SuperDerivedClass:SubDerivedClass
    {
        public void displayName()
        {
            Console.WriteLine("SuperDerivedClass");
        }     
    }


    class Program
    {
        static void Main(string[] args)
        {
            SuperDerivedClass superDerivedClass = new SuperDerivedClass();
            SubDerivedClass subDerivedClass = superDerivedClass;
            DerivedClass derivedClass = superDerivedClass;
            BaseClass baseClass = superDerivedClass;

            superDerivedClass.displayName();
            subDerivedClass.displayName();
            derivedClass.displayName();
            baseClass.displayName();

        }
    }

執行結果

clip_image001

結果剖析:

superDerivedClass.displayName();

clip_image002 

不需解釋。沒有子類,所以無多態。

 

subDerivedClass.displayName();

clip_image003

subDerivedClass重寫了DerivedClass的方法,則subDerivedClass中的displayName也是虛方法,於是運行時要從繼承鏈中盡量找派生得最遠的虛方法,發現其子類SuperDerivedClass沒有用override,這意味著SuperDerivedClass只是覆蓋了displayName方法,沒有重寫它。所以並不執行SuperDerivedClass的displayName,而執subDerivedClass的displayName。

 

derivedClass.displayName();

clip_image004

DerivedClass覆蓋了(是覆蓋,不是重寫,因為沒有override標簽)BaseClass的方法,但這個覆蓋的方法被聲明為virtual,於是運行時要從繼承鏈中盡量找派生得最遠的虛方法,發現其子類SubDerivedClass重寫了這個方法,於是從SubDerivedClass繼續往下找,找到SuperDerivedClass時,發現SuperDerivedClass覆蓋了這個方法,沒有重寫,所以最終執行SubDerivedClass的displayName方法。

 

baseClass.displayName();

clip_image005

在BaseClass中displayName是個虛方法,於是它要試圖找派生的最遠的虛方法。但找到DerivedClass就發現,DerivedClass已經把displayName覆蓋了,這條虛鏈於是就斷了。所以就直接執行BaseClass的方法了。

 

注意:

如果把SubDerivedClass的override去掉,則試圖在SuperDerivedClass中寫public override void displayName()是編譯不過的。因為雖然在DerivedClass中有虛的displayName可供子類override,但由於SubDerivedClass中的DerivedClass沒有加override,這相當於SubDerivedClass覆蓋了DerivedClass的displayName方法,而非override了它,於是在SuperDerivedClass看到的displayName,其實是SubDerivedClass的dislayName,是一個非虛的方法,而不是從DerivedClass傳承下來的虛方法,所以不能override

 

總結

若一個類中有一個方法,則只在兩種情況下該方法才會是一個虛方法。

1:該方法用virtual定義。

2:該類的父類中有一個同名的虛方法,在該類中用override關鍵字重寫了父類的虛方法。

 

子類要想“重寫”而非“覆蓋”父類的方法,要滿足兩個條件。

一:“父類方法是虛方法。(這意味著該方法或者是有virtual標記的,或者是override它的父類的。)”。

二:“子類中有override標記”。

這二者缺一,則意味著子類是對父類的方法進行了“覆蓋”,而非“重寫”。

 

如果一個方法是虛方法(),則運行時從找那個“重寫”得最遠的方法來執行。一旦遇到“覆蓋”,則繼承鏈就斷掉了。

 

    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved