9

タイトルがわかりにくいかもしれませんが、下のパターンを見てください

public abstract class Animal
{

    public abstract Dog GetDog { get; }

    public abstract Cat GetCat { get; }

}

public class Dog : Animal
{

    public override Dog GetDog {
        get { return this; }
    }

    public override Cat GetCat {
        get { return null; }
    }

}

これは、基本クラスにプロパティを持ち、派生型を返すことは悪い習慣と見なされますか? または、次のようなことをする必要があります

public abstract AnimalTypeEnum AnimalType { get; }

編集:コメントに基づいて、私が達成しようとしていることをより明確にする必要があると思います。Dogまたはクラスの新しいインスタンスは、Cat特定の基準に基づいて別の関数によって作成されAnimal、呼び出し元に型を返します。呼び出し元のメソッドは、返されたインスタンスの型をチェックし、それに応じて使用します。

public Animal CreateAnimal(string path)
{

    //Process the document in path and create either a new instance of dog or cat

    Dog dg = new Dog();

    return dg;

}
4

5 に答える 5

7

呼び出し元のメソッドは、返されたインスタンスの型をチェックし、それに応じて使用します。

問題があります。それを行う必要があるのはコードの匂いです。犬と猫を別々に扱うのではなく、それが何であれ、単なるオブジェクトとして扱うことができるはずです.

いずれかの動物のコンテンツを表示する必要がある場合は、ToString両方のクラスでメソッドをオーバーライドし、動物を呼び出すだけToStringです。犬や猫の名前を知る必要がある場合は、Nameプロパティを に追加しますAnimal。可能な限り、ここでポリモーフィズムを使用して、オブジェクトを使用しているものは何でもAnimal、同じメソッドのさまざまな実装の結果として発生するさまざまなことが単に含まれるようにする必要があります。

本当にAnimalが aDogか aかを知る必要がある場合は、 or演算子Catを使用できます。OP で示したすべてのコードを追加する必要はありません。isas

于 2012-10-18T19:10:15.123 に答える
5

いや、あなたはそれを間違っています。

より良いことは、単一のメソッドを持つことです。

public abstract Animal getAnimal();

派生クラスは、それ自体を返す方法を認識します。それが理にかなっていることを願っています。しかし、動物を返したいとは思わないでしょう。意味がありません。

Animal dog = new Dog() ;
dog.getAnimal(); 

紛らわしいですよね?

Animals/List の配列を取得し、コレクションを反復処理して、次のように確認できます。

if(animal is Dog)

しかし、まだタイプをチェックしています。基本クラスを使用する場合は、意味があり、共通のメソッドを公開するようにします。

于 2012-10-18T18:45:20.317 に答える
1

Open-Closed の原則に違反しているため、これは非常に基本的な設計です。クラスを拡張に対してオープンにし、変更に対してクローズする必要があります。明日、別のクラスを追加したい場合はどうなりますか?

public class Donkey : Animal
{
}

プロパティを持つように、基本クラスを変更する必要がありますGetDonkey。また、クラスを使用するすべてのクラスを変更して追加する必要がありますif (animal.GetDonkey == null)

すべきことは、次のようなファクトリ デザイン パターンを使用することです。

public static class AnimalFactory
{
  public static Dog GetDog()
  {
    return new Dog();
  }

  public static Cat GetCat()
  {
    return new Cat();
  }
}

または、 @Lews Therinが提案したような仮想メソッドを使用する必要があります。

于 2012-10-18T18:57:29.493 に答える
-2

呼び出されたオブジェクトを返すだけのプロパティを持つことはあまり役に立ちません。

スーパークラスからサブクラスにダウンキャストする方法を探しているだけでしょうか? その場合は、キャストを使用してください。

Animal a = new Cat();

try
{
    Dog d = (Dog)a;
}
catch (InvalidCastException)
{
    try
    {
        Cat c = (Cat)a;
    }
    catch (InvalidCastException)
    {
    }
}
于 2012-10-18T18:54:02.967 に答える