Gre*_*egD 23 c# inheritance overriding
好的,在我学习的时候,请跟我们男孩和女孩们一起.这是我的问题.
我无法弄清楚为什么我不能从父类重写方法.这是来自基类的代码(是的,我从OOP书中窃取了java代码,并试图用C#重写它).
using System;
public class MoodyObject
{
protected String getMood()
{
return "moody";
}
public void queryMood()
{
Console.WriteLine("I feel " + getMood() + " today!");
}
}
Run Code Online (Sandbox Code Playgroud)
这是继承基类(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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
和:
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.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的主要内容:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,非常基本的东西,但这是输出:
今天喜怒无常的物体感觉如何?我今天心情郁闷!
今天伤心的物体感觉如何?我今天心情郁闷!华...号泣
幸福的对象今天感觉如何?我今天心情郁闷!hehehehehehe.按任意键继续 ...
不像我预期的那样.我试图使基本方法虚拟并在尝试覆盖它时调用覆盖,这只是让我得到这个错误"无法覆盖继承的成员'MoodyObject.getMood()',因为它没有标记为虚拟,抽象或覆盖".我也尝试了没有虚拟和覆盖,它认为我试图隐藏基本方法.再说一遍,我是OOP的新手,并会感谢任何指导.
编辑添加:我找到了!MoodyObject.cs只是解决方案资源管理器中的"解决方案项",而不是"ConsoleApplication1"项.我把它拖到解决方案资源管理器所属的位置,瞧!它现在有效.我在下面将Luc的答案标记为答案,因为他提供了我所需要的帮助,以便我解决问题......我在这里学到了很多东西.这太棒了,你们和女孩们都很聪明!
Ily*_*kov 61
在C#中,默认情况下方法不是虚拟的,因此如果将某个方法设计为可覆盖,则应将其指定为虚拟方法:
class Base
{
protected virtual string GetMood() {...}
}
Run Code Online (Sandbox Code Playgroud)
其次,您必须指定要在派生类中重写基类中的方法.
class Derived : Base
{
protected override string GetMood() {...}
}
Run Code Online (Sandbox Code Playgroud)
如果你没有指定"override"关键字,你将获得隐藏基类型的方法(以及编译器的警告,为方法显示"new"关键字以明确说明).
如果要停止继承链并禁止进一步覆盖该方法,则应将方法标记为已密封,如下所示:
protected sealed override string GetMood() {...}
Run Code Online (Sandbox Code Playgroud)
您需要使用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";
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里推荐的是,你有意将MoodyObject作为一个抽象类.(如果你这样做,你必须改变你的主要方法但是你应该去探索它)在喜怒无常的模式中真的有意义吗?我们上面的问题是你的HappyObject不需要为getMood提供一个实现.通过使一个类抽象,它做了几件事:
所以要做到这一点你最终:
public abstract class MoodyObject
{
protected abstract String getMood();
public void queryMood()
{
Console.WriteLine("I feel " + getMood() + " today!");
}
}
Run Code Online (Sandbox Code Playgroud)
请注意您不再为getMood提供实现.
据我所知,在Java中,默认情况下所有方法都是虚拟的.这不是C#的情况,因此您需要使用"虚拟"标记基类方法,例如protected virtual string getMood() ...,使用"覆盖"覆盖,例如protected override string getMood()....