老田:接着来回答你的第三个问题。如何去修改父类中已经写死的方法呢?要回答这个问题之前,我们先来看看下面这几种申明和实例化的方式,判断下对不对
Truct tc = new Truct(); //实例化一个卡车类 Car c = new Truct(); //卡车 是 车 对不对? Truct tc2 = c; //车 是 卡车 对不对? |
小天:我试着写了下,第二行是对的,但是第三行错误,为什么呢?
老田:是的,用任意子类都可以实例化对象去实例化成一个基类型的对象。因为基类型包含了这些子类型。相反,如下代码就有问题了。
Truct tc2 = c; //错误,怎么能说车就是卡车呢?那轿车算什么? //必须修改为下面的这种形式,将基类实例对象交给派生类时必须强类型转换为子类的类型 Truct tc2 = (Truct)c; |
小天:为什么要强类型呢?
老田:你想啊,就好像我们可以说小猫小狗是动物,但是总不能说动物是小猫小狗吧?这也就体现了C#的另外一个核心概念---多态。
小天:这个问题为什么说是多态,我还是有点不明白,你每次都实例化了不同的类型,然后去调用这些类型中都存在的方法,这凭什么说是C#编译器做了什么判断呢?
老田:恩,这个问题问得好,来看下面的实例:
class A { public virtual string Method() //一个虚方法 { return "A.Method()"; } } class B:A {//类B中有两个方法,一个是重写父类的Method方法,另外还有一个自己的 public override string Method() //重写基类的虚方法 { return "B.Method()"; }
public string New_Method() { return "B.New_Method()"; } } |
接下来,申明一个A类的对象引用,用B类来实例化,然后使用,效果如图4-31
图4-31
猛然一看没有什么,仔细一看,顿时就惊呆了。因为B类中明明还有一个叫New_Method()的方法,而且这个方法是公开的,可为什么用B类实例化之后的对象引用却找不到呢?其实很简单,因为A类中并未有这个叫New_Method()的方法,而当前的对象实例a虽然是B类实例化的,可它的类型却是标准的A类型。
小天:晕死了,这可不是,其实这是因为中间实现了一次隐式的类型转换。如果现在我们希望让实例a在变成B类型,还必须强类型装换才行,如下:
A a = new B(); B b = a; //错误 B b = (B)a; //正确 |
小天:我告非,你还没有回答我第三个问题呢,怎么又提到什么虚方法和重写了?
本文章为天轰穿原创作品,转载请注明出处及作者。