淺談.NET中不一樣的多態(tài)
在.NET中,多態(tài)通常意味著子類(lèi)對(duì)于父類(lèi)一種衍變。子類(lèi)繼承自父類(lèi),擁有父類(lèi)所定義的一切(public或protected)成員。但同時(shí),它又可以修改(重寫(xiě)或復(fù)寫(xiě))這些成員,使其實(shí)現(xiàn)與父類(lèi)以及其他子類(lèi)完全不同。我們可以說(shuō),繼承體現(xiàn)了類(lèi)的多態(tài)性。
大家應(yīng)該很熟悉Duck的例子了吧?
- public abstract class Duck
- {
- public abstract void Quack();
- }
- public class MallardDuck : Duck
- {
- public override void Quack()
- {
- Console.WriteLine("Quack, quack, quack...");
- }
- }
- public class RubberDuck : Duck
- {
- public override void Quack()
- {
- Console.WriteLine("Squeak, squeak, squeak...");
- }
- }
- public class Program
- {
- public static void Main()
- {
- Duck duck = new MallardDuck();
- duck.Quack();
- duck = new RubberDuck();
- duck.Quack();
- Console.ReadLine();
- }
- }
MallardDuck和RubberDuck雖然都繼承自抽象類(lèi)Duck,同樣擁有Quack()方法,但它們卻有不同的實(shí)現(xiàn),產(chǎn)生不同的結(jié)果。在聲明Duck類(lèi)型時(shí),既可以實(shí)例化為Mallard,也可以實(shí)例化為RubberDuck,或者是其他繼承自Duck的類(lèi),在運(yùn)行時(shí),將自動(dòng)調(diào)用各個(gè)子類(lèi)的實(shí)現(xiàn)。
多態(tài)的這些特性使依賴(lài)注入和面向抽象編程成為可能,其重要性不言而喻。
不一樣的多態(tài)
然而,既然多態(tài)是指同一類(lèi)事物之間的不同形態(tài),那么我們?yōu)槭裁匆褜?duì)于多態(tài)的理解局限于類(lèi)的繼承關(guān)系呢?在.NET中是否還存在著非繼承關(guān)系的多態(tài)性呢?
泛型體現(xiàn)了參數(shù)的多態(tài)性
類(lèi)型參數(shù)在泛型中通常解釋為占位符,而我更愿意將其理解為對(duì)參數(shù)的一種抽象。以最常見(jiàn)的List
- public class MyList<T>
- {
- private T[] items;
- private int size;
- public void Add(T item)
- {
- if (size == items.Length)
- {
- // modify capacity
- }
- items[size++] = item;
- }
- }
如果我們使用MyList
您是否也覺(jué)得這是多態(tài)性的一種體現(xiàn)呢?
再來(lái)看看十分經(jīng)典的Swap
- public class Swapper
- {
- private static void Swap<T>(ref T o1, ref T o2)
- {
- T temp = o1;
- o1 = o2;
- o2 = temp;
- }
- }
Swap
委托體現(xiàn)了方法的多態(tài)性
委托是對(duì)擁有相同參數(shù)和返回值的所有方法的封裝。只要方法擁有同樣的參數(shù)列表和返回值,委托都認(rèn)為它們屬于同一“類(lèi)型”的方法,可以添加到同一個(gè)委托鏈表中。
- public delegate void FooDelegate(List<string> list, string str);
- public class DelegateTest
- {
- public void AddToList(List<string> list, string strToAdd)
- {
- list.Add(strToAdd);
- }
- public static void PrintIfContains(List<string> list, string strToCheck)
- {
- if (list.Contains(strToCheck))
- Console.WriteLine("The list contains " + strToCheck);
- }
- }
- public class Program
- {
- public static void Main()
- {
- List<string> list = new List<string>();
- list.Add("Kirin");
- DelegateTest delegateTest = new DelegateTest();
- FooDelegate fooDelegate = new FooDelegate(delegateTest.AddToList);
- fooDelegate += new FooDelegate(DelegateTest.PrintIfContains);
- fooDelegate(list, "麒麟.NET");
- Console.ReadLine();
- }
- }
在上例中,F(xiàn)ooDelegate委托封裝了參數(shù)為L(zhǎng)ist
您是否也認(rèn)為這是方法的多態(tài)性的一種體現(xiàn)呢?
多態(tài)小結(jié)
我們通常所討論的多態(tài),就是指子類(lèi)對(duì)父類(lèi)方法的重寫(xiě)(虛方法)或覆蓋(非虛方法),這樣的理解未免過(guò)于狹隘。.NET強(qiáng)大的特性能夠?qū)崿F(xiàn)其他語(yǔ)言中無(wú)法實(shí)現(xiàn)的多態(tài)性。如本文所列舉的泛型和委托。您是否認(rèn)同筆者的觀點(diǎn)呢?如果認(rèn)同,您是否還能舉出其他的例子呢?
您可能覺(jué)得本文缺乏技術(shù)含量。的確是的,本文并不包含多么高深的技術(shù)和思想,而只是筆者最近學(xué)習(xí)過(guò)程中一些瑣碎的領(lǐng)悟。如果能夠幫助到您,將是筆者的榮幸。
【編輯推薦】