帮助覆盖和继承

时间:2008-12-03 15:50:55

标签: c# inheritance override

好的,在我学习的时候,请跟我们男朋友一起。这是我的问题。

我无法弄清楚为什么我不能从父类重写方法。这是来自基类的代码(是的,我从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的答案标记为答案,因为他提供了我所需要的帮助,以便我解决问题......我在这里学到了很多东西。这太棒了,你们和女孩们都很聪明!

8 个答案:

答案 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提供一个实现。通过使一个类抽象,它做了几件事:

  1. 你不能新建一个抽象类的实例。你必须使用儿童班。
  2. 您可以强制派生的孩子实施某些方法。
  3. 所以要做到这一点你最终:

    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方法。