深入理解C#之繼承
C#之繼承
繼承、封裝和多態(tài)是面向?qū)ο缶幊痰闹匾匦浴?/p>
其成員被繼承的類叫基類也稱父類,繼承其成員的類叫派生類也稱子類。
派生類隱式獲得基類的除構(gòu)造函數(shù)和析構(gòu)函數(shù)以外的所有成員。派生類只能有一個(gè)直接基類,所以C#并不支持多重繼承,但一個(gè)基類可以有多個(gè)直接派生類。
繼承是可以傳遞的。
即:如果 ClassB 派生出 ClassC,ClassA 派生出 ClassB,則 ClassC 會(huì)繼承 ClassB 和 ClassA 中聲明的成員。
class A
{
public void Sum(int i,int j)
{
int sum = i + j;
Console.WriteLine("I am A ,my sum ={0}",sum);
}
}
class B : A
{
public void Minus(int i,int j)
{
int minus = i - j;
Console.WriteLine("I am B ,my minus ={0}", minus);
this.Sum(3, 4);
}
}
class InheritanceTest1
{
static void Main(string[] args)
{
B b = new B();
b.Minus(3, 4);
Console.Read();
}
}
結(jié)果:
I am B ,my minus=-1
I am A ,my sum = 7
試想一下,當(dāng)基類Sum()方法是私有時(shí),派生類還會(huì)繼承該方法嗎?
經(jīng)過本人測(cè)試,沒有在B類找到該方法,那么是不是它就沒有被繼承呢?其實(shí)不是的,私有成員其實(shí)已經(jīng)被繼承了,但是它們卻不可以被訪問,因?yàn)樗接谐蓡T只能被聲明它們的類或結(jié)構(gòu)體中才可訪問,所以看上去像是沒有被繼承。
如果我們想降低訪問基本,我們可以把基類Sum()方法定義為protected。
能夠阻止某個(gè)類被其他類繼承嗎?
答案是可以的,C#提供了一個(gè)sealed 修飾符,此修飾符會(huì)阻止其他類從該類繼承。
sealed class A
{
int test;
public void Sum(int i,int j)
{
int sum = i + j;
Console.WriteLine("I am A ,my sum ={0}",sum);
}
}
class B : A
{
public void Minus(int i,int j)
{
int minus = i - j;
Console.WriteLine("I am B ,my minus ={0}", minus);
this.Sum(3, 4); //編譯器會(huì)報(bào)錯(cuò)
}
}
前面說過,派生類隱式獲得基類的除構(gòu)造函數(shù)和析構(gòu)函數(shù)以外的所有成員。
那么我們?cè)撊绾潍@得基類的構(gòu)造函數(shù)和自身的構(gòu)造函數(shù)呢?
我們知道基類的初始化工作由基類的構(gòu)造函數(shù)完成,派生類的初始化工作則有派生類的構(gòu)造函數(shù)完成,但是這樣就產(chǎn)生了派生類構(gòu)造函數(shù)的執(zhí)行順序問題。
當(dāng)基類沒有構(gòu)造函數(shù),派生類也沒有構(gòu)造函數(shù)時(shí),派生類新曾成員的初始化工作由其他公有函數(shù)來完成。
public class A
{
int test=0;
public void sum()
{
test++;
Console.WriteLine("I am test ={0}" ,test);
}
}
class B : A
{
int i;
public void PrintInt()
{
i = 3;
Console.WriteLine("I am i ={0}", i);
}
}
class InheritanceTest1
{
static void Main(string[] args)
{
B b = new B();
b.PrintInt();
Console.Read();
}
}
結(jié)果:
I am i=3
如果只有派生類定義構(gòu)造函數(shù)時(shí),只需構(gòu)造派生類對(duì)象即可。對(duì)象的基類部分使用默認(rèn)構(gòu)造函數(shù)來自動(dòng)創(chuàng)建。當(dāng)基類和派生類
都定義有構(gòu)造函數(shù)時(shí),那么執(zhí)行順序會(huì)怎樣呢?
如果基類中是沒有參數(shù)的構(gòu)造函數(shù),那么他可以隱式的被派生類執(zhí)行,也就是說,派生類根本不需要包含構(gòu)造函數(shù)如果基類中是沒有參數(shù)的構(gòu)造函數(shù),在派生類中可以自定義有參數(shù)的構(gòu)造函數(shù)publicclassA
public class A
{
int test=0;
public A()
{
test = 5;
Console.WriteLine("I am A 公有默認(rèn)構(gòu)造函數(shù) ,test={0}", test);
}
}
class B : A
{
}
class InheritanceTest1
{
static void Main(string[] args)
{
B b = new B();
Console.Read();
}
}
結(jié)果:
I am A 公有默認(rèn)構(gòu)造函數(shù) ,test=5
由此可以看見,基類的構(gòu)造函數(shù)被執(zhí)行,在派生類中被調(diào)用。
如果基類定義了帶有參數(shù)的構(gòu)造函數(shù),那么此構(gòu)造函數(shù)必須被執(zhí)行,且在派生類中實(shí)現(xiàn)該構(gòu)造函數(shù),此時(shí)我們可以使用base關(guān)鍵字
class A
{
int test=0;
public A(int i)
{
test = i;
Console.WriteLine("I am A 公有有參構(gòu)造函數(shù) ,test={0}", test);
}
}
class B : A
{
public B(int j):base(j)
{
Console.WriteLine("I am B 公有有參構(gòu)造函數(shù),j={0}",j);
}
}
class InheritanceTest1
{
static void Main(string[] args)
{
B b = new B(1);
Console.Read();
}
}
結(jié)果:
I am A 公有有參構(gòu)造函數(shù) ,test=1
I am B 公有有參構(gòu)造函數(shù),j=1
由此可見: 派生類隱式執(zhí)行基類中帶有參數(shù)的構(gòu)造函數(shù),在程序中基類定義了帶有參數(shù)的構(gòu)造函數(shù),在其派生類中被繼承,并使用base關(guān)鍵字調(diào)用基類中的構(gòu)造函數(shù)來傳送參數(shù)。
我們可以從代碼中看到在創(chuàng)建派生類的對(duì)象后,程序首先運(yùn)行的是基類的構(gòu)造函數(shù)中的內(nèi)容,然后才是派生類中的內(nèi)容。
如果派生類的基類也是派生類,則每個(gè)派生類只需負(fù)責(zé)其直接基類的構(gòu)造,不負(fù)責(zé)間接基類的構(gòu)造,并且其執(zhí)行構(gòu)造函數(shù)的順序是從最上面的基類開始的,直到最后一個(gè)派生類結(jié)束。
總結(jié)
本篇文章就到這里了,希望可以幫助到你,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C#中的DataTable查詢實(shí)戰(zhàn)教程
這篇文章主要介紹了C#中的DataTable查詢實(shí)戰(zhàn)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01
C# Websocket連接實(shí)現(xiàn)wss協(xié)議
本文主要介紹了C# Websocket連接實(shí)現(xiàn)wss協(xié)議,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
C#實(shí)現(xiàn)在前端網(wǎng)頁(yè)彈出警告對(duì)話框(alert)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)在前端網(wǎng)頁(yè)彈出警告對(duì)話框(alert)的方法,涉及C#通過自定義函數(shù)調(diào)用window.alert方法彈出對(duì)話框的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
C#實(shí)現(xiàn)在PDF文檔中應(yīng)用多種不同字體
在PDF文檔中,可繪制不同字體樣式、不同語(yǔ)言的文字,可通過使用Standard字體、TrueType字體、CJK字體或者自定義(私有)等字體類型。本文將具體介紹實(shí)現(xiàn)的方法,需要的可以參考一下2022-01-01
詳解ObjectARX開發(fā)環(huán)境的創(chuàng)建與開發(fā)實(shí)例Hello World(VS2005+AutoCad2008+Object
這篇文章主要介紹了ObjectARX開發(fā)環(huán)境的創(chuàng)建與開發(fā)實(shí)例Hello World(VS2005+AutoCad2008+ObjectArx2008),本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
聊聊C# 中HashTable與Dictionary的區(qū)別說明
這篇文章主要介紹了聊聊C# 中HashTable與Dictionary的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01
c#中實(shí)現(xiàn)圖片灰度化技術(shù)詳解
這篇文章主要介紹了c#中實(shí)現(xiàn)圖片灰度化技術(shù)詳解,本文給出計(jì)算公式和實(shí)現(xiàn)代碼以及圖片例子,需要的朋友可以參考下2014-08-08

