A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© aynulily 中级黑马   /  2014-3-22 16:58  /  1181 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看到这样的代码
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。(但是事实上不是啊,哪错了?)

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1

查看全部评分

4 个回复

倒序浏览
第三个 b2 应该是 Base 类型的一个引用变量,但它指向的是 Sub 的一个实例,Sub是它的子类,由于它指向子类的实例,所以在调用方法的时候子类的方法将父类的方法重写,所以输出的是Sub;

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1

查看全部评分

回复 使用道具 举报 0 1
都是引用类型,base类型的变量其实是指向SUB类实例,子类方法又对父类方法进行重写了,所以就使用子类的方法输出。
回复 使用道具 举报
我是这么理解的:
重写时。两者在托管堆中的位置,相当于大圆套小圆,Base是小圆,Sub是大圆。由于执行Base b2 = new Sub();时指向的首地址为小圆和大圆想同的首地址,
b2的类型为Base,所以范围为小圆。但是此时大圆依旧存在于小圆的外面。
由于Base中的方法为virtual所以此时在大圆的范围内搜索override。如果存在就是重写,执行override方法,如果不存在就返回,为隐藏父类方法。

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1

查看全部评分

回复 使用道具 举报
我对这句:
  1. Base b2 = new Sub();
复制代码

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

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

另外建议楼主不要去想什么大圆小圆的,因为所有对象类型本质都是引用,不可能存在嵌套关系。如果真的想追根求底,可以关注一下程序底层真正的运行方式,比如运行时多态什么的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马