好的,在我学习的时候,请跟我们男朋友一起。这是我的问题。
我无法弄清楚为什么我不能从父类重写方法。这是来自基类的代码(是的,我从OOP书中窃取了java代码并试图用C#重写它)。
using System;
public class MoodyObject
{
protected String getMood()
{
return "moody";
}
public void queryMood()
{
Console.WriteLine("I feel " + getMood() + " today!");
}
}
以下是继承基类(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。 按任意键继续 。 。
不像我预期的那样。我试图使基本方法虚拟并在尝试覆盖它时调用覆盖,这只是让我得到这个错误“无法覆盖继承的成员'MoodyObject.getMood()',因为它没有标记为虚拟,抽象或覆盖”。我也尝试了没有虚拟和覆盖,它认为我试图隐藏基本方法。再说一遍,我是OOP的新手并且非常感谢任何指导。
编辑添加:我找到了! MoodyObject.cs只是解决方案资源管理器中的“解决方案项”,而不是“ConsoleApplication1”项。我把它拖到解决方案资源管理器所属的位置,瞧!它现在有效。我在下面将Luc的答案标记为答案,因为他提供了我所需要的帮助,以便我解决问题......我在这里学到了很多东西。这太棒了,你们和女孩们都很聪明!
答案 0 :(得分:61)
在C#中,默认情况下,方法不是虚拟的,因此如果将某个方法设计为可覆盖,则应将其指定为虚拟方法:
class Base
{
protected virtual string GetMood() {...}
}
其次,您必须指定要在派生类中从基类重写方法。
class Derived : Base
{
protected override string GetMood() {...}
}
如果你没有指定“override”关键字,你将获得隐藏基类型的方法(以及编译器的警告,为方法明确说明所谓的“new”关键字)。
如果要停止继承链并禁止进一步覆盖该方法,则应将方法标记为已密封,如下所示:
protected sealed override string GetMood() {...}
答案 1 :(得分:7)
您需要使用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提供一个实现。通过使一个类抽象,它做了几件事:
所以要做到这一点你最终:
public abstract class MoodyObject
{
protected abstract String getMood();
public void queryMood()
{
Console.WriteLine("I feel " + getMood() + " today!");
}
}
请注意您不再为getMood提供实现。
答案 2 :(得分:5)
据我所知,在Java中,默认情况下所有方法都是虚拟的。这与C#不同,因此您需要使用“virtual”标记基类方法,例如: protected virtual string getMood() ...
以及覆盖“覆盖”的覆盖,例如protected override string getMood()...
。
答案 3 :(得分:3)
如果要覆盖基类方法,则需要将其声明为virtual
。派生类中的重写方法必须显式声明为override
。这应该有效:
public class BaseObject
{
protected virtual String getMood()
{
return "Base mood";
}
//...
}
public class DerivedObject: BaseObject
{
protected override String getMood()
{
return "Derived mood";
}
//...
}
编辑:我刚刚在c#控制台应用程序中尝试过它,然后编译。因此,您使用的源代码应该与您在此处发布的内容有所不同。但
我的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.");
}
}
}
答案 4 :(得分:2)
通过在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所指出的那样)。
答案 5 :(得分:2)
您需要告诉C#您的对象正在覆盖基类中的函数。
以下是有关您需要的语法的MSDN文章:http://msdn.microsoft.com/en-us/library/ebca9ah3(VS.71).aspx
public class SadObject: MoodyObject
{
override String getMood()
答案 6 :(得分:1)
public class SadObject: MoodyObject
{
override String getMood()
答案 7 :(得分:0)
您需要使用“override”关键字标记getMood的覆盖。您还需要使用“virtual”关键字标记基本的getMood方法。