关于继承的一个问题

chenbin6562 2010-03-25 03:25:59
以下代码主要是三个类,关系为C继承A,A继承Base类
代码如下:

public class BaseClass
{
public virtual void Method()
{
Console.WriteLine(" 基类.Method()");
}
}

public class DeriveClassA : BaseClass
{
public override void Method()
{
base.Method(); //注意这里的base
Console.WriteLine(" 类A.Method() in override");
Console.WriteLine(this.ToString());
}
}

public class DeriveClassC : DeriveClassA
{
}

class Program
{
static void Main(string[] args)
{
DeriveClassC c1 = new DeriveClassC();
c1.Method(); //这里输出
}
}


结果输出为:
基类.Method()
类A.Method() in override
DeriveClassC

==========================================

现在有个问题,一直没想清楚.
类C继承至类A,那么C也就有了那个method,而且里面的实现应该和类A里的实现是一样的,应该是也带有个base关键字,所以我觉得调用C类的方法时,首先遇到一个base,然后跳到类A中,类A又有base,又跳到最上层的基类,我预期的结果觉得应该是:
基类.Method()
类A.Method() in override
DeriveClassC
类A.Method() in override
DeriveClassC

可为什么输出结果会是只有一个,感觉只执行了一个base,这到底是base的机制还是继承的机制上的问题,望指点指点,谢谢~!

...全文
187 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
我刚刚通过反汇编后,然后单步执行和对堆栈的观察,跟踪汇编执行发现,当执行到C类的method方法时,程序是跳到了A类的method上去执行,堆栈此时也是在类A的堆栈位置上.
所以基本上可以确定继承里调用未重写的方法时,是调用基类的方法.
diegoyu 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 chenbin6562 的回复:]
恩,其实一旦确实继承方法,在未重写的情况下,是调用父类的方法,那么我的问题也就全部能解释了~!
[/Quote]
应该是这样
鸭梨山大帝 2010-03-25
  • 打赏
  • 举报
回复
不是为了交互,而是本身.NET 中的语言就是编译成MSIL(微软中间代码)的.
然后交予CLR来执行.


[Quote=引用 22 楼 peter200694013 的回复:]
引用 19 楼 wanyeyinfeng 的回复:
要分析这个建议你用il dasm打开你的exe文件看看就会很清楚,C里面到底有有没有方法的副本了。


打开后DriverClassC没有Method:void();但是有继承关系的类里面有extends DeriveClassA.
IL是中间语言,.net平台下有多种语言,为了交互,才把它们转成IL[/Quote]
chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
恩,其实一旦确实继承方法,在未重写的情况下,是调用父类的方法,那么我的问题也就全部能解释了~!
吟风 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 peter200694013 的回复:]

引用 19 楼 wanyeyinfeng 的回复:
要分析这个建议你用il dasm打开你的exe文件看看就会很清楚,C里面到底有有没有方法的副本了。


打开后DriverClassC没有Method:void();但是有继承关系的类里面有extends DeriveClassA.
IL是中间语言,.net平台下有多种语言,为了交互,才把它们转成IL
[/Quote]

所以说输出这个结果

基类.Method()
类A.Method() in override
DeriveClassC

你应该就理解了吧。
至于为什么最后一行会是DeriveClassC,而不是DeriveClassA,
这个就是多态了。
flyerwing 2010-03-25
  • 打赏
  • 举报
回复
隐藏,转换
搞不懂还是给高手能得了。
chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
我用Reflector打开看了下,C里确实也没见method
base类和A都存在那个method
Peter200694013 2010-03-25
  • 打赏
  • 举报
回复
LZ找本CLR Via C# 看看,好像是第三章有相关内容
Peter200694013 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 wanyeyinfeng 的回复:]
要分析这个建议你用il dasm打开你的exe文件看看就会很清楚,C里面到底有有没有方法的副本了。
[/Quote]

打开后DriverClassC没有Method:void();但是有继承关系的类里面有extends DeriveClassA.
IL是中间语言,.net平台下有多种语言,为了交互,才把它们转成IL
吟风 2010-03-25
  • 打赏
  • 举报
回复


加油加油
chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 wanyeyinfeng 的回复:]
要分析这个建议你用il dasm打开你的exe文件看看就会很清楚,C里面到底有有没有方法的副本了。
[/Quote]

看来还是偷不了这个懒要去学IL了~~呵呵~
吟风 2010-03-25
  • 打赏
  • 举报
回复
要分析这个建议你用il dasm打开你的exe文件看看就会很清楚,C里面到底有有没有方法的副本了。
思年华 2010-03-25
  • 打赏
  • 举报
回复
DeriveClassC 没有重写Method方法,就调用A的,A会先调用BaseClass的,所以输出基类.Method()
然后调用自己的输出类A.Method() in override DeriveClassA,但是注意多态的利用,所以输出的应该是DeriveClassC
chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
看来还是和继承的方法调用有关系~!C究竟是自己本身有副本了,还是在运行时调用的是A类的method~
Peter200694013 2010-03-25
  • 打赏
  • 举报
回复
from msdn:

GetType()
return the Type instance that represents the exact runtime type of the current instance.
chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 peter200694013 的回复:]
DeriveClassC c1 = new DeriveClassC();
c1.Method();
Type t = c1.GetType();

MemberInfo []info = t.GetMembers();
for (int i = 0; i < info.Length; i++)
{

Console.WriteLine(info[i].Name);
}

=……
[/Quote]

从这里看出来,C里其实还是有方法的哈~~
Peter200694013 2010-03-25
  • 打赏
  • 举报
回复
由反射可以得到DeriveClassC的信息,输出表明它有Method(我觉得)

lk121815097 2010-03-25
  • 打赏
  • 举报
回复
C类 调用的是 A类的Method()方法,C类本身没有Method() 方法
Peter200694013 2010-03-25
  • 打赏
  • 举报
回复
DeriveClassC c1 = new DeriveClassC();
c1.Method();
Type t = c1.GetType();

MemberInfo []info = t.GetMembers();
for (int i = 0; i < info.Length; i++)
{

Console.WriteLine(info[i].Name);
}

============
输出:
基类.Method()
类A.Method() in override
DeriveClassC
Method //输出方法名,为什么有Method?
ToString
Equals
GetHashCode
GetType
.ctor

chenbin6562 2010-03-25
  • 打赏
  • 举报
回复
突然觉得里面不是单纯的调用了A的方法,因为后面还有一个this.tostring,显示的是C,这个就不由的觉得这个方法应该是在类C里~还望高手更详细的指点~
加载更多回复(10)

110,539

社区成员

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

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

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