最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#子類對基類方法的繼承、重寫與隱藏詳解

 更新時(shí)間:2020年07月26日 09:20:09   作者:老胡寫代碼  
這篇文章主要介紹了C#子類對基類方法的繼承、重寫與隱藏的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

提起子類、基類和方法繼承這些概念,肯定大家都非常熟悉。畢竟,作為一門支持OOP的語言,掌握子類、基類是學(xué)習(xí)C#的基礎(chǔ)。不過,這些概念雖然簡單,但是也有一些初學(xué)者可能會(huì)遇到的坑,我們一起看看吧。

子類繼承基類非私有方法

首先我們看最簡單的一種,子類繼承自基類,但子類對繼承的方法沒有任何改動(dòng)

class Person
{
 public void Greeting()
 {
 Console.WriteLine("Hello, I am Person");
 }
}

class Employee : Person
{

}

class Program
{
 static void Main(string[] args)
 {
 Person p = new Employee();
 p.Greeting();
 }
}

在這個(gè)例子中,作為子類的Employee自動(dòng)繼承了基類的Greeting方法,當(dāng)在子類實(shí)例調(diào)用這個(gè)方法的時(shí)候,實(shí)際上調(diào)用的是基類的方法。這個(gè)例子非常簡單,毋庸多言。 

子類覆蓋基類方法

接著是最常見的情況,子類覆蓋基類的方法,典型的例子如下

class Person
{
 public virtual void Greeting()
 {
 Console.WriteLine("Hello, I am Person");
 }
}

class Employee : Person
{
 public override void Greeting()
 {
 Console.WriteLine("Hello, I am Employee");
 }
}

class Program
{
	static void Main(string[] args)
	{
		Employee e = new Employee();
		Person p = e;
		p.Greeting();
		e.Greeting();
	}
}

同樣,這段代碼也很簡單,基類方法通過關(guān)鍵字virtual表明方法可以被覆蓋,子類通過關(guān)鍵字override實(shí)現(xiàn)對基類方法的覆蓋,最后看調(diào)用部分,無論變量類型是子類還是基類,只要對象實(shí)際類型是子類,調(diào)用的方法都是子類覆蓋的方法,這也是多態(tài)的實(shí)現(xiàn)基礎(chǔ)。 

子類隱藏基類方法

上面兩個(gè)例子都非常簡單,邏輯也很清楚,有點(diǎn)繞的要算子類隱藏基類方法的情況。

子類隱藏基類的非虛方法

基類被子類繼承的方法可能是虛方法,也可能是非虛方法,先看非虛方法被子類隱藏的情況,隱藏基類方法使用的關(guān)鍵字是new

class Person
{
 public void Greeting()
 {
 Console.WriteLine("Hello, I am Person");
 }
}

class Employee : Person
{
 public new void Greeting()
 {
 Console.WriteLine("Hello, I am Employee");
 }
}

class Program
{
 static void Main(string[] args)
 {
 Employee e = new Employee();
 Person p = e;
 p.Greeting();
 e.Greeting();
 }
}

這里的結(jié)果可能就出乎某些初學(xué)者的意料了,為什么明明是子類Employee的實(shí)例,卻在不同的引用變量類型下呈現(xiàn)出了不一樣的效果?為什么會(huì)調(diào)用到了基類里面的方法?
其實(shí)這跟C#的函數(shù)調(diào)用機(jī)制有關(guān),一般來說,C#編譯成MSIL之后,有兩種函數(shù)調(diào)用方式。

  • Call 以非虛的方式調(diào)用方法,一般用于靜態(tài)函數(shù)調(diào)用,因?yàn)殪o態(tài)函數(shù)不可能是虛的,但也可以以非虛的方式調(diào)用一個(gè)虛方法
  • Callvirt 以虛方式調(diào)用,一般用于非靜態(tài)方法和虛方法的調(diào)用。如果調(diào)用的方法非虛,則引用變量類型決定了最終調(diào)用的方法;反之,如果調(diào)用的方法為虛,則實(shí)例變量類型決定最終調(diào)用的方法——因?yàn)榭赡艹霈F(xiàn)方法重寫,即,多態(tài)

用ILDASM打開我們的程序集看看,

證明了這里確實(shí)是用的Callvirt,而這個(gè)方法是非虛的方法,所以在兩次調(diào)用中,引用變量類型Person和Employee就能夠決定所調(diào)用的方法。兩個(gè)類分別實(shí)現(xiàn)了自己的Greeting方法,沒有出現(xiàn)子類覆蓋基類方法的情況。這就解釋了為什么兩次調(diào)用結(jié)果不同。最后讓我們來看看最復(fù)雜的一種情況 

子類隱藏基類的虛方法

考慮下面的代碼

class Person
{
 public virtual void Greeting()
 {
  Console.WriteLine("Hello, I am Person");
 }
}

class Employee : Person
{
 public new virtual void Greeting()
 {
  Console.WriteLine("Hello, I am Employee");
 }
}

class Manager : Employee
{
 public override void Greeting()
 {
  Console.WriteLine("Hello, I am Manager");
 }
}

class Program
{
 static void Main(string[] args)
 {
  Manager m = new Manager();
  Person p = m;
  Employee e = m;
  p.Greeting();
  e.Greeting();
  m.Greeting();
 }
}

猜一下輸出應(yīng)該是什么?這也是老胡曾經(jīng)遇到過的一道筆試題,表面看著簡單,但是不注意也會(huì)掉坑里

1,2,3,答案揭曉

是不是有點(diǎn)出乎意料呢,讓我們來分析一下

