1. 程式人生 > >深入繼承續——虛方法、override 、new

深入繼承續——虛方法、override 、new

虛方法

virtual關鍵字用於修飾方法、屬性、索引器或事件宣告,並且允許在派生類中重寫這些物件。例如,此方法可被任何繼承它的類重寫。

當類中的方法宣告前加上了virtual修飾符,我們稱之為虛方法,反之為非虛。    
 若希望或預料到基類的這個方法在將來的派生類中會被重寫(override ),則此方法必須被宣告為 virtual。

呼叫虛方法時,將為重寫成員檢查該物件的執行時型別。將呼叫大部分派生類中的該重寫成員,如果沒有派生類重寫該成員,則它可能是原始成員。

預設情況下,方法是非虛擬的。不能重寫非虛方法。

virtual修飾符不能與staticabstract, private

override修飾符一起使用。

除了宣告和呼叫語法不同外,虛擬屬性的行為與抽象方法一樣。

·        在靜態屬性上使用virtual修飾符是錯誤的。

·        通過包括使用override修飾符的屬性宣告,可在派生類中重寫虛擬繼承屬性。

虛方法的定義形式

virtual 修飾符 返回的資料型別方法名(引數表)

{

    方法體

}

對於非虛的方法,無論被其所在類的例項呼叫,還是被這個類的派生類的例項呼叫,方法的執行方式不變。而對於虛方法,它的執行
方式可以被派生類改變,這種改變是通過方法的過載來實現的。

虛方法的過載形式

override 修飾符 返回的資料型別方法名(引數表)

{

    方法體

}

override 重寫繼承自基類的 virtural 方法,可以理解為拆掉老房子,在原址上建新房子,老房子再也找不到了(基類方法永遠呼叫不到了)。

New和override的異同

 new和override的相同點:

 都可以對基類成員進行隱藏,都可以用base關鍵字呼叫基類的成員 

 new和override的不同點:

 用override的基類的方法必須要用virtual,而new不必要

 本質區別在於當派生類物件作為基類型別使用時,override 的執行派生類方法,new 的執行基類方法。如果作為派生類型別呼叫,則都是執行 override 或 new 之後的。

  override 重寫繼承自基類的 virtural 方法,可以理解為拆掉老房子,在原址上建新房子,老房子再也找不到了(基類方法永遠呼叫不到了)。

   new 隱藏繼承自基類的 virtual 方法,老房子還留著,在旁邊蓋個新房,想住新房住新房(作為派生類物件呼叫),想住老房住老房(作為基類物件呼叫)。

   當派生類中出現與基類同名的方法,而此方法前面未加 override 或 new 修飾符時,編譯器會報警告,但不報錯,真正執行時等同於加了 new。

下面是程式碼實現:

 public interface I_9_A
    {
        int Age { get;set;}
        string GetName();
        string GetPwd();
    }
    /// <summary>
    /// 下面這個類繼承了A介面,並實現了裡面的全部成員
    /// </summary>
    public class I_9_L_1 : I_9_A
    {
        protected int age;
        protected string name;
        protected string pwd;

        public I_9_L_1()
        {
            age = 28;
            name = "提高班";
            pwd = "tgb";
        }

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public string GetName()
        {
            return name;
        }
        public string GetPwd()
        {
            return pwd;
        }
    }
    public class I_9_L_2 : I_9_L_1
    {
        public new string GetName()
        {
            return ":" + name;
        }
        public new string GetPwd()
        {
            return "密碼:" + pwd;
        }
    }

    /**當我們看了上面的演示以後會發現一個很嚴重的問題,
     * 我們明明就呼叫的2這個類,可為什麼方法卻依然是1哪個類的呢?
     * 原因就在2這個類雖然是複寫了1類中的方法,但是他並沒有去改寫1類中的方法
    **/
    ///////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// 下面這個類繼承了A介面,並實現了裡面的全部成員
    /// </summary>
    public class I_9_L_3 : I_9_L_1
    {
        protected int age;
        protected string name;
        protected string pwd;

        public I_9_L_3(int a, string n, string p)
        {
            age = a;
            name = n;
            pwd = p;
        }

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public virtual string GetName()
        {
            return name;
        }
        public virtual string GetPwd()
        {
            return pwd;
        }
    }
    public class I_9_L_4 : I_9_L_3
    {
        public I_9_L_4(int a, string n, string p)
            : base(a, n, p)
        {
            age = a;
            name = n;
            pwd = p;
        }
        public override string GetName()
        {
            return "我是:" + name;
        }
        public override string GetPwd()
        {
            return "密碼是:" + pwd;
        }
    }

    /**
     * 其實這個例題理解起來不難的,首先我們知道他整個的執行順序
     * 然後就是,如果發現不是虛方法,那麼就直接呼叫了,但是如果是他就會繼續往下找,一直找到不是虛的位置.
     * 
     * 我們這個例題說完了,不知道你有沒有想起我們前面說過的一個問題,就是顯示實現的無法使用修飾符,
     * 既然不能使用修飾符,那virtual也沒法用,難道顯示實現的方法就不能使用虛方法了嗎?
     * 
     * 答案是否定的,呵呵
     * 
     * 我們可以在這個顯示實現中呼叫另一個方法嘛,哈哈,然後這個被呼叫的方法再是虛方法,我想法律不會不允許吧
     * **/
    ///////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// 下面這個類繼承了A介面,並實現了裡面的全部成員
    /// </summary>
    public class I_9_L_5 : I_9_A
    {
        protected int age;
        protected string name;
        protected string pwd;

        public I_9_L_5(int a, string n, string p)
        {
            age = a;
            name = n;
            pwd = p;
        }

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public string GetName()
        {
            return name;
        }
        public string GetPwd()
        {
            return pwd;
        }
    }
    public class I_9_L_6 : I_9_L_5,I_9_A
    {
        public I_9_L_6(int a, string n, string p)
            : base(a, n, p)
        {
            age = a;
            name = n;
            pwd = p;
        }
        public  string GetName()
        {
            return "我是:" + name;
        }
        public string GetPwd()
        {
            return "密碼是:" + pwd;
        }
    }
}

