晕了,为何ToString必须加上override

乐百川 2015-03-19 10:43:22
class Test
{
private string str;
public string Str
{
get
{
return str;
}
set
{
str = value;
}
}
public Test()
: this("123")
{

}
public Test(string str)
{
this.str = str;
}
public override string ToString()
{
return Str;
}
/*
* public string ToString()
{
return Str;
}
* public new string ToString()
{
return Str;
}
*/
}
class Program
{
public static void Main(String[] args)
{
Test a, b;
a = new Test();
b = a;
Console.WriteLine("{0} {1} ", a, b);
a.Str = "555";
Console.WriteLine("{0} {1} ", a, b);
}
}

注释掉的那两个,显示结果是名字空间名.加类名,我感觉既然我使用的是Test对象,那么在输出中也应该调用的是我定义的那个,为何会调用object中的Tostring呢,求解
...全文
751 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
K-dash 2015-03-22
  • 打赏
  • 举报
回复
哈哈,楼主是不是用过JAVA或PHP所以不习惯这样,JAVA和PHP重写父类的方法时是不用加的,调用的时候默认调用最终类声明的这个方法
wangmoxhn 2015-03-20
  • 打赏
  • 举报
回复
所有的虚函数都在一个虚函数指针的地方。 Object的ToString是个虚函数 所以它的地址就放在虚函数地址中。 任何子类如果想覆盖掉这个虚函数地址中的函数,必须使用override关键字。这样在初始化一个子类的时候,就会用这个新的地址覆盖掉父类中的函数地址。 而不加的override 关键字的函数,只存在于子类自己的函数地址中。尽管他们是同名的。 比如: Object的ToString 在地址0x0001 子类的ToString在地址0x0002 虚函数指针的地址0x0005 如果不加override 0x0005里存放的是0x0001 加了override 后,0x0005里存放的0x0002 这样调用ToString的时候 发现它是个虚函数,就在虚函数地址0x0005这里调用,而此时这里的地址已经是子类的ToString的地址了,所以调用你的自定义的ToString
乐百川 2015-03-20
  • 打赏
  • 举报
回复
我刚才又看了一下C#入门经典,再结合各位说的,好像明白了一点。在Console.WriteLine中有对象的话,会调用object.ToString,除非自己重写(override)了新的ToString,如果显示调用ToString的话比如a.ToString这样就会根据a的类型判断到底是调用的哪个版本,我这样理解对吗
thisishexiao 2015-03-20
  • 打赏
  • 举报
回复
语法就是这么规定的。。。 所以你应该首先接受这个事实:重写父类中的方法,就必须添加修饰符override(或new) 然后再去搞清楚:重写方法后,不同类型的对象调用的是哪里的方法。 比如:定义为父类型的对象,定义为子类型的对象,定义为父类型但用子类型对象初始化的对象等。
乐百川 2015-03-20
  • 打赏
  • 举报
回复
我好像问题没说明白。我知道在C++里,子类的函数会隐藏父类的函数,这样在用子类指针调用的时候不管这个函数是不是虚的都会调用子类的版本。但是再用基类指针指向子类对象的时候仍然会调用基类的函数版本,要实现多态性就要把函数声明成虚的,这样编译器就会自动识别要调用的版本。可是在C#里面,就拿我上面那个例子,我没有重写object类的ToString,所以应该是隐藏了object的ToString才对, 为何在WriteLine一句中,显示的仍然是object.ToString版本,而不是我写的Test.ToString,不知道我这次说清楚了没
於黾 2015-03-20
  • 打赏
  • 举报
回复
引用 15 楼 u011054333 的回复:
[quote=引用 5 楼 caozhy 的回复:] 如果不加,那么如果这么写 object obj = new Test(); obj.ToString()怎么调用你写的版本呢?
抱歉我好像没说明白。这个语句当然会调用object,我想知道的是Console.WriteLine("{0} {1} ", a, b);这句为什么还是调用object的函数,难道只有我写成Console.WriteLine("{0} {1} ", a.ToString(), b);才会调用我自己的吗(在不用override的情况下)[/quote] 你那样的写法是隐式转换, 到底自动调用object的ToString方法,还是a对象的ToString方法,自己加个断点看看就知道了
乐百川 2015-03-20
  • 打赏
  • 举报