首先,三次調(diào)用均是callvirt,而且方法Greeting是虛方法,我們需要考慮對象實(shí)例以決定要調(diào)用的方法。

  • 在第一次調(diào)用中,引用變量類型是Person,雖然對象實(shí)例類型Manger重寫了Greeting方法,但是它重寫的是繼承自Manger基類Emplyee的Greeting方法,Person中Greeting方法在子類Manger中僅僅是被隱藏而沒有被重寫,所以這里調(diào)用的是Person中的Greeting
  • 而第二次調(diào)用中,引用變量類型是Employee,Employee的Greeting方法被Manager重寫,所以這次調(diào)用到的是Manager中的Greeting
  • 最后一次調(diào)用毋庸多言,簡單的重寫案例而已

怎么樣,是不是有小伙伴猜錯(cuò)結(jié)果了? 

總結(jié)

在子類對基類有方法繼承、重寫和隱藏的情況下,有時(shí)候判斷具體哪個(gè)方法被調(diào)用會(huì)有難度,但請記住以下要點(diǎn):

如果被調(diào)用方法非虛,那么只用關(guān)注引用變量類型就好,引用變量類型能決定調(diào)用方法在哪里如果調(diào)用方法為虛,我們需要站在引用變量類型的角度,審視該方法是否被對象類型所重寫;若是,則調(diào)用對象類型的重寫方法;反之,則再次讓引用變量類型決定調(diào)用方法。

這樣,當(dāng)我們再遇到子類隱藏基類虛方法的情況,應(yīng)用以上要點(diǎn)就可以撥云見日。

到此這篇關(guān)于C#子類對基類方法的繼承、重寫與隱藏的文章就介紹到這了,更多相關(guān)C#子類對基類方法繼承、重寫與隱藏內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C# 排序算法之堆排序

    C# 排序算法之堆排序

    這里是指一種數(shù)據(jù)結(jié)構(gòu),而不是我們在C#中提到的用于存儲引用類型對象的地方。它可以被當(dāng)成一棵完全二叉樹。
    2010-09-09
  • 使用C#編寫兩個(gè)漂亮?xí)r鐘的示例代碼

    使用C#編寫兩個(gè)漂亮?xí)r鐘的示例代碼

    這篇文章主要為大家分享了兩個(gè)使用C#編寫的兩個(gè)漂亮?xí)r鐘的示例代碼,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-07-07
  • C#繪制鼠標(biāo)指針的示例代碼

    C#繪制鼠標(biāo)指針的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)將鼠標(biāo)的指針樣式給繪制成圖片,顯示或者保存下來,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2024-01-01
  • 舊項(xiàng)目升級新版Unity2021導(dǎo)致Visual?Studio無法使用的問題

    舊項(xiàng)目升級新版Unity2021導(dǎo)致Visual?Studio無法使用的問題

    在項(xiàng)目開發(fā)過程中,不可避免的會(huì)升級開發(fā)工具。這次我在舊項(xiàng)目版本升級到新版Unity2021.2.x時(shí),出現(xiàn)Visual?Studio無法定位等問題,這里我給大家分享下解決方法,舊項(xiàng)目升級新版Unity2021導(dǎo)致Visual?Studio無法使用的問題,需要的朋友可以參考下
    2021-12-12
  • C# XML序列化方法及常用特性總結(jié)分析

    C# XML序列化方法及常用特性總結(jié)分析

    這篇文章主要介紹了C# XML序列化方法及常用特性,總結(jié)分析了C# xml序列化的實(shí)現(xiàn)方法及序列化常用Attribute含義與功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • C#強(qiáng)制類型轉(zhuǎn)換小結(jié)

    C#強(qiáng)制類型轉(zhuǎn)換小結(jié)

    任何一門編程語言均有相關(guān)數(shù)據(jù)類型。C#也不例外,不過轉(zhuǎn)換過程要注意小類型能轉(zhuǎn)換成大類型,但大類型一般不能轉(zhuǎn)換成小類型,下面小編給大家詳解C#強(qiáng)制類型轉(zhuǎn)換小結(jié),需要的朋友參考下吧
    2017-07-07
  • WCF實(shí)現(xiàn)的計(jì)算器功能實(shí)例

    WCF實(shí)現(xiàn)的計(jì)算器功能實(shí)例

    這篇文章主要介紹了WCF實(shí)現(xiàn)的計(jì)算器功能,結(jié)合具體實(shí)例形式較為詳細(xì)的分析了WCF實(shí)現(xiàn)計(jì)算器功能的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • C# RSA分段加解密實(shí)現(xiàn)方法詳解

    C# RSA分段加解密實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了C# RSA分段加解密實(shí)現(xiàn)方法,結(jié)合具體實(shí)例形式分析了C# RSA加密解密的原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • C#之字符串截取--Regex.Match使用

    C#之字符串截取--Regex.Match使用

    這篇文章主要介紹了C#之字符串截取--Regex.Match使用解讀,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • C# DialogResult用法案例詳解

    C# DialogResult用法案例詳解

    這篇文章主要介紹了C# DialogResult用法案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評論

安平县| 原阳县| 房产| 洛浦县| 拉萨市| 汶上县| 松滋市| 澜沧| 朔州市| 宝坻区| 莫力| 都江堰市| 罗山县| 平远县| 名山县| 武夷山市| 桐庐县| 华蓥市| 利辛县| 二连浩特市| 龙川县| 绥德县| 泾源县| 星子县| 思南县| 基隆市| 固镇县| 鄱阳县| 子长县| 信阳市| 育儿| 柘荣县| 博野县| 北票市| 黔南| 石河子市| 潜江市| 北碚区| 修武县| 基隆市| 喀喇沁旗|