不同角度看C#多態(tài)
封裝、繼承、多態(tài),面向?qū)ο蟮娜筇匦裕皟身椑斫庀鄬θ菀祝斫舛鄳B(tài),特別是深入的了解,對于初學(xué)者而言可能就會有一定困難了。我一直認為學(xué)習(xí)OO的最好方法就是結(jié)合實踐,封裝、繼承在實際工作中的應(yīng)用隨處可見,但C#多態(tài)呢?也許未必,可能不經(jīng)意間用到也不會把它跟“多態(tài)”這個詞對應(yīng)起來。在此拋磚引玉,大家討論,個人能力有限,不足之處還請指正。
之前看到過類似的問題:如果面試時主考官要求你用一句話來描述多態(tài),盡可能的精煉,你會怎么回答?當然答案有很多,每個人的理解和表達不盡相同,但我比較趨向這樣描述:通過繼承實現(xiàn)的不同對象調(diào)用相同的方法,表現(xiàn)出不同的行為,稱之為多態(tài)。
1、一個簡單的C#多態(tài)實現(xiàn)(參考自http://www.cnblogs.com/glacierh/):
- public class Animal
- {
- public virtual void Eat()
- {
- Console.WriteLine("Animal Eat ...");
- }
- }
- public class Cat : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Cat Eat ...");
- }
- }
- public class Dog : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Dog Eat ...");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Animal[] animals = new Animal[3];
- animals[0] = new Animal();
- animals[1] = new Cat();
- animals[2] = new Dog();
- for (int i = 0; i < 3; i++)
- {
- animals[i].Eat();
- }
- }
- }
輸出結(jié)果:
Animal Eat ...
Cat Eat ...
Dog Eat ...
OK,從上面的例子可以看出,通過繼承,使得Animal對象數(shù)組中的不同的對象,在調(diào)用Eat()方法時,表現(xiàn)出了不同的行為,這就是一個最簡單的多態(tài)示例。
2、如果繼承中使用new而不是override關(guān)鍵字
- public class Animal
- {
- public virtual void Eat()
- {
- Console.WriteLine("Animal Eat ...");
- }
- }
- public class Cat : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Cat Eat ...");
- }
- }
- public class Dog : Animal
- {
- //注意此處用了 new 而不再是 override 關(guān)鍵字
- public new void Eat()
- {
- Console.WriteLine("Dog Eat ...");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Animal animal = new Animal();
- animal.Eat();
- Animal cat = new Cat();
- cat.Eat();
- Animal dog = new Dog();
- dog.Eat();
- }
- }
輸出結(jié)果:
Animal Eat ...
Cat Eat ...
Animal Eat ...
從結(jié)果中可以看出,當派生類Dog的Eat()方法使用new修飾時,Dog的對象轉(zhuǎn)換為Animal對象后,調(diào)用的是Animal類中的Eat()方法。其實可以理解為,使用new關(guān)鍵字后,使得Dog中的Eat()方法和Animal中的Eat()方法成為毫不相關(guān)的兩個方法,只是它們的名字碰巧相同而已。也由此可以看出:多態(tài),依賴override實現(xiàn)。
3、多重繼承
如果class A有一個virtual method(),class B繼承于class A,并override method(),class C又繼承于class B,那么class C是否可以繼續(xù)override method()并實現(xiàn)多態(tài)呢?看下面的例子:
- public class Animal
- {
- public virtual void Eat()
- {
- Console.WriteLine("Animal Eat ");
- }
- }
- public class Dog : Animal
- {
- public override void Eat()
- {
- Console.WriteLine("Dog Eat ");
- }
- }
- public class WolfDog : Dog
- {
- public override void Eat()
- {
- Console.WriteLine("WolfDog Eat ");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Animal animal = new Animal();
- animal.Eat();
- Animal dog = new Dog();
- dog.Eat();
- Animal wolfdog = new WolfDog();
- wolfdog.Eat();
- }
- }
輸出結(jié)果:
Animal Eat ...
Dog Eat ...
WolfDog Eat ...
OK,現(xiàn)在得到了肯定的答案,不管繼承關(guān)系包含了多少層,都可以在子類中對父類中已經(jīng)重寫的方法繼續(xù)進行重寫。即如果父類方法用override修飾,子類繼承了該方法,同時也可以用override修飾,多重繼承中的C#多態(tài)就是如此實現(xiàn)。要想終止這種重寫,只需重寫方法時使用sealed關(guān)鍵字。
【編輯推薦】