【新手问题】A是B的父类,A a=new B()

jy02534047 2011-07-11 10:37:12
public abstract class A
{
public A()
{
Console.WriteLine( 'A ');
}
public virtual void Fun()
{
Console.WriteLine( "A.Fun() ");
}
}
public class B: A
{
public B()
{
Console.WriteLine( 'B ');
}
public new void Fun()
{
Console.WriteLine( "B.Fun() ");
}
public static void Main()
{
A a = new B();
a.Fun();
}
}


执行结果如下:
A
B
A.Fun()



如果把class B中的Fun()的new改成override,执行结果如下:
A
B
B.Fun()



问题①:A a=new B()和B a=new B()具体有什么区别?
问题②:我知道如果是B a=new B()的话,那无论class B中Fun()是new还是override,最后输出的都会是B.Fun(),为什么换成A a=new B()就不同了?(问题还是在于A a=new B())
...全文
166 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
另外不要把面试看作考试。

事实上面试官看重的是你的悟性和理解能力,而不是看你做的答案是否标准。

对于真正理解本质,能质疑题目的,面试官印象反而好于一个只能背标准答案的书呆子。
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
那我给你个诀窍,你牢牢记住一种,并且记住另一种和它相反,即可。

反之,记住两种反而会搞反。
jy02534047 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 caozhy 的回复:]
这些所谓的游戏规则,如同故意把男女厕所的牌子交换,看人们会不会走错一样无聊。

可是有些人还研究这种规则乐此不疲:
(1)在牌子正确的情况下,正常人不会走错,傻子会走错
(2)把牌子反过来,正常人也会走错,不过进去发现不对,如果是女人会尖叫,男人会走出来骂个粗口。
[/Quote]

我完全能明白你的意思……但问题是,现在像我们这样的新人去公司面试,公司就爱出这样的面试题……虽然工作中根本就很少甚至根本就不会用到……
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jy02534047 的回复:]
引用 8 楼 caozhy 的回复:
引用 7 楼 jy02534047 的回复:
我明白你的意思,你是说初学的话只要记住“游戏规则”就好了,是吧?

那现在这个“游戏规则”是不是:
①如果是A a=new B(),那最后的输出就会和class B中Fun()是new还是override有关。
②如果是B a=new B(),那不管class B中Fun()是new还是override……
[/Quote]
我说了,等你学了面向对象就会发现,覆盖成员是基本上唯一你需要用到的,而隐藏父类,定义一个新成员方法使用的机会极低,根本在初学阶段不用考虑,更不用去了解实现过程。
你发现程序这么写,第一反应应该是写错了。
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
这些所谓的游戏规则,如同故意把男女厕所的牌子交换,看人们会不会走错一样无聊。

可是有些人还研究这种规则乐此不疲:
(1)在牌子正确的情况下,正常人不会走错,傻子会走错
(2)把牌子反过来,正常人也会走错,不过进去发现不对,如果是女人会尖叫,男人会走出来骂个粗口。
jy02534047 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 caozhy 的回复:]
引用 7 楼 jy02534047 的回复:
我明白你的意思,你是说初学的话只要记住“游戏规则”就好了,是吧?

那现在这个“游戏规则”是不是:
①如果是A a=new B(),那最后的输出就会和class B中Fun()是new还是override有关。
②如果是B a=new B(),那不管class B中Fun()是new还是override,最后输出的都会是B.Fun()。

……
[/Quote]

晕,我知道啊,但是这里父子方法重名主要是为了讨论继承、override与new等问题啊……
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
如同,假如有个类
class A
{
private int i = 0;
private void foo()
{
int i; // 如果已经有个成员变量了,你显然不会去定义一个局部变量故意和它混淆。
}
}
对于永远用不到的东西,不要去掌握什么游戏规则。虽然我可以告诉你,这么定义也是有游戏规则的,就是成员变量被隐藏了。但是有意义么?
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jy02534047 的回复:]
我明白你的意思,你是说初学的话只要记住“游戏规则”就好了,是吧?

那现在这个“游戏规则”是不是:
①如果是A a=new B(),那最后的输出就会和class B中Fun()是new还是override有关。
②如果是B a=new B(),那不管class B中Fun()是new还是override,最后输出的都会是B.Fun()。

“游戏规则”是这样么?
[/Quote]
你记住:
如果看到一个类,比如
class A
{
public void foo() { ... }
}
这个 foo 没有 virtual 修饰,对吧。
那么,如果你从这个类继承:
class B
{
public void foo() { ... } // 禁止
}
不要试图定义一个和A中成员重名的方法。永远不要这么做,除非你明白这么做的用途。

这样,就没有什么“游戏规则”了。只剩下一种情况,而如果你懂面向对象,你知道这么做就是你想要的。
jy02534047 2011-07-11
  • 打赏
  • 举报
回复
我明白你的意思,你是说初学的话只要记住“游戏规则”就好了,是吧?

那现在这个“游戏规则”是不是:
①如果是A a=new B(),那最后的输出就会和class B中Fun()是new还是override有关。
②如果是B a=new B(),那不管class B中Fun()是new还是override,最后输出的都会是B.Fun()。

“游戏规则”是这样么?
jy02534047 2011-07-11
  • 打赏
  • 举报
回复
我明白你的意思,你是说初学的话只要记住“游戏规则”就好了,是吧?

那现在这个“游戏规则”是不是:
①如果是A a=new B(),那最后的输出就会和class B中Fun()是new还是override有关。
②如果是B a=new B(),那不管class B中Fun()是new还是override,最后输出的都会是B.Fun()。

“游戏规则”是这样么?
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
底层不关你的事。

因为你不懂面向对象,去学语法就会很困难。

早在10年前,一批学生在一群误人子弟的老师的带领下,学习C++下虚函数的实现原理,什么动态联编,什么虚函数表,学来学去,云里来雾里去,换一种语言,全部没用。

如同问为什么把食物放入冰箱就冷了,放入微波炉就加热了。你从制冷和微波加热的角度去理解越理解越搞不清。如果你知道你需要保存食物,需要一种可以冷藏的设备,OK,冰箱可以满足你的要求。如果你希望食用食物,那么你需要把食物加热到可口的温度,微波炉可以帮助你。那就可以了。

对于virtual方法,你去理解为什么A类型也能调用出B类型定义的方法没有意义,你多想想编程中为什么我们需要覆盖一个方法。
jy02534047 2011-07-11
  • 打赏
  • 举报
回复
还是不太明白。能不能从底层讲一下A a=new B()和B a=new B()的区别?
ycproc 2011-07-11
  • 打赏
  • 举报
回复
好吧 caozhy 说的很明白了 很基础的理论知识
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
事实上,没有特殊原因,不要试图在子类中定义和父类中同名的方法。如同不要在方法体内声明一个和成员变量重名的变量,这是很不好的习惯。

所以看到父类的方法没有 virtual 修饰的话,就不要再定义了。
threenewbee 2011-07-11
  • 打赏
  • 举报
回复
A a=new B()和B a=new B()的区别,一个是A类型,一个是B类型,如果用A类型,则访问不到B新增的成员,如果调用非虚方法,那么调用的是A对象的那个方法。

问题2也不难理解。如果是virtual->override,那么对A类型调用方法,则子类型覆盖掉这个方法。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