多态
多态
有了继承,一个类可以从类继承,可以实现接口,那么这个类除了有它本身的类型,还将具有基类的类型,以及它所实现的接口的类型,也就意味着一个基类的引用可以指向它的所有派生类型,那么当通过基类的引用调用在派生类中实现的方法时,不同的派生类将产生不同的调用结果,这就是多态性。继承机制(此处将接口的实现也是继承的一种)是实现多态的基础。C#中每种类型都是多态的,因为所有类型都从Object类型派生。
C#中的多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。
编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数个数、参数类型等信息决定使用哪个重载方法,以实现某种操作。
运行时的多态性:C#中运行时的多态性是通过覆写虚方法实现的。具体是指直到系统运行时,才根据实际情况决定实现何种操作。
重载方法
重载就是在同一个类中存在多个同名的方法,但签名却不同,重载是编译时的多态,事实上是一种静态绑定。
//非泛型重载
public void DoSomething(int num, string str) { }
public void DoSomething(int num, string str1, string str2) { }
public int DoSomething(string str, int num) { }
//泛型重载
public class TestClass<T, V>
{
public T DoSomething(T n, V m)
{
Console.WriteLine(“method 1”);
return n;
}
public T DoSomething(V n, T m)
{
Console.WriteLine(“method 2”);
return m;
}
public int DoSomething(int m, int n)
{
Console.WriteLine(“method 3”);
return 0;
}
}
//如果在使用时T和V类型相同(如int),那么方法123会发生什么?以上代码并不会报异常,因为第3个非泛型方法存在,若无第3个方法存在,会编译错误
//当非泛型方法和泛型方法具有相同的签名时,运行时将优先调用非泛型方法
//泛型方法的重载是否产生混淆,是在运行时调用的时候检查的,而非编译的时候检查
虚方法
class Person
{
public virtual void Speak()
{
Console.WriteLine("Speak...");
}
}
virtual关键字必须位于方法的返回类型之前,而且虚方法可以有方法体,抽象方法是必须被派生类覆写的方法,其本身不允许有方法体,静态成员不能是虚函数,构造函数不能是虚函数。
派生类必须实现基类的抽象方法,但非必须实现基类的虚方法,基类的虚方法已有实现。
覆写方法
class Chinese : Person
{
public override void Speak()
{
Console.WriteLine(“中国话”);
}
}
class English : Person
{
public override void Speak()
{
Console.WriteLine(“English”);
}
}
被标记为override的方法也可以被派生类再次覆写,但如果不想被覆写,可将该方法而不是类标记为sealed,表示该方法标记为密封,从而不允许派生类对它进行覆写。
抽象类及抽象方法
- 抽象类及抽象方法仅可以被继承,不能被实例化
- 抽象方法不能包含方法体,并且抽象方法所在的类必须也声明为抽象类
- 要声明抽象类及抽象方法,可以使用关键字abstract,置于关键字class前面
- 抽象方法没有实现,所以后面紧跟分号,而不是方法体
- 抽象类的派生类必须实现所有的抽象方法
- 当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法
abstract class Chinese : Person
{
public abstract override void Speak();
}
参考引用
[1]: C# 权威指南