代码之家  ›  专栏  ›  技术社区  ›  GregD

帮助重写和继承

  •  21
  • GregD  · 技术社区  · 15 年前

    using System;
    
    public class MoodyObject
    {
        protected String getMood()
        {
            return "moody";
        }
    
        public void queryMood()
        {
            Console.WriteLine("I feel " + getMood() + " today!");
        }
    }
    

    下面是我的另外两个继承基类(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();
            }
        }
    }
    

    这个情绪化的物体今天感觉如何?

    今天心情不好!哇…呜呜

    快乐的对象今天感觉如何? 按任意键继续。

    不像我预料的那样。我尝试将基方法设置为虚拟,并在尝试重写它时调用override,这只会导致以下错误:“无法重写继承的成员'MoodyObject.getMood()',因为它未标记为虚拟、抽象或重写”。我也在没有虚拟和重写的情况下尝试了它,它认为我在试图隐藏基本方法。再说一次,我是OOP新手,希望得到任何指导。

    编辑添加:我找到了!MoodyObject.cs只是解决方案资源管理器中的“解决方案项”,而不是“ConsoleApplication1”项。我把它拖到了解决方案浏览器中的位置,瞧!现在可以了。我在下面把Luc的答案标记为答案,因为他提供了我所需要的帮助,帮助我解决了问题。。。我在这里学到了很多。这太神奇了,你们这些家伙和女孩都非常聪明!

    8 回复  |  直到 5 年前
        1
  •  65
  •   Ilya Ryzhenkov    15 年前

    在C#中,默认情况下,方法不是虚拟的,因此如果将某个方法设计为可重写的,则应将其指定为虚拟的:

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

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

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

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

      protected sealed override string GetMood() {...}
    
        2
  •  6
  •   JoshBerke    15 年前

    您需要使用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. 不能新建抽象类的实例。您必须使用子类。

    因此,要做到这一点,你必须:

    public abstract class MoodyObject
    {
        protected abstract String getMood();
    
        public void queryMood() 
        { 
            Console.WriteLine("I feel " + getMood() + " today!"); 
        }
    }
    

        3
  •  5
  •   Dan C.    15 年前

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

        4
  •  3
  •   Treb    15 年前

    virtual . 派生类中的重写方法必须显式声明为 override . 这应该起作用:

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

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

    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.");
            }
        }
    }
    
        5
  •  2
  •   Jeremiah    15 年前

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

    http://msdn.microsoft.com/en-us/library/ebca9ah3(VS.71).aspx

    public class SadObject: MoodyObject    
    {        
        override String getMood()
    
        6
  •  2
  •   Luc Touraille    15 年前

    通过使你的方法获得情绪 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所指出的)。

        7
  •  1
  •   James Curran    15 年前
    public class SadObject: MoodyObject
        {
            override String getMood()
    
        8
  •  0
  •   Kevin Tighe    15 年前

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