虚方法和重写方法的继承特性
这个题目起的还是有点不合适,但是当你看到下面的代码就会明白我在搞些什么名堂,其实质是辨析了一下virtual关键字和override关键字,MD写的代码,部分语言输入法兼容性问题,搞的我只能用用英文注释,破键盘这两也让我敲坏了很多键都按下了不起作用了,无奈啊。。。。下面我按我的理解简单的介绍一下虚方法和重写方法。
虚方法:这个方法其实就是为了重写方法而存在的(在声明中包含virtual关键字),否则哪,我也没感觉它存在的意义。
其一:因为要重写所以它的访问类型如果为private则毫无意义阻碍了重写动作的进行也就是它不能私有化,所以C#中virtual关键字和private关键字不能同时使用。
其二:因为静态的方法和抽象方法不能重写,同理C#中static,abstract关键字和virtual关键字不能同时使用。
其三:不能在声明虚方法的同时指定重写虚方法,因为重写方法只能重写基类的虚方法,也就是要提前在基类中声明虚方法,所以virtual关键字和override关键字不能同时使用。
重写方法:就是使从基类继承的虚方法提供新的实现(使用关键字override声明),从而为其子类所专有化。
同上面的思路一样:因为静态的方法和抽象方法不能重写,同理C#中static,abstract,new关键字和override关键字不能同时使用。
今天彻底的实验了一下,总结用法如下:
非虚方法的实现(全部隐藏的虚方法)最初声明的是什么类的方法就永远是什么类的方法。
虚方法的实现:最终是什么类型的方法就调用该类型的方法。
(含有隐藏的)虚方法的实现:最终是什么类型的方法就调用(最靠近)该类型的方法。
直接上代码,看看就明白了我总结的用法了。
using System;
namespace HideTest
{
class Great_grandfather
{
public void printf()
{
Console.WriteLine("曾祖父.printf()");
}//非虚方法
public virtual void F()
{
Console.WriteLine("曾祖父.F()");
}//虚方法
public virtual void D()
{
Console.WriteLine("曾祖父.D()");
}//虚方法
public virtual void E()
{
Console.WriteLine("曾祖父.E()");
}
}
class grandfather:Great_grandfather
{
new private void printf() //仅在grandfather类内隐藏Great_grandfather.printf()方法
{
Console.WriteLine("祖父.printf()");
}
public void Show()
{
grandfather n=new grandfather();
n.printf();
}
new public virtual void F()
{
Console.WriteLine("祖父.F()");
}
public override void D()
{
Console.WriteLine("祖父.D()");
}
public override void E()
{
Console.WriteLine("祖父.E()");
}
}
class father_1:grandfather
{
new public void printf()
{
Console.WriteLine("父.printf()");
}
new public virtual void F()
{
Console.WriteLine("父.F()");
}
new public virtual void D()//Hide The base class methods, Redefined a new method.
{
Console.WriteLine("父.D()");
}
public override void E()
{
Console.WriteLine("父.E()");
}
}
class father_2 : grandfather
{
public void TryHide()
{
father_2 father = new father_2();
father.printf();
}
}
class child:father_1
{
new public void printf()
{
Console.WriteLine("子.printf()");
}
new public virtual void F()
{
Console.WriteLine("子.F()");
}
public override void D()
{
Console.WriteLine("子.D()");
}
public override void E()
{
Console.WriteLine("子.E()");
}
}
class Test
{
public static void Main()
{
child a = new child();
father_1 b = a;
grandfather c = a;
Great_grandfather d = a;
father_2 e = new father_2();
Console.WriteLine("=========test the inherited of methods===========\n\n");
Console.WriteLine("=========测试隐藏非虚方法===========");
a.printf(); //调用child.printf(),打印子.printf()
b.printf(); //调用father.printf(),打印父.printf()
e.printf(); //此处证明仅在grandfather类内隐藏了Great_grandfather.printf()方法
//所以此处仍调用Great_grandfather.printf()
c.printf(); //因为father.printf()在grandfather类外不可见( 注意和e.printf()的区别)
//所以仍调用继承的Great_grandfather.printf()的方法
c.Show(); //在grandfather类内隐藏了Great_grandfather.printf()的方法在打印祖父.printf()
d.printf();//调用 Great_grandfather.printf()打印曾祖父.printf()
Console.WriteLine("=========测试(隐藏的)隐藏虚方法===========");
a.F();//调用Child.F()
b.F();//调用father.F()
c.F();//调用grandfather.F()
d.F();//调用Great_grandfather.F()
Console.WriteLine("=========测试重写(含隐藏的)虚方法===========");
a.D();//调用Child.D()
b.D();//调用Child.D() override by the Chid.D()
c.D();//调用grandfather.D() because it is Hide in the (farther)class not override
d.D();//调用grandfather.D() override by the grandfather.D()
Console.WriteLine("=========测试重写(不含隐藏的)虚方法===========");
a.E();//调用Child.E()
b.E();//调用Child.E()
c.E();//调用Child.E()
d.E();//调用Child.E()
Console.WriteLine("=========OVER===========");
Console.ReadKey();
}
}
}