标题:关于override和new在孙子类里面调用祖父类方法差异的问题
只看楼主
cpxuvs
Rank: 3Rank: 3
等 级:论坛游侠
威 望:3
帖 子:45
专家分:142
注 册:2015-12-22
结帖率:85.71%
已结贴  问题点数:20 回复次数:4 
关于override和new在孙子类里面调用祖父类方法差异的问题
程序代码:
using System;
namespace foreachtest
{
    class program
    {
        public static void Main(string[] args)
        {
            A a=new A();
            B b=new B();
            A ab=new B();
            C c=new C();
//            a.afuc();
//            a.avfuc();
//            b.afuc();
//            b.avfuc();
//            ab.afuc();
//            ab.avfuc();
//            c.afuc();
            c.avfuc();
        }
    }
    class A
    {
        public void afuc()
        {
            Console.WriteLine("这是A的普通方法");
        }
        public virtual void avfuc()
        {
            Console.WriteLine("这是A的虚方法");
        }
    }
    class B:A
    {
        public new void afuc()
        {
            Console.WriteLine("这是B的普通方法");
        }
        public override void avfuc()
        {
//            base.avfuc();
            Console.WriteLine("这是B的虚方法");
        }
    }
    class C:B
    {
        public override void avfuc()
        {
            ((A)this).avfuc();//这里的问题
            Console.WriteLine("这是C的虚方法");
        }
        public new void afuc()
        {
            ((A)this).afuc();
            Console.WriteLine("这是c的普通方法");
        }
       

    }
}


这个程序编译通过了,但运行出错Process is terminated due to StackOverflowException.
我知道它有错,但是不是很了解原因

((A)this).avfuc()编译通过,说明了编译器的确将当前对象强制转换成了A类对象,但为什么运行时异常,是因为仍然使用的是c对象?类似多态?那new里面为什么是可以通过的?

望大神解释解释



















搜索更多相关主题的帖子: color 
2016-05-19 17:38
yhlvht
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:36
帖 子:707
专家分:4405
注 册:2011-9-30
得分:20 
编译通过表示语法上没有问题,并非确实将C强制转换成了A,只是一个类型上的转换
事实上你new的是一个C对象,即使类型转换成了A对象,但它仍然是C,存放C对象的那块内存区域里面的东西,是不会因为强转变成A对象的东西
当类型转换成了A以后,((A)this).avfuc()确实是去找A的avfuc()方法,但A的avfuc()方法是虚方法,就会去找A的子类有没有override(重写)的方法
因为当前对象C有override方法,就会直接调用C的avfuc()方法,这就无限循环下去了
如果C没有override方法,那就会找到B对象的override方法,如果B也没有,才会调用A的avfuc()方法

2016-05-19 20:18
cpxuvs
Rank: 3Rank: 3
等 级:论坛游侠
威 望:3
帖 子:45
专家分:142
注 册:2015-12-22
得分:0 
回复 2楼 yhlvht
谢谢大神,明白了一些!
请问一下,这种因为调用虚函数,会查找override的过程,是不是只会在父类类型指向子类对象是才会这么去做?
还有就是,既然这样的强制转换不能真正改变对象的类型,那是不是一个对象一旦建立,它的类型(heap上的)就无法更改了?
虽然我觉得这样干没啥意义,但是想得到一个确定的答案。
2016-05-19 21:09
yhlvht
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:36
帖 子:707
专家分:4405
注 册:2011-9-30
得分:0 
你说的是对的
override的过程,从类型开始,直到真正的对象结束,如A类型引用指向C对象,就从A开始,到C结束
heap上的对象建立后,内容就不会改变了,所以我们允许子类强转为父类类型,因为子类包含了父类的内容。而不允许父类强转为子类类型,因为heap上并没有子类的东西
2016-05-19 21:38
QQ328626969
Rank: 2
等 级:论坛游民
帖 子:8
专家分:11
注 册:2016-4-26
得分:0 
嗯。大神。。
2016-05-19 21:55



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-465017-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.137326 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved