黑马程序员技术交流社区

标题: 重载和子类转换基类问题(看代码) [打印本页]

作者: aynulily    时间: 2014-3-22 16:58
标题: 重载和子类转换基类问题(看代码)
看到这样的代码
public class Base
    {
        public virtual void Hello()
        {
            Console.Write("Base");
        }
    }
public class Sub : Base
    {
        public override void  Hello()
        {
            Console.Write("Sub");
        }
    }
public class a
{


    static void Main()
    {
        Base b = new Base();
        b.Hello();
        Sub s = new Sub();
        s.Hello();
        Base b2 = new Sub();
        b2.Hello();        
        Console.Read();

    }
}

结果是:Base  Sub Sub.

我想知道最后一个Sub 是怎样出来的。
先说一下我的理解(理解不正确,请帮我看看哪出错了):第三个调用 构造了一个Sub类的实例,同时也实例化了一个Base类,两者在托管堆中的位置,相当于大圆套小圆,Base是小圆,都有Hello(),但内容不同(重载了),而 b2 是Base类,就会指向那个小圆的地址,从而执行 基类的方法,而输出Base。(但是事实上不是啊,哪错了?)
作者: 白夜行    时间: 2014-3-22 17:31
第三个 b2 应该是 Base 类型的一个引用变量,但它指向的是 Sub 的一个实例,Sub是它的子类,由于它指向子类的实例,所以在调用方法的时候子类的方法将父类的方法重写,所以输出的是Sub;
作者: mdb    时间: 2014-3-22 17:35
都是引用类型,base类型的变量其实是指向SUB类实例,子类方法又对父类方法进行重写了,所以就使用子类的方法输出。
作者: 百川    时间: 2014-3-22 18:47
我是这么理解的:
重写时。两者在托管堆中的位置,相当于大圆套小圆,Base是小圆,Sub是大圆。由于执行Base b2 = new Sub();时指向的首地址为小圆和大圆想同的首地址,
b2的类型为Base,所以范围为小圆。但是此时大圆依旧存在于小圆的外面。
由于Base中的方法为virtual所以此时在大圆的范围内搜索override。如果存在就是重写,执行override方法,如果不存在就返回,为隐藏父类方法。


作者: 鬼鬼    时间: 2014-3-23 23:25
我对这句:
  1. Base b2 = new Sub();
复制代码

的理解是这样的:
  1. Sub temp = new Sub();
  2. Base b2 = temp;
复制代码

由于多态的存在,父类引用可以指向子类对象,所以最后是调用了子类中的方法。

另外建议楼主不要去想什么大圆小圆的,因为所有对象类型本质都是引用,不可能存在嵌套关系。如果真的想追根求底,可以关注一下程序底层真正的运行方式,比如运行时多态什么的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2