在看C#高级编程第二版,有个例子看不懂,请教一下

tianhu 2007-08-20 06:34:16
using System;
namespace MortimerPhone5Funny
{
public class Customer
{
public string GetFunnyString()
{
return "Plain ordinary customer.Kaark!";
}
}

public class Nevermore60Customer:Customer
{
public new string GetFunnyString()
{
return "Nervermore60.Nevermore!";
}
}
public class MainEntryPoint
{
public static int Main(string[] args)
{
Customer Cust1;
Nevermore60Customer Cust2;
Cust1 = new Customer();
Console.WriteLine("Customer referencing Customer:"+Cust1.GetFunnyString());

Cust1 = new Nevermore60Customer();
Console.WriteLine("Customer referencing Nevermor60Customer:"+Cust1.GetFunnyString());

Cust2 = new Nevermore60Customer();
Console.WriteLine("Nevermore60Customer referencing:"+Cust2.GetFunnyString());
return 0;
}
}
}
***************************************************************************
Cust1 = new Customer();
Console.WriteLine("Customer referencing Customer:"+Cust1.GetFunnyString());

Cust1 = new Nevermore60Customer();
Console.WriteLine("Customer referencing Nevermor60Customer:"+Cust1.GetFunnyString());
这一段,Cust1先是声明为Customer的一个实例,然后声明为Nevermore60Customer的实例,在Nervermore60Customer中新的GetFunnyString()方法不是已经把基类中的方法隐藏了么,为什么还是输出基类方法的结果?
...全文
281 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
conannb 2007-08-23
  • 打赏
  • 举报
回复
学习
ycpang422 2007-08-23
  • 打赏
  • 举报
回复
我的理解是这样的:
1运行时类型
2编译时类型
对于virtual声明的方法是根据运行时类型来确定调用哪种方法,而对于非virtual方法则是根据编译时类型。
例子中GetFunnyString是一个非virtual方法,所以只与声明类型有关,
new 只是隐藏了基类方法,其实不用new也可以,只是编译时会给出一个警告,而不是错误。
xwk789xwk 2007-08-23
  • 打赏
  • 举报
回复
学习中,听各位这么的讲解,小弟也都明白其中的道理了.
wangli_cola 2007-08-23
  • 打赏
  • 举报
回复
基类:
public string GetFunnyString()
{
return "Plain ordinary customer.Kaark!";
}
子类:
public new string GetFunnyString()
{
return "Nervermore60.Nevermore!";
}

因为基类中它不是虚函数,
在子类中不是override
new 并不体现多态性
实例化对象的时候用什么类型创建的对象,调用出来就是什么类型中的函数,
这跟虚函数采用OVERRIDE进行重写就区别开来了
tianhu 2007-08-23
  • 打赏
  • 举报
回复
这两天会挺多,还要给客户写些文档什么的,反正杂七杂八的事儿挺多,中午休息的时候,翻了翻书,靠,发现我笨的还真可以
Customer Cust1;
Nevermore60Customer Cust2;
这两句话都没有注意到,这样的话就理解了我的为什么到底是为什么了
这样的话
Cust1 = new Customer()等价于Cust1 = (Customer) new Customer();
Cust1 = news Nevermore60Customer()也等价于Cust1 = (Customer) new Nevermore60Customer();
Customer Cust1是声明,那Cust1 = ...就相当于赋值了(呵呵)
回头看书,发现这么一句及其拗口的话有些蹊跷:
“如前所述,编译器总是检查变量引用数据的类型是否在决定调用哪个方法是进行了声明。”
30遍之后,恍然大悟,哦~~!原来翻译这书的人哪,在俺们农村的时候,脑袋叫驴给踢过
“编译器总是检查变量引用数据的类型,根据他们之前的声明的类型来决定调用哪个类型对应类中的方法”----这是俺理解后把这句话改了改,虽然也有脑袋被踢过的嫌疑,不过俺觉得应该没有译者那么重吧,呵呵
衷心感谢yan53125(刚毕业无工作---最艰难的时期)和went_200622110026()两位同学的热心指点,其实两位早就指出了我的疑问何在,无奈啊,脑袋被小驴踢了,竟然没有理解......
不管咋说,还是感谢各位了,包括楼上各位对方法重写方面的论述,都非常精辟哈,谢谢各位
tianhu 2007-08-22
  • 打赏
  • 举报
