深入繼承 - 抽象類和接口
首先我們給出抽象類和接口的概念,大家可以把視頻暫停下來記錄一下.
抽象類:又叫抽象基類(不是雞肋):他在定義的時候使用 abstract 關(guān)鍵字標記的一般類.他可包含一般類所包含的所有特性,例如,字段,屬性,方法,另外他還包含一個很特殊的方法,叫抽象方法(這些方法基本上是沒有執(zhí)行代碼的函數(shù)標題,而派生于該類的的類就必須提供執(zhí)行的代碼).最可氣的是,他不能被實例化,他主要的用在類的定義和部分實現(xiàn)這方面,所以他需要在擴充類中完整的擴充并實現(xiàn)功能.
抽象方法: 當(dāng)類中的方法在聲明的時候加上 abstract 關(guān)鍵字的時候,他就被我們稱為抽象方法(洋名字叫 abstract method , 其實偷偷告訴你哈,我最近學(xué)了好多英文單詞,雖然還是常常讀錯,但是已經(jīng)有很大進步了,估計要不了多久就可以在那里大聲朗讀李白曾經(jīng)寫過的一首英文詩歌了),但是有個很重要的提醒,只有在抽象類和接口中才可以使用抽象方法.
例如 : 下面這個
public abstract class Thc123_Com
{
public abstract void GoTo();
}
public class Thc123_Net : Thc123_Com
{
public override void GoTo()
{
//實現(xiàn)上面抽象方法
}
}
=========================================================================================
在講接口之前呢我又想跟大家吹下牛, 大家知道我們的組裝計算機,即便是那些品牌機他實際上也是來自很多不同的廠商然后組裝起來的, 那么這寫硬件之間就有一個必然的聯(lián)系,那就是他們之間一定要有規(guī)范的接口,可是就拿我們的主板來說吧,這個CPU,他既可以是賽陽的,也可以是奔騰的,更可以是速龍,閃龍,當(dāng)然我跟特別非常十分希望再加上一個咱們中國的CPU品牌,這些CPU肯定采用了一些不同的運算方式啊,所以說我們這個接口就還要學(xué)會一點(我們常常勸老人的話,他只要在孝順你,你就別關(guān)他那么多的家務(wù)事),說得太好了,我們的接口還要做的事就是不管對方是怎么實現(xiàn)的,反正你插到這里面((*&^#@*&^%$%^$$#$)你就要實現(xiàn)具體的功能,至于你怎么實現(xiàn)就不管那么多了.
接口:他呢其實也是一種特殊的抽象類,用 interface 關(guān)鍵字標記,他的定義沒有 class 關(guān)鍵字,他可以包含 方法和屬性和事件,但是方法也只能是虛擬方法,任何派生于該接口的類就必須提供執(zhí)行的代碼.任何接口成員前面都不能加修飾符.
接口可用的修飾符有 new , public ,protected , internal , private ,但是同一聲明中修飾符只能有一個,new關(guān)鍵字只能出現(xiàn)在鑲套接口中,表示復(fù)寫繼承來的同名成員.
接口和類一樣,可以被繼承和發(fā)展,但不同的是,類繼承不僅說明繼承也會實現(xiàn)繼承,但是接口繼承只是說明繼承,通俗的說,派生類可以繼承基類的方法實現(xiàn),而派生接口只是繼承父接口的方法說明,卻沒有繼承父接口的實現(xiàn).
語法:
interface Ibook
{
string GetBookName();
}
接口相關(guān)知識:
1.聲明在接口中的方法,不可以包含方法的內(nèi)容區(qū)塊,簡單來說就是不能有大括號存在,例如下面
public interface Ibook
{
string GetBookName()
{ }
}
2. 實現(xiàn)接口的類就要這樣寫
public class Employee:Ibook , IUser
{
}
3 . 實現(xiàn)接口需要注意的一些東東
(1).實現(xiàn)一個接口就必須完成接口里的所有方法.(就好象誰家有幾個女兒,有漂亮的有對不起觀眾的,我要去娶那個漂亮的,然后人家開口了,小伙子,你要娶我女兒可以,但是你必須把幾個女兒全部娶了,否則我會讓你后悔一輩子. )
(2).在實現(xiàn)的類中又有幾點必須遵循的(我倒,都三重編號了,看來我寫的書后期編輯是件很棘手的事)
·存取權(quán)限必須相同 ;
·返回值類型必須相同
·方法的名稱必須相同
·參數(shù)必須相同
(3) . 接口內(nèi)的方法不能用 virtual 關(guān)鍵字申明,更不要設(shè)置存取權(quán)限.
下面我們繼續(xù)來看下個例題
另外還有一種呢就是以明確的方式實現(xiàn)接口
簡單來說就是方法前面必須加上接口的名稱.這個解釋起來沒有看起來明確,來吧,看這里(怎么聽這話有點怪怪的,難道是我思想不健康,按理說我算是生在陽光下,長在花叢中(不過18歲以后我就基本上是成長在一群 花蟲 中了),沒理由思想會這么XX啊.)
下面針對抽象類和接口做一個詳細的對比
virtual: 這個關(guān)鍵字表示當(dāng)前方法、屬性、索引器或事件的抽象實現(xiàn)或虛實現(xiàn)可被任何派生自這個類的擴充類進行復(fù)寫.
override: 表示當(dāng)前方法已經(jīng)改寫了基類的同名同參數(shù)的方法、屬性、索引器或事件的抽象實現(xiàn)或虛實現(xiàn).
==============================下面是相關(guān)的代碼=================================
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
![]()
/// <summary>
/// 為了演示顯得更簡單,我從一C#設(shè)計模式書中的例題精簡了一下
/// 說心理話,做這級教程真的算是把我折磨夠了,我總試圖用一個簡單的例題同時說明
/// 在什么地方用他最合適,該怎么用,可是簡單了就感覺不出為什么需要用
/// 復(fù)雜了吧,我口才又不佳,感覺說不清楚,把主題都搞偏離了.很郁悶
/// </summary>
public abstract class vehicle
{//首先我們定義一個抽象的汽車基類
![]()
public int chelun; //車輪
public float zhongliang;
![]()
public vehicle(int cl,float zl)
{
chelun = cl;
zhongliang = zl;
}
public abstract string GetMore();
//定義一個抽象方法
}
public class car : vehicle
{//定義一個轎車類,繼承自vehicel ,所以他必須實現(xiàn)父類中的所有抽象方法
![]()
public int passeng; //乘客數(shù)量
![]()
public car(int cl, float zl, int p)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
}
![]()
public override string GetMore()
{
//return 他的詳細信息
}
}
public class Truck : vehicle
{
public int passeng; //乘客數(shù)量
public float load; //載重
![]()
public Truck(int cl, float zl, int p, float l)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
load = l;
}
public override string GetMore()
{
//return 卡車的全部信息
}
}
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
![]()
using I_B;
![]()
![]()
public partial class demo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
////////////////////////////---接 口 一 演 示---////////////////////////
Book b = new Book("人性的優(yōu)點");
lbl_bn.Text = GetS(b);
}
private static string GetS(IBook ib)
{//注意到這里,我們給的參數(shù)是我們的接口類型
return ib.BookName;
//這里返回的是我們的接口的屬性
}
![]()
////////////////////////////---接 口 二 演 示---////////////////////////
![]()
protected void Button1_Click(object sender, EventArgs e)
{//接口二的演示
I_2_L i2 = new I_2_L();
i2.A = 5;
lbl_i_2.Text = i2.Count(2, 4).ToString();
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
![]()
![]()
/**
* 大致演示接口的定義和訪問,下面的例題開始詳細的演示每個細節(jié)
* */
namespace I_B
{
![]()
public interface IBook
{
string BookName { get;set;} //聲明接口中的屬性
void InsertToDate(); //聲明接口中的方法
}
![]()
public class Book : IBook
{ //我們聲明這樣一個類,他繼承了接口IBook
![]()
string bookname;
![]()
public Book(string bn)
{
bookname = bn;
}
![]()
/// <summary>
/// 實現(xiàn)接口中的BookName屬性
/// </summary>
public string BookName
{
get { return bookname; }
set { bookname = value; }
}
/// <summary>
/// 實現(xiàn)接口中聲明的方法
/// </summary>
public void InsertToDate()
{
//將我們的信息寫如數(shù)據(jù)庫
}
}
![]()
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
![]()
![]()
/**
* 在這個演示中我們主要說明一個問題,就是如果繼承了有父接口的接口,那么也必須實現(xiàn)他全部父接口的方法和屬性
* 這個就是我剛才說娶老婆的哪個問題了,很頭大吧
* **/
![]()
interface I_2_A //聲明第一個接口
{
int A { get;set;} //聲明一個屬性
}
interface I_2_B //聲明第二個接口
{
int Count(int i,int j); //聲明一個方法
}
interface I_2_C : I_2_A, I_2_B { } //聲明第三個接口又繼承了前兩個接口
//什么都沒有聲明。但是他實際上是繼承了前面兩個接口的屬性和方法。
![]()
public class I_2_L : I_2_C //聲明一個類,他繼承了I_2_C這個接口
{
int a;
![]()
public int A
{
get { return a; }
set { a = value; }
}
public int Count(int i, int j)
{
return i * j * a;
}
}
![]()
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
![]()
/**
* 外部對接口的訪問,如果出現(xiàn)同名的參數(shù)或者方法,必須顯示的指出他的父接口。
* 特別是在不清楚具體情況的前提下,最好是做得保守一點。
* **/
![]()
public interface I_3_A
{
int Count { get;set;}
int J(int j);
}
public interface I_3_B
{
void Count(int i);
double J(double j);
}
public interface I_3_C : I_3_A, I_3_B { }
![]()
public class I_3_L
{
public void Sum(I_3_C thc)
{
thc.Count(); //錯誤,具有二義性
thc.Count = 1; //錯誤,具有二義性
thc.Count(1); //錯誤,具有二義性
![]()
![]()
((I_3_A)thc).Count = 1; //正確
((I_3_B)thc).Count(1);
![]()
((I_3_A)thc).J(1);
((I_3_B)thc).J(1);
thc.J(1.0);
thc.J(1);
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
![]()
![]()
/**
* 外部類中對多重繼承中的成員訪問問題
* 感覺上有點繞,實際上一下想通了其實也就簡單了
* **/
![]()
public interface I_4_A
{
string F(string A);
}
public interface I_4_B : I_4_A
{
new string F(string A);
}
public interface I_4_C : I_4_A
{
string T();
}
![]()
/// <summary>
/// 下面這個接口我們需要注意一下,他繼承了B 和 C ,但是這兩個有同時繼承了 A
/// 不同的是,他們兩個接口在內(nèi)部定義的時候又采取了不同的策略,我們的訪問該是如何的呢?
/// </summary>
public interface I_4_D : I_4_B, I_4_C { };
![]()
public class I_4_L
{
public string Test(I_4_D thc) //接受的參數(shù)類型為接口D類型的
{
thc.T(); //這個好理解,他直接調(diào)用 C接口的 T方法
thc.F("B接口的方法"); //這個呢就直接訪問的B接口的F方法,雖然A接口也有一個F方法,但是他這里new了,就是說攔截了向上的訪問
((I_4_A)thc).F("A接口的方法"); //通過明確指定的方法來訪問A接口的F方法
((I_4_C)thc).F("A接口的方法"); //因為在C接口中并沒有復(fù)寫A接口的F方法,所以還是可以直接訪問的
((I_4_D)thc).F("B接口的方法"); //同理是訪問B接口的F方法,跟我們第二行的直接訪問是一個道理
}
}
以上轉(zhuǎn)自天轟穿的BLOG
抽象類:又叫抽象基類(不是雞肋):他在定義的時候使用 abstract 關(guān)鍵字標記的一般類.他可包含一般類所包含的所有特性,例如,字段,屬性,方法,另外他還包含一個很特殊的方法,叫抽象方法(這些方法基本上是沒有執(zhí)行代碼的函數(shù)標題,而派生于該類的的類就必須提供執(zhí)行的代碼).最可氣的是,他不能被實例化,他主要的用在類的定義和部分實現(xiàn)這方面,所以他需要在擴充類中完整的擴充并實現(xiàn)功能.
抽象方法: 當(dāng)類中的方法在聲明的時候加上 abstract 關(guān)鍵字的時候,他就被我們稱為抽象方法(洋名字叫 abstract method , 其實偷偷告訴你哈,我最近學(xué)了好多英文單詞,雖然還是常常讀錯,但是已經(jīng)有很大進步了,估計要不了多久就可以在那里大聲朗讀李白曾經(jīng)寫過的一首英文詩歌了),但是有個很重要的提醒,只有在抽象類和接口中才可以使用抽象方法.
例如 : 下面這個
public abstract class Thc123_Com
{
public abstract void GoTo();
}
public class Thc123_Net : Thc123_Com
{
public override void GoTo()
{
//實現(xiàn)上面抽象方法
}
}
=========================================================================================
在講接口之前呢我又想跟大家吹下牛, 大家知道我們的組裝計算機,即便是那些品牌機他實際上也是來自很多不同的廠商然后組裝起來的, 那么這寫硬件之間就有一個必然的聯(lián)系,那就是他們之間一定要有規(guī)范的接口,可是就拿我們的主板來說吧,這個CPU,他既可以是賽陽的,也可以是奔騰的,更可以是速龍,閃龍,當(dāng)然我跟特別非常十分希望再加上一個咱們中國的CPU品牌,這些CPU肯定采用了一些不同的運算方式啊,所以說我們這個接口就還要學(xué)會一點(我們常常勸老人的話,他只要在孝順你,你就別關(guān)他那么多的家務(wù)事),說得太好了,我們的接口還要做的事就是不管對方是怎么實現(xiàn)的,反正你插到這里面((*&^#@*&^%$%^$$#$)你就要實現(xiàn)具體的功能,至于你怎么實現(xiàn)就不管那么多了.
接口:他呢其實也是一種特殊的抽象類,用 interface 關(guān)鍵字標記,他的定義沒有 class 關(guān)鍵字,他可以包含 方法和屬性和事件,但是方法也只能是虛擬方法,任何派生于該接口的類就必須提供執(zhí)行的代碼.任何接口成員前面都不能加修飾符.
接口可用的修飾符有 new , public ,protected , internal , private ,但是同一聲明中修飾符只能有一個,new關(guān)鍵字只能出現(xiàn)在鑲套接口中,表示復(fù)寫繼承來的同名成員.
接口和類一樣,可以被繼承和發(fā)展,但不同的是,類繼承不僅說明繼承也會實現(xiàn)繼承,但是接口繼承只是說明繼承,通俗的說,派生類可以繼承基類的方法實現(xiàn),而派生接口只是繼承父接口的方法說明,卻沒有繼承父接口的實現(xiàn).
語法:
interface Ibook
{
string GetBookName();
}
接口相關(guān)知識:
1.聲明在接口中的方法,不可以包含方法的內(nèi)容區(qū)塊,簡單來說就是不能有大括號存在,例如下面
public interface Ibook
{
string GetBookName()
{ }
}
2. 實現(xiàn)接口的類就要這樣寫
public class Employee:Ibook , IUser
{
}
3 . 實現(xiàn)接口需要注意的一些東東
(1).實現(xiàn)一個接口就必須完成接口里的所有方法.(就好象誰家有幾個女兒,有漂亮的有對不起觀眾的,我要去娶那個漂亮的,然后人家開口了,小伙子,你要娶我女兒可以,但是你必須把幾個女兒全部娶了,否則我會讓你后悔一輩子. )
(2).在實現(xiàn)的類中又有幾點必須遵循的(我倒,都三重編號了,看來我寫的書后期編輯是件很棘手的事)
·存取權(quán)限必須相同 ;
·返回值類型必須相同
·方法的名稱必須相同
·參數(shù)必須相同
(3) . 接口內(nèi)的方法不能用 virtual 關(guān)鍵字申明,更不要設(shè)置存取權(quán)限.
下面我們繼續(xù)來看下個例題
另外還有一種呢就是以明確的方式實現(xiàn)接口
簡單來說就是方法前面必須加上接口的名稱.這個解釋起來沒有看起來明確,來吧,看這里(怎么聽這話有點怪怪的,難道是我思想不健康,按理說我算是生在陽光下,長在花叢中(不過18歲以后我就基本上是成長在一群 花蟲 中了),沒理由思想會這么XX啊.)
下面針對抽象類和接口做一個詳細的對比
| 抽象類( abstract method ) | 接口 ( interface ) |
| 可以包含實現(xiàn)區(qū)塊 | 不能包含實現(xiàn)區(qū)塊 |
| 可以包含抽象方法 | 不能包含抽象方法 |
| 可以包含非public成員 | 不可以包含非public成員 |
| 能繼承其他的類,包含非抽象類 | 能繼承其他接口 |
| 可以控制版本 | 無法控制版本 |
| 不能被實例化 | 不能被實例化 |
virtual: 這個關(guān)鍵字表示當(dāng)前方法、屬性、索引器或事件的抽象實現(xiàn)或虛實現(xiàn)可被任何派生自這個類的擴充類進行復(fù)寫.
override: 表示當(dāng)前方法已經(jīng)改寫了基類的同名同參數(shù)的方法、屬性、索引器或事件的抽象實現(xiàn)或虛實現(xiàn).
==============================下面是相關(guān)的代碼=================================
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// 為了演示顯得更簡單,我從一C#設(shè)計模式書中的例題精簡了一下
/// 說心理話,做這級教程真的算是把我折磨夠了,我總試圖用一個簡單的例題同時說明
/// 在什么地方用他最合適,該怎么用,可是簡單了就感覺不出為什么需要用
/// 復(fù)雜了吧,我口才又不佳,感覺說不清楚,把主題都搞偏離了.很郁悶
/// </summary>
public abstract class vehicle
{//首先我們定義一個抽象的汽車基類
public int chelun; //車輪
public float zhongliang;
public vehicle(int cl,float zl)
{
chelun = cl;
zhongliang = zl;
}
public abstract string GetMore();
//定義一個抽象方法
}
public class car : vehicle
{//定義一個轎車類,繼承自vehicel ,所以他必須實現(xiàn)父類中的所有抽象方法
public int passeng; //乘客數(shù)量
public car(int cl, float zl, int p)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
}
public override string GetMore()
{
//return 他的詳細信息
}
}
public class Truck : vehicle
{
public int passeng; //乘客數(shù)量
public float load; //載重
public Truck(int cl, float zl, int p, float l)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
load = l;
}
public override string GetMore()
{
//return 卡車的全部信息
}
}
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using I_B;

public partial class demo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
////////////////////////////---接 口 一 演 示---////////////////////////
Book b = new Book("人性的優(yōu)點");
lbl_bn.Text = GetS(b);
}
private static string GetS(IBook ib)
{//注意到這里,我們給的參數(shù)是我們的接口類型
return ib.BookName;
//這里返回的是我們的接口的屬性
}
////////////////////////////---接 口 二 演 示---////////////////////////
protected void Button1_Click(object sender, EventArgs e)
{//接口二的演示
I_2_L i2 = new I_2_L();
i2.A = 5;
lbl_i_2.Text = i2.Count(2, 4).ToString();
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/**
* 大致演示接口的定義和訪問,下面的例題開始詳細的演示每個細節(jié)
* */
namespace I_B
{
public interface IBook
{
string BookName { get;set;} //聲明接口中的屬性
void InsertToDate(); //聲明接口中的方法
}
public class Book : IBook
{ //我們聲明這樣一個類,他繼承了接口IBook
string bookname;
public Book(string bn)
{
bookname = bn;
}
/// <summary>
/// 實現(xiàn)接口中的BookName屬性
/// </summary>
public string BookName
{
get { return bookname; }
set { bookname = value; }
}
/// <summary>
/// 實現(xiàn)接口中聲明的方法
/// </summary>
public void InsertToDate()
{
//將我們的信息寫如數(shù)據(jù)庫
}
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/**
* 在這個演示中我們主要說明一個問題,就是如果繼承了有父接口的接口,那么也必須實現(xiàn)他全部父接口的方法和屬性
* 這個就是我剛才說娶老婆的哪個問題了,很頭大吧
* **/
interface I_2_A //聲明第一個接口
{
int A { get;set;} //聲明一個屬性
}
interface I_2_B //聲明第二個接口
{
int Count(int i,int j); //聲明一個方法
}
interface I_2_C : I_2_A, I_2_B { } //聲明第三個接口又繼承了前兩個接口
//什么都沒有聲明。但是他實際上是繼承了前面兩個接口的屬性和方法。
public class I_2_L : I_2_C //聲明一個類,他繼承了I_2_C這個接口
{
int a;
public int A
{
get { return a; }
set { a = value; }
}
public int Count(int i, int j)
{
return i * j * a;
}
}

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/**
* 外部對接口的訪問,如果出現(xiàn)同名的參數(shù)或者方法,必須顯示的指出他的父接口。
* 特別是在不清楚具體情況的前提下,最好是做得保守一點。
* **/
public interface I_3_A
{
int Count { get;set;}
int J(int j);
}
public interface I_3_B
{
void Count(int i);
double J(double j);
}
public interface I_3_C : I_3_A, I_3_B { }
public class I_3_L
{
public void Sum(I_3_C thc)
{
thc.Count(); //錯誤,具有二義性
thc.Count = 1; //錯誤,具有二義性
thc.Count(1); //錯誤,具有二義性

((I_3_A)thc).Count = 1; //正確
((I_3_B)thc).Count(1);
((I_3_A)thc).J(1);
((I_3_B)thc).J(1);
thc.J(1.0);
thc.J(1);
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/**
* 外部類中對多重繼承中的成員訪問問題
* 感覺上有點繞,實際上一下想通了其實也就簡單了
* **/
public interface I_4_A
{
string F(string A);
}
public interface I_4_B : I_4_A
{
new string F(string A);
}
public interface I_4_C : I_4_A
{
string T();
}
/// <summary>
/// 下面這個接口我們需要注意一下,他繼承了B 和 C ,但是這兩個有同時繼承了 A
/// 不同的是,他們兩個接口在內(nèi)部定義的時候又采取了不同的策略,我們的訪問該是如何的呢?
/// </summary>
public interface I_4_D : I_4_B, I_4_C { };
public class I_4_L
{
public string Test(I_4_D thc) //接受的參數(shù)類型為接口D類型的
{
thc.T(); //這個好理解,他直接調(diào)用 C接口的 T方法
thc.F("B接口的方法"); //這個呢就直接訪問的B接口的F方法,雖然A接口也有一個F方法,但是他這里new了,就是說攔截了向上的訪問
((I_4_A)thc).F("A接口的方法"); //通過明確指定的方法來訪問A接口的F方法
((I_4_C)thc).F("A接口的方法"); //因為在C接口中并沒有復(fù)寫A接口的F方法,所以還是可以直接訪問的
((I_4_D)thc).F("B接口的方法"); //同理是訪問B接口的F方法,跟我們第二行的直接訪問是一個道理
}
}
以上轉(zhuǎn)自天轟穿的BLOG


浙公網(wǎng)安備 33010602011771號