26

わかりました、私が学んでいる間、私と一緒に待ってください。これが私の質問です。

親クラスのメソッドをオーバーライドできない理由がわかりません。これが基本クラスのコードです (はい、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();
        }
    }
}

ご覧のとおり、かなり基本的なものですが、出力は次のとおりです。

ムーディーなオブジェクトは今日どのように感じますか? 今日は気分が悪い!

悲しいオブジェクトは今日どのように感じますか? 今日は気分が悪い!うわ…ブーフー

今日の幸せなオブジェクトはどう感じますか? 今日は気分が悪い!ふふふふふ。何かキーを押すと続行します 。. .

私が期待したようではありません。基本メソッドを仮想にして、オーバーライドしようとしたときにオーバーライドを呼び出してみましたが、「仮想、抽象、またはオーバーライドとマークされていないため、継承されたメンバー '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() {...}
}

"override" キーワードを指定しないと、基本型を非表示にするメソッドが取得されます (メソッドが明示的に宣言するために "new" キーワードを配置するようコンパイラから警告されます)。

継承チェーンを停止し、メソッドのそれ以上のオーバーライドを禁止する場合は、次のようにメソッドをシール済みとしてマークする必要があります。

  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# には当てはまらないため、基本クラス メソッドを「仮想」でマークしprotected virtual string getMood() ...、オーバーライドを「オーバーライド」でマークする必要があります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

virtualMoody およびoverride派生クラスでメソッド GetMood を作成すると、コードが機能するはずです。これらのキーワードを適切な場所に配置しましたか? コンパイルして正常に実行される完全なコードは次のとおりです。

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 のオーバーライドをマークする必要があります。また、ベースの getMood メソッドを「virtual」キーワードでマークする必要があります。

于 2008-12-03T15:59:05.577 に答える