1

次の例では、C# を使用しています。

抽象クラスを作成し、Base_Collectionそこから他のクラスを派生させます ( BookMovieGame)。ただし、コンパイラ エラーを発生させずに、これらの新しい子クラスに使用できる新しいメソッドを追加する方法がわかりません。

namespace polymorphism_test_01
{
    abstract class Base_Collection
    {
        public int id = 0;
        public string title = "";

        public Base_Collection() { }
    }
}    

namespace polymorphism_test_01
{
    class Book : Base_Collection
    {
        public Book() { }

        public override void Read_Book() { }
    }
}    

namespace polymorphism_test_01
{
    class Game : Base_Collection
    {
        public Game() { }

        public void Play_Game() { }
    }
}   

namespace polymorphism_test_01
{
    class Movie : Base_Collection
    {
        public Movie() { }

        public void Watch_Movie() { }
    }
}

次のスニペットでは呼び出しbook.Read_Book()が機能せず、コンパイラはエラーを出力します。

namespace polymorphism_test_01
{
    class Program
    {
        public static void Main(string[] args)
        {
            Base_Collection book = new Book();

            book.title = "The Dark Tower";
            book.Read_Book();

            Console.WriteLine(book.title);
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}
4

5 に答える 5

3

基本クラスに問題なくメソッドを追加できます。コンパイラ エラーが発生する理由は、overrideキーワードを間違って使用したためです。

キーワードを使用するにはoverride、メソッド名と署名が親クラスのメソッド名と署名と一致している必要があり、メソッドは基本クラスとしてvirtualまたはとしてマークされている必要があります。abstract両者の違いについては、こちらで回答しています。

本、映画、映画はすべて「上演」できるため、クラスを次のように作成することを検討することをお勧めします。

abstract class Base_Collection
{
    public int id = 0;
    public string title = "";

    public Base_Collection() { }

    public virtual void PerformAction() { } // or public virtual void PerformAction(){ }
}

class Book : Base_Collection
{
    public Book() { }

    public override void PerformAction() { // read book }
}

class Game : Base_Collection
{
    public Game() { }

    public override void PerformAction() { // play game }
}

class Movie : Base_Collection
{
    public Movie() { }

    public void PerformAction() { // watch movie }
}
于 2012-12-09T00:35:28.290 に答える
2

@Will からの回答 (これは正しい) に加えて、階層構造をもう少しうまく構成できます。たとえば、メディア タイプごとに異なることを行いますが、各タイプは引き続き消費されます。

したがって、基本クラスを と呼ばれる抽象基本メソッドを持つように変更します。これはオーバーライドされ、各派生クラスで実際に実装されます。このようにして、基本クラスのインスタンスを渡すことができ、各メディアConsume()でメソッドを呼び出すためにキャストする必要はありません。Consume()タイプ:

public abstract class Base_Collection
{

    public int id = 0;
    public string title = "";

    public Base_Collection() {   }

    public abstract void Consume();

}

public class Book : Base_Collection
{
    public Book() {   }

    public override void Consume()
    {
        //do book reading stuff in here
    }
}

public class Movie : Base_Collection
{
    public Movie() {   }

    public override void Consume()
    {
        //do movie watching stuff in here
    }
}



public class SomeOtherClass
{
    public void SomeMethod(Base_Collection mediaItem)
    {
        //note that the book/movie/whatever was passed as the base type
        mediaItem.Consume();
    }
}
于 2012-12-09T00:32:15.920 に答える
1

Base_Collectionという名前のメソッドがありませんRead_Book。派生クラスでメソッドを呼び出すには、たとえばキャストする必要があります

(Book)book.Read_Book();
于 2012-12-09T00:24:18.023 に答える
1

存在しないメソッドをオーバーライドすることはできません。を削除してoverrideから、メソッドにアクセスする前にキャストします。

class Book : Base_Collection
{
    public Book()
    {

    }

    public void Read_Book()
    {

    }
}


public static void Main(string[] args)
{
    Base_Collection book = new Book();

    book.title = "The Dark Tower";
    (Book)book.Read_Book();
    ...
}

ただし、キャストするのではなく Book オブジェクトを作成するだけです。そうしないと、プログラムで多くのキャストを行う必要があります。スラッグスターの言及のように、クラス階層を再考することさえあるかもしれません。

于 2012-12-09T00:27:34.377 に答える
0

public override void Read_Book() から override キーワードを削除するか、この関数を以下のように Base_Collection に追加する必要があります。

    public abstract void Read_Book();
于 2012-12-31T13:43:23.020 に答える