回复
To:went_200622110026()

那为什么
Cust2 = new Nevermore60Customer();
Console.WriteLine("Nevermore60Customer referencing:"+Cust2.GetFunnyString());
中派生类却把基类的同名方法给隐藏了
因为Cust1曾经声明为Customer类的实例么?
onlyrinoa 2007-08-22
  • 打赏
  • 举报
回复
new只是隐藏了父类方法(也可以理解为子类生成一个与父类同名的新方法) 父类方法还是存在 所以用父类声明的对象还是会采用父类的方法

如果父类方法用virtual方法 子类方法用override覆写 那么这时候就会采用子类方法 因为子类方法把父类方法覆盖了

就是一个隐藏和覆盖的区别
tianhu 2007-08-21
  • 打赏
  • 举报
回复
to楼上
汗阿,难不成这个例子有误,闷头翻书ing
yan53125 2007-08-21
  • 打赏
  • 举报
回复
Customer Cust1;
我以为关键在这里
具体我也有点晕了
tianhu 2007-08-21
  • 打赏
  • 举报
回复
To:楼上各位
关键是这里我不理解
Cust1 = new Customer();
Console.WriteLine("...");
这时候Cust1是Customer的实例
到这里,注意还是Cust1
Cust1 = new Nevermore60Customer();
Cust1不是应该变为Nevermore60Customer的实例了么
那么接下来的WriteLine语句输出的应该是Nevermore60Customer实例的方法么
ps:to:jmbkeyes168(凯思) 书上说,如果方法在基类中没有声明为virtual,仍可在派生类中提供另一个带有相同签名的方法,但新方法不会重写基类的方法,而会隐藏基类的方法
其实,我主要还是不明白,为什么一个对象,先声明为基类的实例,再声明为派生类的实例,为什么接着调用的时候,他好像还是基类的实例,呵呵,不知道我说清楚了没有,闷头翻书去,说句题外话,这书翻译的还真不是一般的垃圾,很多地方,一个句子读上好几遍,依然云里雾里的,呵呵
yan53125 2007-08-21
  • 打赏
  • 举报
回复
为楼上鼓掌
went_200622110026 2007-08-21
  • 打赏
  • 举报
回复
Cust1 = new Customer();
Cust1 = new Nevermore60Customer();
其实等价于
Cust1 = new Customer();
Cust1 = (Customer) new Nevermore60Customer();
所以在
Cust1 = new Nevermore60Customer();之后
Cust1依然调用基类的方法
yan53125 2007-08-21
  • 打赏
  • 举报
回复
有高手来总结一下就全明白了
我上面的理解是
Customer Cust1;
都是基类的对象,所以调用基类的
sadever 2007-08-20
  • 打赏
  • 举报
回复
up
yan53125 2007-08-20
  • 打赏
  • 举报
回复
子类对象会调用子类的方法,
基类对象会调用基类的方法.
jmbkeyes168 2007-08-20
  • 打赏
  • 举报
回复
重新定义的基类的方法,并未实现多态性,所以调用的是基类的。除非基类定义了vitual的方法,子类中用override基类的方法,将会运行时将会根据具体引用的对象而执行相应的方法
yan53125 2007-08-20
  • 打赏
  • 举报
回复
Customer Cust1;
Nevermore60Customer Cust2;
Cust1 = new Customer();
声明的时候,应该是声明了一个基类的对象
如果这样----
Nevermore60Customer Cust2 = new Nevermore60Customer();
(Customer )Cust2

然后再显示转换一下,你说他是调用哪个方法呢?
我只是说一下我的理解,请楼下继续

111,125

社区成员

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

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

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