淺析C#的多(duo)態性
時(shi)間:2018-09-29 來源(yuan):未知
什么是多態:同(tong)(tong)(tong)一個(ge)操作(zuo)(zuo),作(zuo)(zuo)用(yong)于(yu)不同(tong)(tong)(tong)的對(dui)象時,會(hui)(hui)有不同(tong)(tong)(tong)的結果,即(ji)同(tong)(tong)(tong)一個(ge)方法根據需(xu)要,作(zuo)(zuo)用(yong)于(yu)不同(tong)(tong)(tong)的對(dui)象時,會(hui)(hui)有不同(tong)(tong)(tong)的實(shi)現。
C#的多(duo)態(tai)包(bao)括:接口多(duo)態(tai),繼(ji)承多(duo)態(tai)。
其中繼承多(duo)態(tai)又包括通(tong)過虛擬方法實現(xian)的(de)多(duo)態(tai)和通(tong)過抽(chou)象方法實現(xian)的(de)多(duo)態(tai)性
例如:基(ji)類(lei)動物都有吃(chi)的方法,但(dan)是不同的動物吃(chi)的東西就(jiu)會不一樣,例如狼吃(chi)肉,羊吃(chi)草(cao),這(zhe)樣“吃(chi)”的這(zhe)個方法就(jiu)要在派生(sheng)類(lei)里面重(zhong)新實(shi)現(xian)以下,運(yun)行(xing)時,通過指向基(ji)類(lei)的指針(zhen),來(lai)調用(yong)實(shi)現(xian)派生(sheng)類(lei)中的方法。
1. 接(jie)口多態(tai)性
把(ba)動物“吃”的方法(fa)放到一個(ge)接(jie)口(IAnimal)里,然后讓(rang)具(ju)體(ti)的動物類(Wolf/Sheep)繼(ji)承這個(ge)接(jie)口,并根(gen)據自己的需要實(shi)現這個(ge)接(jie)口。
代碼實現:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
}
}
public class Wolf : IAnimal {
//多(duo)態實(shi)現
public void Eat() {
Console.WriteLine("狼(lang)吃肉!");
}
}
public class Sheep : IAnimal {
//多態實(shi)現
public void Eat() {
Console.WriteLine("羊吃草!");
}
}
//接(jie)口(kou)
public interface IAnimal {
void Eat();
}
接口的(de)多態性就是當不同(tong)(tong)的(de)類(lei)繼承了相同(tong)(tong)的(de)接口以后,都(dou)要(yao)根據自(zi)己的(de)需要(yao)重新(xin)實(shi)現(xian)繼承的(de)接口,這樣同(tong)(tong)樣的(de)方法簽名在不同(tong)(tong)的(de)類(lei)中就會(hui)實(shi)現(xian)不同(tong)(tong)的(de)操作。
2. 繼承的多態性
設(she)想(xiang)動物(wu)園飼養員每天需要給他所負責死樣的(de)獅(shi)子(zi)、猴子(zi)和(he)鴿子(zi)喂(wei)食。
首先,建(jian)立三個類分別代表三個動物

飼養員用Feeder類表示(shi)。由于三種動物(wu)吃的(de)(de)動物(wu)一樣,Feeder類必須擁有三個(ge)喂動物(wu)的(de)(de)公共方法:

過程如下:
static void Main(string[] args)
{
Monkey m=new Monkey();
Pigeon p=new Pigeon();
Lion l=new Lion();
Feeder f=new Feeder();
f.Name="小李";
f.FeedMonkey(); //喂(wei)猴子
f.FeedPigeon(); //喂鴿子
f.FeedLion(); //喂獅(shi)子(zi)
}
如果有又把熊貓交給他管理,這(zhe)是(shi)我們的程(cheng)序不(bu)得不(bu)給Feeder類在增(zeng)加一個方法:FeedPanda();
萬一(yi)小李(li)后來又不管(guan)猴(hou)子了,又要從Feeder類中刪(shan)除FeedPigeon()方法(fa)。
所以這種編程方(fang)式很明顯不合(he)理的(de)。
我們可(ke)以(yi)應用多態(tai)的(de)方法解(jie)決。
首先(xian)因(yin)為它們(men)都(dou)是動物(wu),因(yin)此,可以(yi)建立一個(ge)Animal抽象基類。

由于不同的(de)動物吃不同的(de)食物,所以(yi)在(zai)Animal類(lei)中定義(yi)一個抽(chou)象方法:eat();有子類(lei)負(fu)責(ze)實現。
abstract class Animal
{
public abstract void eat();
}
//獅子
class Lion:Animal
{
public override void eat()
{
Console.WriteLine("吃肉");
}
}
//猴子
class Money:Animal
{
public override void eat()
{
Console.WriteLine("吃香蕉");
}
}
//鴿子
class Pigeon:Animal
{
public override void eat()
{
Console.WriteLine("吃大(da)米");
}
}
現在,可以將Feeder類的(de)三個(ge)喂(wei)養方(fang)法合并為一(yi)個(ge)FeedAnimal:

Feeder類代碼:
//飼養員
class Feeder
{
public String Name;
public void FeedAnimal(Animal animals)
{
animals.eat();
}
}
喂養過程:
static void Main(string[] args)
{
Monkey m=new Monkey();
Pigeon p =new Pigeon();
Lion l=new Lion();
Feeder f=new Feeder();
f.Name="小李(li)";
f.FeedAnimal(m);//喂(wei)猴(hou)子
f.FeedAnimal(p);//喂鴿(ge)子
f.FeedAnimal(l);//喂獅(shi)子(zi)
}
我們修(xiu)改(gai)一(yi)下Feeder類的(de)定義(yi),增加一(yi)個新方法FeedAnimals(),新方法遠程的(de)功能(neng)是喂養一(yi)群動物,接受的(de)是Animal的(de)數(shu)組:
class Feeder
{
//喂養一群(qun)動物
public voidFeedAnimals(Animal[] ans)
{
foreach(Animal an in ans)
{
an.eat();
}
}
}
過程如下:
static void Main(string args)
{
//動物數組
Animal[] ans={new Monkey(),new Pigeon(), new Lion()};
Feeder f=new Feeder();
f.Name="小李";
f.FeedAnimals(ans);
}
代碼中(zhong)數(shu)組ans的(de)元素為(wei)Animal,因此(ci),可以在其中(zhong)存入任何一個Animal的(de)子類。具有這種特性的(de)數(shu)組成為(wei)"多態數(shu)組"。
多態(tai)的(de)意義:
編程中(zhong)應用多態,可以將其簡化為一(yi)下兩(liang)句:
應(ying)用(yong)繼承實(shi)現對象的統一管理。
應用接口定義對象的行為特征(zheng)。
使(shi)用多態的好(hao)處:
當要修(xiu)(xiu)改程序(xu)并(bing)擴充系統時,需(xu)要修(xiu)(xiu)改的地方(fang)較(jiao)(jiao)少(shao),對其他部分代碼的影響較(jiao)(jiao)小。

