为什么要调用基类?

时间:2010-04-30 18:04:05

标签: c# polymorphism

这是我的情况:

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.

当我如上所述运行我的代码时,输​​出只是“模糊容器”。我在这里失踪了什么?有没有更好的方法来获得理想的结果?

5 个答案:

答案 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方法”。