我有这个实验代码:
interface I { string ToString(); }
class TestI : I {
public override string ToString() { return "Hello"; }
}
abstract class A1 { public override abstract string ToString(); }
class TestA1 : A1 {
public override string ToString() { return "world!"; }
}
abstract class A2 { public new abstract string ToString(); }
class TestA2 : A2 {
public override string ToString() { return "world!"; }
}
class Program {
static void Main(string[] args) {
TestI ti = new TestI();
I i = ti;
Console.WriteLine(ti); Console.WriteLine(i); //predictable writes "Hello"
TestA1 ta1 = new TestA1();
A1 a1 = ta1;
Console.WriteLine(ta1); Console.WriteLine(a1); //predictable writes "world!"
TestA2 ta2 = new TestA2();
A2 a2 = ta2;
Console.WriteLine(ta2); Console.WriteLine(a2); //writes "ConsoleApplication1.TestA2"
Console.WriteLine(ta2.ToString()); Console.WriteLine(a2.ToString()); //good
Console.ReadLine();
}
}
为什么new
关键字会在#3的情况下中断方法ToString()
?
我理解方法Console.Write
有ToString(params object[])
之类的签名,并使用object.ToString()
实现。
在这种情况下,如何强制正确覆盖ToString()
?
我不打算使用案例#4。
答案 0 :(得分:0)
如果是Console.WriteLine(a2); Console.WriteLine方法中的a2的编译时类型是一个对象,因为调用了一个对象的重载。由于您没有重写对象的ToString()方法,因此调用对象中的默认ToString()。您没有覆盖对象上的ToString(),因为您通过“new”关键字(用于隐藏父类的方法)将方法隐藏在抽象类中来打破链。
答案 1 :(得分:0)
不是试图强迫人们覆盖ToString
,而是为了不只是在你的类上有一个调用抽象方法的基本实现。例如:
abstract class Base
{
protected abstract string GetMessage();
public sealed override string ToString()
{
return GetMessage();
}
}
class Derived : Base
{
protected override string GetMessage()
{
return "hello";
}
}
现在你不是想欺骗编译器,任何使用你的类的人都会明白他们必须做的事情。