重新开始学习.NET之二–继承和实现多态的几种方法
1)虚方法virtual
使用virtual关键字标记基类中的函数为虚方法,再在派生类中使用override关键字重写该方法是实现多态的一种方法。
class MyClass : FatherClass
{
public override void Get_n(int m)
{
n = 1;
}
}
class FatherClass
{
public int n {get; set;}
public virtual void Get_n(int m)
{
n = m;
}
}
如上代码所示,MaClass继承自父类FatherClass,Get_n是父类中定义的一个虚方法,通过在派生类中使用override重写该方法可以实现不同的功能。
需要注意的是:
1)基类中的构造函数无法显示的声明为virtual;
2)除了函数,属性也可以声明为virtual;
3)因为所有的自定义类都继承于Object,而Object中的一些方法(如:ToString())等是被声明为virtual的,所以在自定义类中可以使用override重写这些方法。
当我们不需要重写基类中的方法时,我们可以选择直接使用base关键字来调用基类中的方法:
class MyClass : FatherClass
{
public override void Get_n(int m)
{
m = 2;
base.Get_n(m);
}
}
class FatherClass
{
public int n {get; set;}
public virtual void Get_n(int m)
{
n = m;
}
}
从上面的代码中可以看出,当不需要改变基类的虚方法实现的功能时,使用base关键字调用基类的方法是一种十分方便的方式。
2)抽象类abstract
使用abstract可以将类或者方法声明为抽象类或抽象方法。如果一个类中包含抽象方法,则这个类必须是抽象类。抽象方法本身也是虚方法,但是不能使用virtual声明它。
抽象方法不能有具体的实现,抽象方法的实现必须在派生类中重写的方法中实现,而继承自抽象类的派生类必须重写基类中的所有抽象成员。
class MyClass : FatherClass
{
public override void Get_n(int m)
{
throw new NotImplementedException();
}
}
abstract class FatherClass
{
public int n {get; set;}
public abstract void Get_n(int m);
}
需要注意的是:抽象方法不能直接实例化,但支持下面这种实现
new FatherClass myClass = new MyClass();
声明一个FatherCalss类的对象,将其实例化为MyClass。
3)接口interface
接口类似于抽象类,接口中只能包含方法(不包括构造函数),属性,索引器和事件的声明。接口的成员都是抽象的,不能有具体的实现,不能实例化接口。接口的存在就是为了被继承。接口的所有成员默认的隐式声明为public,因此不能用修饰符声明接口的成员。
class GetInt : IGetInt
{
public int n { get; set; }
public void Get_n(int m)
{
throw new NotImplementedException();
}
}
interface IGetInt
{
int n {get; set;}
void Get_n(int m);
}
接口和抽象类的区别:
1)接口中所有的成员都是抽象的,不能在接口被实现的
2)接口中的成员都不能用修饰符声明
3)C#中不支持类的多继承,但一个类可以集成自多个接口