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重寫方法。