封裝、繼承、多態,物件導向的三大特性,前兩項理解相對容易,但要理解多態,特別是深入的瞭解,對於初學者而言可能就會有一定困難了。我一直認為學習OO的最好方法就是結合實踐,封裝、繼承在實際工作中的應用隨處可見,但多態呢?也許未必,可能不經意間用到也不會把它跟“多態”這個詞對應起來。在此拋磚引玉,大家討論,個人能力有限,不足之處還請指正。
之前看到過類似的問題:如果面試時主考官要求你用一句話來描述多態,儘可能的精鍊,你會怎麼回答?當然答案有很多,每個人的理解和表達不盡相同,但我比較趨向這樣描述:通過繼承實現的不同對象調用相同的方法,表現出不同的行為,稱之為多態。
1、一個簡單的多態實現(參考自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();
}
}
}
輸出結果:Animal Eat ...
Cat Eat ...
Dog Eat ...
OK,從上面的例子可以看出,通過繼承,使得Animal對象數組中的不同的對象,在調用Eat()方法時,表現出了不同的行為,這就是一個最簡單的多態樣本。
2、如果繼承中使用new而不是override關鍵字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 關鍵字
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();
}
}
輸出結果:Animal Eat ...
Cat Eat ...
Animal Eat ...
從結果中可以看出,當衍生類別Dog的Eat()方法使用new修飾時,Dog的對象轉換為Animal對象後,調用的是Animal類中的Eat()方法。其實可以理解為,使用new關鍵字後,使得Dog中的Eat()方法和Animal中的Eat()方法成為毫不相關的兩個方法,只是它們的名字碰巧相同而已。也由此可以看出:多態,依賴override實現。
3、多重繼承
如果class A有一個virtual method(),class B繼承於class A,並override method(),class C又繼承於class B,那麼class C是否可以繼續override method()並實現多態呢?看下面的例子: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();
}
}
輸出結果:Animal Eat ...
Dog Eat ...
WolfDog Eat ...
OK,現在得到了肯定的答案,不管繼承關係包含了多少層,都可以在子類中對父類中已經重寫的方法繼續進行重寫。即如果父類方法用override修飾,子類繼承了該方法,同時也可以用override修飾,多重繼承中的多態就是如此實現。要想終止這種重寫,只需重寫方法時使用sealed關鍵字。
未完待續...