C# 中的重写和继承
好吧,在我学习的过程中,请耐心等待。 这是我的问题。
我不明白为什么我不能重写父类的方法。 这是基类的代码(是的,我从 OOP 书中窃取了 Java 代码,并尝试用 C# 重写它)。
using System;
public class MoodyObject
{
protected String getMood()
{
return "moody";
}
public void queryMood()
{
Console.WriteLine("I feel " + getMood() + " today!");
}
}
这是我的另外 2 个继承基类 (MoodyObject) 的对象:
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();
}
}
}
如您所见,非常基本的东西,但这是输出:
这个喜怒无常的物体今天感觉如何? 我今天心情不好!
悲伤的物体今天感觉如何? 我 今天心情郁闷! 哇...嘘
快乐的物体今天感觉如何? 我今天心情不好! 呵呵呵呵呵呵。 按任意键继续 。 。 .
不像我预期的那样。 我尝试将基本方法设为虚拟,并在尝试覆盖它时调用覆盖,这只会让我出现此错误“无法覆盖继承的成员'MoodyObject.getMood()',因为它没有标记为虚拟、抽象或覆盖”。 我还尝试了没有虚拟和覆盖的情况,它认为我正在尝试隐藏基本方法。 再说一次,我是 OOP 的新手,希望得到任何指导。
编辑添加:我找到了! MoodyObject.cs 只是解决方案资源管理器中的“解决方案项”,而不是“ConsoleApplication1”项。 我将它拖到解决方案资源管理器中它所属的位置,瞧! 现在可以了。 我将下面卢克的答案标记为答案,因为他提供了我解决问题所需的帮助......我在这里学到了很多东西。 太棒了,你们这些家伙和女孩们都非常聪明!
Ok, bear with me guys and girls as I'm learning. Here's my question.
I can't figure out why I can't override a method from a parent class. Here's the code from the base class (yes, I pilfered the java code from an OOP book and am trying to rewrite it in C#).
using System;
public class MoodyObject
{
protected String getMood()
{
return "moody";
}
public void queryMood()
{
Console.WriteLine("I feel " + getMood() + " today!");
}
}
and here are my other 2 objects that inherit the base class (MoodyObject):
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");
}
}
}
And:
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.");
}
}
}
and here is my main:
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();
}
}
}
As you can see, pretty basic stuff, but here's the output:
How does the moody object feel today?
I feel moody today!How does the sad object feel today? I
feel moody today! wah...boohooHow does the happy object feel today?
I feel moody today! hehehehehehe.
Press any key to continue . . .
Not as I expected. I've tried to make the base method virtual and calling override when trying to override it and that just gets me this error "cannot override inherited member 'MoodyObject.getMood()' because it is not marked virtual, abstract, or override". I also tried it without the virtual and override and it thinks I'm trying to hide the base method. Again, I'm new to OOP and would appreciate any guidance.
EDITED TO ADD: I found it! The MoodyObject.cs was only a "solution item" in the solution explorer as opposed to a "ConsoleApplication1" item. I dragged it down to where it belonged in the solution explorer and voila! It works now. I marked Luc's answer below as the answer because he offered the help I needed to get to where I have it resolved... I'm learning so much here. It's amazing and you guys and girls are crazy smart!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
在 C# 中,方法默认不是虚拟的,因此,如果您将某个方法设计为可重写的,则应将其指定为虚拟:
其次,您必须指定要在派生类中重写基类的方法。
如果您不指定“override”关键字,您将获得隐藏基类型的方法(并警告编译器为该方法添加“new”关键字以显式声明)。
如果您想停止继承链并禁止进一步重写该方法,您应该将方法标记为密封,如下所示:
In C# methods are not virtual by default, so if you design some method as overridable, you should specify it as virtual:
Second, you have to specify that you are going to override method from base class in derived class.
If you don't specify "override" keyword, you will get method that hides base type (and warning from compiler to put "new" keyword for the method to explicitly state so).
If you want to stop inheritance chain and disallow further overrides of the method, you should mark method as sealed, like this:
您需要使用 override 关键字来覆盖任何虚拟方法或实现任何抽象方法。
我在这里建议的是,您可能希望 MoodyObject 成为一个抽象类。 (如果你这样做,你就必须改变你的主要方法,但你应该探索它)处于喜怒无常的模式真的有意义吗? 我们上面的问题是,您的 HappyObject 不需要提供 getMood 的实现。通过使类抽象,它可以做几件事:
因此,要做到这一点,您最终会:
注意您如何不再提供 getMood 的实现。
You need to use the override keyword to override any virtual or implement any abstract methods.
What I would recommend here is that you probally meant for MoodyObject to be an abstract class. (You'd have to change your main method if you do this but you should explore it) Does it really make sense to be in a moody mode? The problem with what we have above is that your HappyObject is not required to provide an implementation for getMood.By making a class abstract it does several things:
So to do this you end up:
Note how you no longer provide an implementation for getMood.
据我所知,在Java中,默认情况下所有方法都是虚拟的。 C# 的情况并非如此,因此您需要用“virtual”标记基类方法,例如
protected virtual string getMood() ...
并用“override”标记覆盖,例如受保护的覆盖字符串 getMood()...
。As far as I know, in Java all methods are virtual by default. This is not the case with C#, so you need to mark the base class methods with "virtual", e.g.
protected virtual string getMood() ...
and the overrides with "override", e.g.protected override string getMood()...
.如果要重写基类方法,则需要将其声明为
virtual
。 派生类中的重写方法必须显式声明为override
。 这应该有效:编辑: 我刚刚在 ac# 控制台应用程序中尝试过它,并且它可以编译。 因此,您使用的源代码应该与您在此处发布的源代码有一些微小但重要的部分不同。
我的program.cs是这样的:
If you want to override a base class method, it needs to be declared as
virtual
. The overriding method in a derived class has to be explicitly declared asoverride
. This should work:Edit: I just tried it in a c# console application, and it compiles. So the source code you use should differ in some tiny but important piece from what you posted here.
My program.cs is this:
您需要告诉 C# 您的对象正在重写基类中的函数。
以下是有关您所需语法的 MSDN 文章:http: //msdn.microsoft.com/en-us/library/ebca9ah3(VS.71).aspx
You need to tell C# that your object is overriding the function from the base class.
Here is the MSDN article about the syntax you need: http://msdn.microsoft.com/en-us/library/ebca9ah3(VS.71).aspx
通过将 Moody 中的方法 GetMood 设为虚拟并在派生类中重写,您的代码应该可以工作。 您确定将这些关键字放在了它们所属的位置吗? 这是完整的代码,可以编译并运行得很好:
也许你的错误来自于这样一个事实:在 Java 中,所有方法都是虚拟的,而 C# 的情况并非如此(正如 Dan C. 所指出的)。
By making your method GetMood
virtual
in Moody andoverride
in the derived classes, your code should work. Are you sure you placed these keywords where they belong ? Here is the complete code, that compiles and run just fine :Maybe your mistake comes from the fact that in Java, all methods are virtual, which is not the case is C# (as pointed out by Dan C.).
您需要使用“override”关键字来标记 getMood 的覆盖。 您还需要使用“virtual”关键字标记基本 getMood 方法。
You need to mark the overrides of getMood with the "override" keyword. You'll also need to mark the base getMood method with the "virtual" keyword.