帮助覆盖和inheritance

好的,在我学习的时候,请耐心地跟着我和男孩们。 这是我的问题。

我无法弄清楚为什么我不能从父类重写方法。 这是来自基类的代码(是的,我从OOP书中窃取了java代码,并试图用C#重写它)。

using System; public class MoodyObject { protected String getMood() { return "moody"; } public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } } 

这是inheritance基类(MoodyObject)的其他2个对象:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class SadObject: MoodyObject { protected String getMood() { return "sad"; } //specialization public void cry() { Console.WriteLine("wah...boohoo"); } } } 

和:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class HappyObject: MoodyObject { protected String getMood() { return "happy"; } public void laugh() { Console.WriteLine("hehehehehehe."); } } } 

这是我的主要内容:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { MoodyObject moodyObject = new MoodyObject(); SadObject sadObject = new SadObject(); HappyObject happyObject = new HappyObject(); Console.WriteLine("How does the moody object feel today?"); moodyObject.queryMood(); Console.WriteLine(""); Console.WriteLine("How does the sad object feel today?"); sadObject.queryMood(); sadObject.cry(); Console.WriteLine(""); Console.WriteLine("How does the happy object feel today?"); happyObject.queryMood(); happyObject.laugh(); } } } 

正如你所看到的,非常基本的东西,但这是输出:

今天喜怒无常的物体感觉如何? 我今天心情郁闷!

今天伤心的物体感觉如何? 我今天心情郁闷! 华…号泣

幸福的对象今天有何感受? 我今天心情郁闷! hehehehehehe。 按任意键继续 。 。 。

不像我预期的那样。 我试图使基本方法虚拟并在尝试覆盖它时调用覆盖,这只是让我得到这个错误“无法覆盖inheritance的成员’MoodyObject.getMood()’,因为它没有标记为虚拟,抽象或覆盖”。 我也没有虚拟和覆盖尝试它,它认为我试图隐藏基本方法。 再说一遍,我是OOP的新手并且非常感谢任何指导。

编辑添加:我找到了! MoodyObject.cs只是解决方案资源管理器中的“解决方案项”,而不是“ConsoleApplication1”项。 我将它拖到解决方案资源管理器所属的位置并瞧! 它现在有效。 我在下面将Luc的答案标记为答案,因为他提供了我需要的帮助,以便我能够解决问题…我在这里学到了很多东西。 这太棒了,你们和女孩们都很聪明!

在C#中,默认情况下方法不是虚拟的,因此如果将某个方法设计为可覆盖,则应将其指定为虚拟方法:

 class Base { protected virtual string GetMood() {...} } 

其次,您必须指定要在派生类中从基类重写方法。

 class Derived : Base { protected override string GetMood() {...} } 

如果你没有指定“override”关键字,你将获得隐藏基类型的方法(以及编译器的警告,为方法显示“new”关键字以明确说明)。

如果要停止inheritance链并禁止进一步覆盖该方法,则应将方法标记为已密封,如下所示:

  protected sealed override string GetMood() {...} 

您需要使用override关键字来覆盖任何虚拟或实现任何抽象方法。

 public class MoodyObject { protected virtual String getMood() { return "moody"; } public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } } public class HappyObject : MoodyObject { protected override string getMood() { return "happy"; } } 

我在这里推荐的是,你有意将MoodyObject作为一个抽象类。 (如果你这样做,你必须改变你的主要方法,但你应该去探索它)在情绪模式下真的有意义吗? 我们上面的问题是你的HappyObject不需要为getMood提供一个实现。通过使一个类抽象,它做了几件事:

  1. 你不能新建一个抽象类的实例。 你必须使用子类。
  2. 您可以强制派生子项实现某些方法。

所以要做到这一点你最终:

 public abstract class MoodyObject { protected abstract String getMood(); public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } } 

请注意您不再为getMood提供实现。

据我所知,在Java中,默认情况下所有方法都是虚拟的。 这不是C#的情况,因此您需要使用“virtual”标记基类方法,例如protected virtual string getMood() ...以及带有“override”的覆盖,例如protected override string getMood()...

如果要覆盖基类方法,则需要将其声明为virtual 。 派生类中的重写方法必须显式声明为override 。 这应该工作:

 public class BaseObject { protected virtual String getMood() { return "Base mood"; } //... } public class DerivedObject: BaseObject { protected override String getMood() { return "Derived mood"; } //... } 

编辑:我刚刚在ac#console应用程序中尝试过,它编译。 因此,您使用的源代码应该与您在此处发布的内容有所不同。

我的program.cs是这样的:

 using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { // leaving out your implementation to save space... } } public class SadObject : MoodyObject { protected override String getMood() { return "sad"; } //specialization public void cry() { Console.WriteLine("wah...boohoo"); } } public class HappyObject : MoodyObject { protected override String getMood() { return "happy"; } public void laugh() { Console.WriteLine("hehehehehehe."); } } } 

您需要告诉C#您的对象是否覆盖了基类中的函数。

以下是有关您需要的语法的MSDN文章: http : //msdn.microsoft.com/en-us/library/ebca9ah3(VS.71).aspx

 public class SadObject: MoodyObject { override String getMood() 

通过在Moody中使用GetMood virtual方法并在派生类中override ,您的代码应该可以正常工作。 您确定将这些关键字放在他们所属的位置吗? 这是完整的代码,编译和运行就好了:

 public class MoodyObject { protected virtual String getMood() { return "moody"; } public void queryMood() { Console.WriteLine("I feel " + getMood() + " today!"); } } public class SadObject : MoodyObject { protected override String getMood() { return "sad"; } //specialization public void cry() { Console.WriteLine("wah...boohoo"); } } public class HappyObject : MoodyObject { protected override String getMood() { return "happy"; } public void laugh() { Console.WriteLine("hehehehehehe."); } } class Program { static void Main(string[] args) { MoodyObject moodyObject = new MoodyObject(); SadObject sadObject = new SadObject(); HappyObject happyObject = new HappyObject(); Console.WriteLine("How does the moody object feel today?"); moodyObject.queryMood(); Console.WriteLine(""); Console.WriteLine("How does the sad object feel today?"); sadObject.queryMood(); sadObject.cry(); Console.WriteLine(""); Console.WriteLine("How does the happy object feel today?"); happyObject.queryMood(); happyObject.laugh(); Console.Read(); } } 

也许你的错误来自这样一个事实,即在Java中,所有方法都是虚拟的,而C#并非如此(正如Dan C.所指出的那样)。

 public class SadObject: MoodyObject { override String getMood() 

您需要使用“override”关键字标记getMood的覆盖。 您还需要使用“virtual”关键字标记基本getMood方法。