C#的多態性:
我的理解是:同一個操作,作用於不同的對象時,會有不同的結果,即同一個方法根據需要,作用於不同的對象時,會有不同的實現。
C#的多態包括:介面多態,繼承多態。
其中繼承多態又包括通過虛擬方法實現的多態和通過抽象方法實現的多態性
例如:基類動物都有吃的方法,但是不同的動物吃的東西就會不一樣,例如狼吃肉,羊吃草,這樣“吃”的這個方法就要在衍生類別裡面重新實現以下,運行時,通過指向基類的指標,來調用實現衍生類別中的方法。
接下來舉例實現多態性。
1. 介面多態性
把動物“吃”的方法放到一個介面(IAnimal)裡,然後讓具體的動物類(Wolf/Sheep)繼承這個介面,並根據自己的需要實現這個介面。
代碼實現:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
}
}
public class Wolf : IAnimal {
//多態實現
public void Eat() {
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : IAnimal {
//多態實現
public void Eat() {
Console.WriteLine("羊吃草!");
}
}
//介面
public interface IAnimal {
void Eat();
}
介面的多態性就是當不同的類繼承了相同的介面以後,都要根據自己的需要重新實現繼承的介面,這樣同樣的方法簽名在不同的類中就會實現不同的操作。
2. 繼承的多態性
2.1.通過虛擬方法實現的多態(virtual,override)
首先要在基類中實現virtual方法,然後在衍生類別中根據自己的需要用override重寫virtual方法。如果不希望這個方法被繼續重寫,則把這個方法寫成sealed方法。
virtual方法必須在基類中實現。
代碼實現:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
new Goat().Eat();
}
}
public class Wolf : Animal {
//多態實現
public override void Eat() {
base.Eat();
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : Animal {
//多態實現
public override void Eat() {
base.Eat();
Console.WriteLine("羊吃草!");
}
}
public class Goat : Sheep {
//多態實現被終結,此Eat方法不能被override,因為用sealed了
public sealed override void Eat() {
//base.Eat();
Console.WriteLine("山羊吃草!");
}
}
//基類實現虛方法
public class Animal {
public virtual void Eat() { }
}
2.2.通過抽象方法實現的多態(abstract,override)
抽象方法必須定義在抽象類別裡。抽象類別不能被建立執行個體。
基類中的抽象方法只能被聲明,不需要實現,所以衍生類別中重寫抽象方法的時候沒有base方法。
代碼實現如下:
class Program {
static void Main(string[] args) {
new Wolf().Eat();
new Sheep().Eat();
new Goat().Eat();
}
}
public class Wolf : Animal {
//多態實現
public override void Eat() {
Console.WriteLine("狼吃肉!");
}
}
public class Sheep : Animal {
//多態實現
public override void Eat() {
Console.WriteLine("羊吃草!");
}
}
public class Goat : Sheep {
//多態實現被終結,此Eat方法不能被override,因為用sealed了
public sealed override void Eat() {
Console.WriteLine("山羊吃草!");
}
}
//基類只需聲明方法
public abstract class Animal {
public abstract void Eat();
}
總結:
1.虛方法重寫的時候可以有base方法(base.Eat()),抽象方法重寫的時候沒有base方法,原因是:虛方法必須在基類中實現,抽象方法只在基類中聲明,不需要實現。
2.衍生類別中可以 不重寫虛方法的實現,但是衍生類別必須重寫抽象方法的實現,原因同1.
3.包含虛方法的非抽象類別可以被建立執行個體(對象),但是包含抽象方法的抽象類別不能被建立執行個體。
4.繼承介面的衍生類別必須實現介面的方法,因為介面也是只負責聲明方法,不負責實現。
5.介面的多態性不需要用override重寫方法。