1. 你通常怎樣用多態(tài)?
假設(shè)我有一個(gè)類,里面有一個(gè) PrintStatus 方法,用于打印實(shí)例的當(dāng)前狀態(tài),我希望該類的派生類都帶有一個(gè) PrintStatus 方法,并且這些方法都用于打印其實(shí)例的當(dāng)前狀態(tài)。那么我會(huì)這樣表達(dá)我的愿望:
// Code #01
class Base
{
public virtual void PrintStatus()
{
Console.WriteLine("public virtual void PrintStatus() in Base");
}
}
于是我可以寫一個(gè)這樣的方法:
// Code #02
public void DisplayStatusOf(Base[] bs)
{
foreach (Base b in bs)
{
b.PrintStatus();
}
}
bs 中可能包含著不同的 Base 的派生類,但我們卻可以忽略這些“個(gè)性”而使用一種統(tǒng)一的方式來處理某事。在 .net 2.0 中,XMLReader 的 Create 有這樣一個(gè)版本:
public static XMLReader Create(Stream input);
你可以向 Create 傳遞任何可用的“流”,例如來自文件的“流”(FileStream)、來自內(nèi)存的“流”(MemoryStream)或來自網(wǎng)絡(luò)的“流”(NetworkStream)等。雖然每一中“流”的工作細(xì)節(jié)都不同,但我們卻使用一種統(tǒng)一的方式來處理這些“流”。
2. 假如有人不遵守承諾...
DisplayStatusOf 隱含著這樣一個(gè)假設(shè):bs 中如果存在派生類的實(shí)例,那么該派生類應(yīng)該重寫 PrintStatus,當(dāng)然必須加上 override 關(guān)鍵字:
// Code #03
class Derived1 : Base
{
public override void PrintStatus()
{
Console.WriteLine("public override void PrintStatus() in Derived1");
}
}
你可以把這看作一種承諾、約定,直到有人沉不住氣...
// Code #04
class Derived2 : Base
{
public new void PrintStatus()
{
Console.WriteLine("public new void PrintStatus() in Derived2");
}
}
假設(shè)我們有這樣一個(gè)數(shù)組: // Code #05
Base[] bs = new Base[]
{
new Base(),
new Derived1(),
new Derived2()
};
把它傳遞給 DisplayStatusOf,則輸出是:
// Output #01
// public virtual void PrintStatus() in Base
// public override void PrintStatus() in Derived1
// public virtual void PrintStatus() in Base
從輸出結(jié)果中很容易看出 Derived2 并沒有按照我們期望的去做。但你無需驚訝,這是由于 Derived2 的設(shè)計(jì)者沒有“遵守約定”的緣故。
假設(shè)我有一個(gè)類,里面有一個(gè) PrintStatus 方法,用于打印實(shí)例的當(dāng)前狀態(tài),我希望該類的派生類都帶有一個(gè) PrintStatus 方法,并且這些方法都用于打印其實(shí)例的當(dāng)前狀態(tài)。那么我會(huì)這樣表達(dá)我的愿望:
// Code #01
class Base
{
public virtual void PrintStatus()
{
Console.WriteLine("public virtual void PrintStatus() in Base");
}
}
于是我可以寫一個(gè)這樣的方法:
// Code #02
public void DisplayStatusOf(Base[] bs)
{
foreach (Base b in bs)
{
b.PrintStatus();
}
}
bs 中可能包含著不同的 Base 的派生類,但我們卻可以忽略這些“個(gè)性”而使用一種統(tǒng)一的方式來處理某事。在 .net 2.0 中,XMLReader 的 Create 有這樣一個(gè)版本:
public static XMLReader Create(Stream input);
你可以向 Create 傳遞任何可用的“流”,例如來自文件的“流”(FileStream)、來自內(nèi)存的“流”(MemoryStream)或來自網(wǎng)絡(luò)的“流”(NetworkStream)等。雖然每一中“流”的工作細(xì)節(jié)都不同,但我們卻使用一種統(tǒng)一的方式來處理這些“流”。
2. 假如有人不遵守承諾...
DisplayStatusOf 隱含著這樣一個(gè)假設(shè):bs 中如果存在派生類的實(shí)例,那么該派生類應(yīng)該重寫 PrintStatus,當(dāng)然必須加上 override 關(guān)鍵字:
// Code #03
class Derived1 : Base
{
public override void PrintStatus()
{
Console.WriteLine("public override void PrintStatus() in Derived1");
}
}
你可以把這看作一種承諾、約定,直到有人沉不住氣...
// Code #04
class Derived2 : Base
{
public new void PrintStatus()
{
Console.WriteLine("public new void PrintStatus() in Derived2");
}
}
假設(shè)我們有這樣一個(gè)數(shù)組: // Code #05
Base[] bs = new Base[]
{
new Base(),
new Derived1(),
new Derived2()
};
把它傳遞給 DisplayStatusOf,則輸出是:
// Output #01
// public virtual void PrintStatus() in Base
// public override void PrintStatus() in Derived1
// public virtual void PrintStatus() in Base
從輸出結(jié)果中很容易看出 Derived2 并沒有按照我們期望的去做。但你無需驚訝,這是由于 Derived2 的設(shè)計(jì)者沒有“遵守約定”的緣故。