回复
引用 5 楼 caozhy 的回复:
如果不加,那么如果这么写 object obj = new Test(); obj.ToString()怎么调用你写的版本呢?
抱歉我好像没说明白。这个语句当然会调用object,我想知道的是Console.WriteLine("{0} {1} ", a, b);这句为什么还是调用object的函数,难道只有我写成Console.WriteLine("{0} {1} ", a.ToString(), b);才会调用我自己的吗(在不用override的情况下)
异常异长 2015-03-20
  • 打赏
  • 举报
回复
想自己写 当然要重写覆盖掉原来的方法
於黾 2015-03-20
  • 打赏
  • 举报
回复
其实我知道楼主纠结的不是如何重写,而是为什么要重写 你把继承,子类,父类,弄明白了,就知道了
剑农 2015-03-20
  • 打赏
  • 举报
回复
重写ToString()
郗晓勇 2015-03-20
  • 打赏
  • 举报
回复
Eiceblue 2015-03-20
  • 打赏
  • 举报
回复
看7楼7楼啊,就是因为你重写所以才要override,这样才是调用你写的ToString(),而不是Object的啊。
於黾 2015-03-20
  • 打赏
  • 举报
回复
已经告诉你所有类都继承自object了,还不明白的话,那就不是逻辑关系没捋顺,而是基础知识不牢靠
於黾 2015-03-20
  • 打赏
  • 举报
回复
引用 4 楼 u011054333 的回复:
引用 2 楼 zujinsheng 的回复:
因为 ToString()方法来自 Object类, 所有的类都隐式的继承了Object.. 要重写ToString()方法, 必须要使用override关键字..
可是我又重新定义了,在我的类里使用难道不是应该先选择我已经定义的吗。如果不重写只能调用object里的tostring的话那什么时候才能调用注释中的那两个函数呢
看来你需要恶补关于继承的知识 子类如何重写父类的函数
为轮子而生 2015-03-20
  • 打赏
  • 举报
回复
你的Test也是一个类,而object是所有类的基类,所以你的Test是继承自object的,如果没有特别规定ToString()方法,调用ToString()的时候,就会自动调用基类的ToString(),但若是要“特别规定”,就是重写,当然要override。 建议你查阅学习一下继承、接口这几个概念,并自己动手写几个具有相互继承关系的类,不懂这几个概念,你现在的“编程”不能称之为“编程”
  • 打赏
  • 举报
回复
你这是在重写ToString()方法,当然要使用override了
於黾 2015-03-20
  • 打赏
  • 举报
回复
到底会不会调用你重新的方法,加个断点不就知道了,乱猜干什么
tcmakebest 2015-03-20
  • 打赏
  • 举报
回复
用 override 就是返回 Str, 楼主确定了没
threenewbee 2015-03-20
  • 打赏
  • 举报
回复
引用 15 楼 u011054333 的回复:
[quote=引用 5 楼 caozhy 的回复:] 如果不加,那么如果这么写 object obj = new Test(); obj.ToString()怎么调用你写的版本呢?
抱歉我好像没说明白。这个语句当然会调用object,我想知道的是Console.WriteLine("{0} {1} ", a, b);这句为什么还是调用object的函数,难道只有我写成Console.WriteLine("{0} {1} ", a.ToString(), b);才会调用我自己的吗(在不用override的情况下)[/quote] 概念不清,还当然会调用object,应该是当然不会调用才对。vitrual是什么意思?
江南小鱼 2015-03-20
  • 打赏
  • 举报
回复
一般需要override ToString方法的是自定义类,方便把某个字段装箱使用,比如

class Test
{
public int ID {get;set;}

public string Name {get;set;}

public override string ToString()
{
      return ID.ToString();
}

}
加载更多回复(6)

110,547

社区成员

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

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

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