データベースの Animals テーブルに、さまざまな種類の動物の行があります。
Speak メソッドを使用した IAnimal インターフェイスがあります。
IAnimal インターフェイス (Dog、Cat など) を実装するさまざまな動物クラスがあります。
タイプのレコードチェックを繰り返してから、タイプに基づいて正しいオブジェクトをインスタンス化し、それらの Speak メソッドを呼び出しますか。
それはインターフェースを使用する典型的な方法ですか?
データベースの Animals テーブルに、さまざまな種類の動物の行があります。
Speak メソッドを使用した IAnimal インターフェイスがあります。
IAnimal インターフェイス (Dog、Cat など) を実装するさまざまな動物クラスがあります。
タイプのレコードチェックを繰り返してから、タイプに基づいて正しいオブジェクトをインスタンス化し、それらの Speak メソッドを呼び出しますか。
それはインターフェースを使用する典型的な方法ですか?
オブジェクトが IAnimal を実装していることがわかっている場合は、オブジェクトの型を気にする必要はありません。
var animal = (IAnimal)animals[i];
animal.Speak();
サンプルを含むリファレンスを確認してください。
いいえ、これは一般的な方法ではありません。基本的には、インターフェイスのインスタンスを取得するSpeak
メソッドがあり、そこでメソッドを呼び出すことができます。渡したオブジェクトがどの具体的な型であるかを気にする必要はありません。これの利点は、時間内にさらに多くの型を追加でき、実装を変更する必要がないことです。
このようなもの:
public void Speak(IAnimal animal)
{
animal.Speak();
}
リレーショナル データベースで派生型を表現しようとしている場合は、次のオプションがあります。
オプション 2 を選択したようです。
通常、インスタンス化の直後に speak メソッドを即座に呼び出すのではなく、メソッドの戻り値の型または別のメソッドへのパラメーターとして IAnimal インターフェイスを使用します。
たとえば、次のコードはインターフェイスの使用法に適している場合があります。
public IList<IAnimal> GetAnimals()
{
var animals = new List<IAnimal>();
foreach(var animal in db.Animals)
{
animals.add( // instantiate new animal here)
}
return animals;
}
これにより、発呼者は、基になるタイプに関係なく、すべての動物を話させることができます。もちろん、インターフェイスに speak メソッドしかない場合は、おそらくあまり役に立ちません。
この場合、あなたが話している関係のタイプは「is a」関係です。犬は動物です。オブジェクト指向設計の「である」関係は、インターフェイスではなく基本クラスを使用して実装されます。
これで、Animal の基本クラスができました。次に、Animal を継承する Dog のクラスを作成します。
データベースからデータを取得するとき、それぞれの動物をそのタイプとして作成しますが、動物のリストに追加します。
呼び出し関数は、動物オブジェクトのリストを繰り返し処理し、各オブジェクトが何であるかを知らなくても Speak を呼び出すことができます。
public void MakeAnimalsSpeak()
{
// gets your animals from the database
List<Animal> animals = GetAnimals();
foreach(Animal animal in animals)
{
animal.Speak();
}
}
private List<Animals> GetAnimals()
{
List<Animal> animalsToReturn = new List<Animal>();
// get data from db
// loop through data
// switch on "type" field, create correct object.
// add too List.
return animalsToReturn;
}