---------------------------原文參考CSDN和天轟穿視訊


相關推薦

深入繼承——方法override new

虛方法 virtual關鍵字用於修飾方法、屬性、索引器或事件宣告,並且允許在派生類中重寫這些物件。例如,此方法可被任何繼承它的類重寫。 當類中的方法宣告前加上了virtual修飾符,我們稱之為虛方法,反之為非虛。      若希望或預料到基類的這個方法在將來的派生類中會被

c# base和this的區別(basethisvirtualoverridestatic詳解)

今天的程式除錯中出現了以下錯誤,引發了我對base關鍵字的用法的疑惑,總結一下。 1、base關鍵字 用法1: base是為了實現子類的方法中實現父類原有的方法。 this關鍵字代表本類物件,base關鍵字代表父類物件。     如: base.pr

C++ overloadoverrideoverwrite

對於函式的過載(overload)、覆蓋(override)、重寫(overwrite)三者的理解,通過程式碼來分析。 過載:是指同一可訪問區內被宣告的幾個具有不同引數列(引數的型別,個數,順序不同)的同名函式,根據引數列表確定呼叫哪個函式,過載解析中不考慮返

類的繼承publicprotectedprivateparent重寫override最終類和最終方法

一、類的繼承 簡單定義:某個類A具有某些特徵,另一個類B,也具有A類的所有特徵,並且還可能具有自己的更多的一些特徵,此時,我們就可以實現:B類使用A的特徵資訊並繼續新增自己的一些特有特徵資訊。 基本概念   繼承:一個類從另一個已有的類獲得其特性,稱為繼承。   派生:

接口抽象類抽象方法方法總結

blog 方法 實例 類名 class 訪問修飾符 檢查 spa code 一、接口   1、定義     1.1、訪問修飾符 interface 接口名{成員可以為屬性、方法、事件、索引器}     1.2、示例代碼     public delegate void D

Java:驗證在類繼承過程中equals() hashcode()toString()方法的使用

red ger 輸出 ria oid nag println manage base 以下通過實際例子對類創建過程匯中常用的equals()、hashcode()、toString()方法進行展示,三個方法的創建過程具有通用性,在項目中可直接改寫。 //通過超類Employ

方法抽象方法接口方法

需要 沒有 類方法 nbsp 類的方法 bst ide ride 抽象方法 1.virtual方法(虛方法) virtual方法用於在基類中修飾子類,會遇到下面2種情況: 情況1:子類沒有重寫,則子類調用的是基類的方法。 情況2:子類重寫了,則子類調用的重寫的方法。

C++ 在繼承函數函數普通函數,三者的區別

pre 沒有 實例 space 自己的 img 引用 虛函數 public 源地址:http://www.cnblogs.com/xudong-bupt/p/3570304.html 1.虛函數(impure virtual)   C++的虛函數主要作用是“運行時多態”,父

