26

好的,在我学习的过程中,请多多包涵。这是我的问题。

我不知道为什么我不能覆盖父类的方法。这是来自基类的代码(是的,我从一本 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”项。我将它拖到解决方案资源管理器中它所属的位置,瞧!现在可以了。我在下面将 Luc 的答案标记为答案,因为他为我提供了解决问题所需的帮助......我在这里学到了很多东西。太棒了,你们这些男孩女孩都非常聪明!

4

8 回答 8

66

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

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

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

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

如果您不指定“覆盖”关键字,您将获得隐藏基类型的方法(并警告编译器将“新”关键字用于该方法的显式声明)。

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

  protected sealed override string GetMood() {...}
于 2008-12-03T16:00:19.287 回答
6

您需要使用 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 的实现。

于 2008-12-03T16:08:32.110 回答
5

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

于 2008-12-03T15:59:30.600 回答
3

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

public class BaseObject
{
    protected virtual String getMood()
    {
        return "Base mood";
    }

    //...
}

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

编辑:我刚刚在 ac# 控制台应用程序中尝试过,它可以编译。因此,您使用的源代码应该与您在此处发布的一些微小但重要的部分有所不同。

我的 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.");
        }
    }
}
于 2008-12-03T16:02:27.520 回答
2

virtual通过在 Moody 和派生类中创建方法 GetMood 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. 所指出的那样)。

于 2008-12-03T15:58:50.227 回答
2

您需要告诉 C# 您的对象正在覆盖基类中的函数。

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

public class SadObject: MoodyObject    
{        
    override String getMood()
于 2008-12-03T16:01:54.963 回答
1
public class SadObject: MoodyObject
    {
        override String getMood()
于 2008-12-03T15:56:28.170 回答
0

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

于 2008-12-03T15:59:05.577 回答