精诚所至,金石为开!
问题:1、初始化一实例:baseClass tempClass=new derivedClass()之后,会输出什么结果?2、把derivedClass类中的override换成 new之后,又会输出什么结果?
正确答案:1、value!=22、Method1 in baseClassMSDN上说:new 关键字在用作修饰符时,可以显式隐藏从基类继承的成员。隐藏继承的成员意味着该成员的派生版本将替换基类版本。也就是说,在用new关键字时,派生类与基类的这两个相同签名的方法已经没有任何联系了。而用override时,它与new的区别主要是,overrid是重写了基类的方法,new是隐藏、覆盖了基类的方法。。
posted on 2007-11-07 17:10 任力 阅读(519) 评论(15) 编辑 收藏 所属分类: C、.NET Framework 、B、ASP.NET 2.0
我觉得你说得还不是很清楚 new是隐藏当前类继承来的方法,隐藏的原来方法还是存在 baseClass baseClass=new derivedClass(); 会执行 Method1 in baseClass override这是重写原来的方法 baseClass baseClass=new derivedClass(); 以就是重写后的方法 value!=2 回复 引用 查看
@無尽海 可能是吧,我对new与override的区别也只是了解个大概。谢谢指导。。 回复 引用
我觉得还是有问题的. baseClass aa = new derivedClass();之后 override的结果为: value!=2,value==2 new的结果为:Method1 in baseClass,Method1 in baseClass; derivedClass bb = new derivedClass();之后 new的结果为:Method1 in baseClass;value==2 override的结果为: value!=2,value==2 回复 引用
override是重写方法,无论是基类对象还是派生类对象都将调用重写后的方法. new只是隐藏基类的方法,派生类看不到而已.但是基类对象还是调用自已原来的方法,派生类调用new之后的方法. Jack Lee以后就是我的网名了.我是河南科技学院三月软件工作室的一员,我的名子是常军伟 回复 引用
(new)“隐藏”,(override)“覆盖”(重写),一楼说的有道理。不够要弄清楚这两个有什么区别确实也很难,因为它们的子类在使用的父亲的方法的时候根本看不出什么区别,反正子类不管父类是new了还是override了用的都是父类的方法。区别就在于,用父类的类型指针去访问子类的成员的时候有区别。 本质区别就是,一个子类的对象中,如果是new的,那么父类的这个函数地址仍然保留着,同时又提供了一个新的子类的该函数入口地址。也就是说子类对象中同时保存了两个入口地址,父类的该函数地址被“隐藏”,但是它还可以用父类的类型指针访问得到,用子类类型指针访问该函数则进入new出来那个函数入口。 如果是override的,表示对象中的这个地址是被改写的,也就是说子类中只能访问到自己定义的函数了。而base的函数地址我们现在没有办法拿到了,因为函数表这个地址被指向了自己定义的函数。因此只能访问到自身定义的该函数。 再向下继承的子类指针就和普通继承一样,没什么好说的了。 回复 引用 查看
给你一段代码,你可以自己去测试一下,并想想结果。变量的命名规则是“指针类型_实际对象类型”,例如ba_c1表示这是一个指向c1对象的ba类型指针。c1_c1表示这是指向c1对象的c1类型指针。ba是base的缩写。 static void Main(string[] args) { BaseClass ba_c1 = new ChildClass1(); BaseClass ba_c2 = new ChildClass2(); //ChildClass1 c1_c3 = new ChildClass3(); ChildClass1 c1_c1 = (ChildClass1)ba_c1; ChildClass2 c2_c2 = (ChildClass2)ba_c2; // override Console.Write("ba_c1:"); ba_c1.Func1(); Console.Write("c1_c1:"); c1_c1.Func1(); // new Console.Write("ba_c2:"); ba_c2.Func1(); Console.Write("c2_c2:"); c2_c2.Func1(); Console.ReadLine(); } } public class BaseClass { public virtual void Func1() { Console.WriteLine(" Base.F1"); } } //改写Base.Func1的入口地址为ChildClass1.Fun1的地址。 public class ChildClass1 : BaseClass { public override void Func1() { Console.WriteLine(" (overrided) C1.myF1"); } } //ChildClass2.Fun1是一个新的入口地址,不会覆盖base.Fun1的地址。 public class ChildClass2 : BaseClass { public new void Func1() { Console.WriteLine(" (new) C2.newF1"); } } 回复 引用 查看
上面的代码运行结果是: ba_c1: (overrided) C1.myF1 c1_c1: (overrided) C1.myF1 ba_c2: Base.F1 c2_c2: (new) C2.newF1 可以看到,override的时候,父类指针的该函数地址被改写了,因此不管用父类还是子类的指针,进入的都是子类定义的函数。 而new时,用父类指针访问到的是父类定义的函数,用子类指针访问到的是自己定义的函数。因为对象中两个函数的地址可以用不同类型指针进行获取。 回复 引用 查看
override: 函数名: 地址 Base.F1: =C1.F1 C1.F1: ******** new: Base.F1: ******** C2.F1 : ******** 一个子类对象 _______________________________________________ |... ___________________......................................| |...|父类成员...................| .....子类成员.....................| |... --------------------- .......................................| |______________________________________________| ............................|...............................| ..................override一个地址.............new一个地址在此处 请注意:访问成员函数的大概过程可以比喻为,基址->成员函数,->操作符将查函数地址表得到偏移量,返回该成员函数的入口地址,代码跳转到此处。->操作符在访问成员变量时,将返回一个和右边变量的类型像匹配的指针或数据类型。 回复 引用 查看
@Jack Lee override是重写方法,无论是基类对象还是派生类对象都将调用重写后的方法. new只是隐藏基类的方法,派生类看不到而已.但是基类对象还是调用自已原来的方法,派生类调用new之后的方法. 没错,override与new是这样理解的。至于下面这几句: 我觉得还是有问题的. baseClass aa = new derivedClass();之后 override的结果为: value!=2,value==2 new的结果为:Method1 in baseClass,Method1 in baseClass; derivedClass bb = new derivedClass();之后 new的结果为:Method1 in baseClass;value==2 override的结果为: value!=2,value==2 就不对了, 首先,将子类对象不论是赋给本身类的对象,还是基类的对象,它的结果应是一样的(生成对象时)。但涉及到override于new,当它调用方法时,结果才可能不一样。 再则,创建对象时,Method1()方法只可能执行一次,不可能有两个结果。 看一下它的执行过程: baseClass aa = new derivedClass(); override时, 执行顺序:derivedClass.Method1()(基类的被覆盖了)-->derivedClass(); 所以结果应该是value!=2 new时, 执行顺序:baseClass.Method1()-->derivedClass(); 所以结果应该是:Method1 in baseClass 回复 引用 查看
题目里面加了一个value成员,应该是考你new一个对象时候的调用顺序,先父类构造函数,再子类构造函数。还有就是定义时未赋值时,value的默认初始值是0,指针是NULL。 回复 引用 查看
@hoodlum1980 是的。分析的不错。 考的是创建对象的调用顺序。value的默认初始值是0,指针是null。 回复 引用 查看
偶明白了!!! 回复 引用 查看
看了大家的回复也发下我的理解 两个考点:基类继承类调用和(new override)。 且看上面试题,姑且把这两个类分别叫 baseClass 基类, derivedClass 派生类 这个时候,我们明确一下派生类的概念,派生类既有自己的特性又有基类的特性。(其实派生类这个对象同时具有两个类的数据和行为,把这种能力我们称为多态性。) 好了,看试题. 1、初始化一实例:baseClass tempClass=new derivedClass()之后,会输出什么结果? 这里我们看到实际是(new derivedclass)结果赋给tempclass. 这个时候看derivedClass类override基类的方法method1() 执行: 从基类method1()-->派生类重写基类的Method1()显示的结果就是:value!=2; 其实这个时候派生类会继续着执行DerivedClass()方法,结果:value的值为2.到此类执行完毕. 2.、把derivedClass类中的override换成 new之后,又会输出什么结果? msdn:new 和 override这两个修饰符在含义上相互排斥。使用 new 会用同样的名称创建一个新成员并使原始成员变为隐藏的,而 override 则扩展继承成员的实现。 如果继承类使用new method1() 只能说是继承类自己创建了以个新方法,和基类没关系了. 执行: 从基类method1()-->基类public virtual void Method1()显示的结果就是:Method1 in baseClass; 至于派生类的new method1()这个原本是基类的成员被隐藏掉了.如果想访问,可以把派生类的实例直接访问。 不知道我的理解有什么错误地方,请指正. 回复 引用 查看
那构造函数也执行了啊,不是给value重新赋值了吗??怎么结果?? 回复 引用 查看
哦,明白了,输出结果是对的,我以为是问value的值呢,SORRY! 学习了!! 回复 引用 查看