day4(繼承修飾符方法的重寫super關鍵詞繼承中的構造方法object類對象轉型)

編程 權限 數列 als str list 兩個 instance 變量 1.類的繼承(extends)通過繼承,子類自動擁有父類的所有成員(成員變量和成員發方法)一個子類只能有一個父類,一個父類可以派生多個子類 2.訪問修飾符(private 默認 protected

抽象類和方法base關鍵字

nbsp 完成 多態性 com soft 共享 log rac 返回 微軟官方文檔:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract-a

析構函數私有方法繼承;環境部署;多線程多進程;鎖

turn cme 網絡io 變量 配置 磁盤io 入參 屬性 tom 1.析構函數、私有、類方法、屬性方法、靜態方法class My: def __init__(self): print(‘構造函數,類在實例化的時候會自動執行他‘) def __d

CLR via C#學習筆記-第六章-CLR如何調用方法屬性和事件

style err rri 實參 寫代碼 調查 pre 好的 屬性 6.6.1 CLR如何調用虛方法、屬性和事件 本節重點是方法,但討論也與虛屬性和虛事件密切相關。屬性和事件實際作為方法實現,以後的章節會討論他們。 方法 方法代表在類型或類型的實例上執行某些操作的代碼。

C#中的方法抽象方法抽象類以及接口

狀態 設置 基本 簡單的 語言 pre 語法 區別 自動生成 眾所周知,C#作為一門OOP(面向對象程序設計)語言,在許多地方都有與C++相似的地方,然而也有很多不同的地方。 說到面向對象,腦袋裏第一反應當然就是面向對象的三大原則(java中是四大原則): 封裝、繼承、多態

C#中的方法抽象方法抽象類介面的聯絡與區別

虛方法的關鍵字是virtual抽象方法的關鍵字是abstract重寫都是override 虛方法也可以new虛方法和抽象方法的區別:虛方法:可以在抽象類和非抽象類中定義,可以寫在父類中,在子類中可以被重寫,在定義虛方法時必須實現虛方法 (在定義虛方法時需要寫實現方法的程式碼或者至少

Java中的繼承方法覆蓋(方法重寫)super關鍵字

Java繼承 繼承 繼承是面向物件的一個重要的特性,它體現了類與類之間的一些邏輯關係,目的是為了程式碼複用(以減少開發成本)。當多個類之間有一些共同的屬性(成員變數)和功能(成員方法)時,我們可以將他們共同的部分拿出來作為一個父類定義實現這些共性,這些類中可以不再定義這

JAVA中方法抽象方法例項方法靜態方法的辨別

抽象方法 抽象方法是用abstract修飾的方法,只能宣告不能實現,抽象方法必須被宣告在抽象類裡(反過來,抽象類裡不一定要有抽象方法),抽象方法的的作用就是強制子類實現該抽象方法(如果子類不是抽象類的話)。 例項方法 可以用物件引用呼叫的方法都可以稱作例項方法,例項方法必須在物件例項化之後,通過物件引用

當沒有繼承關係時,靜態塊靜態方法非靜態方法構造方法普通方法的執行順序

<span style="font-size:18px;">package test; /** * 不含有繼承時,各種方法(靜態塊,靜態方法,非靜態程式碼塊,構造方法,普通方法)的執行順序 * */ public class uExt

C#多型的實現:方法抽象類介面

一、多型的概念         多型簡單講就是一個類針對同一個方法可以表現出多種不同的形態。舉例:動物類有個叫的方法,通過多型當呼叫動物類叫的方法時,根據動物類物件實際存放子物件的不同,則表現出不同的叫聲,有可能是人叫、也有可能是狗叫、也有可能是貓叫等等。 二、多型的

子類與父類之間的方法過載隱藏重寫與方法呼叫

由於子類物件同時“彙集了”父類和子類的所有公共方法,如果子類中某個方法與父類方法的簽名一樣(即方法名和方法引數都一樣),那當通過子類物件訪問此方法時,訪問的是子類還是父類所定義的方法? 總的來說,子類方法與父類方法之間的關係可以概括為以下三種。    擴充(Extend):

C#方法過載(overload)重寫(覆蓋)(override隱藏(new

轉載地址:https://blog.csdn.net/u010926964/article/details/20719951  過載、重寫、隱藏這三個概念對於很多人都不是很清晰,我也是差了很多資料又請教師哥才感覺能理解了,有不足之處還請老師同學們批評指正!