这是我的情况:
interface Icontainer{
string name();
}
abstract class fuzzyContainer : Icontainer{
string name(){
return "Fuzzy Container";
}
}
class specialContainer: fuzzyContainer{
string name(){
return base.name() + " Special Container";
}
}
Icontainer cont = new SpecialContainer();
cont.name(); // I expected "Fuzzy Container Special Container" as the output.
当我如上所述运行我的代码时,输出只是“模糊容器”。我在这里失踪了什么?有没有更好的方法来获得理想的结果?
答案 0 :(得分:17)
如果您在specialContainer中创建名称()virtual
然后override
,您将获得预期的行为。
public interface Icontainer
{
string name();
}
public abstract class fuzzyContainer : Icontainer
{
public virtual string name()
{
return "Fuzzy Container";
}
}
public class specialContainer : fuzzyContainer
{
public override string name()
{
return base.name() + " Special Container";
}
}
答案 1 :(得分:6)
首先,当您有问题发布实际编译的代码时,它会很有帮助。 当问题充满缺失修饰符和拼写错误时很难分析问题; 很难知道问题是否是错字。
一旦我们完成了修复你的程序以便它实际编译的工作,编译器会发出警告,告诉你重载看起来不对。既然你的问题是“为什么超载错了?”读取我们精确发出的编译器警告可能是个好主意,以便您可以分析这个问题。
问题是派生类包含一个名为“name”的 new 方法,而不是现有方法的 override 。这就是警告试图告诉你的。
有两种方法可以解决此问题,具体取决于您意图方法是“新”还是“覆盖”。如果您希望该方法为“覆盖”,则使基本实现成为虚拟,并使派生实现覆盖。
如果您希望该方法为“new”和,您仍然希望新方法将绑定替换为接口实现,那么使用 interface reimplementation :
class SpecialContainer: FuzzyContainer, IContainer
{
public new string Name()
{
return base.Name() + " Special Container";
}
}
注意“新”以及我们重新陈述这个类实现IContainer的事实。这告诉编译器“忽略从基类中推断出的IContainer方法的绑定并重新开始。”
答案 2 :(得分:3)
这是因为您隐藏了该方法而没有覆盖它。如果不将基本方法设为虚拟,则无法覆盖它,但您可以通过创建同名方法来“隐藏”它。
如果你有:
SpecialContainer cont = new SpecialContainer();
cont.name();
然后你也会得到你期望的输出。
Matt的答案也有效,如果您可以编辑基类以使方法成为虚拟,则可能更好。默认情况下,除非使用virtual
关键字
答案 3 :(得分:3)
您需要声明名称方法virtual并在派生类中覆盖它。
我还冒昧地用最常见的命名约定“修复”你的代码。
abstract class FuzzyContainer : IContainer{
protected virtual string GetName(){
return "Fuzzy Container";
}
}
class SpecialContainer: FuzzyContainer{
override string GetName(){
return base.GetName() + " Special Container";
}
}
答案 4 :(得分:0)
该类中的'name'方法不是FuzzyContainer的Name方法的重写。因此,当您将specialContainer对象转换为IContainer时,它只具有要调用的基类“Name方法”。