我的数据库中的 Animals 表中有不同类型的动物行。
我有一个带有 Speak 方法的 IAnimal 接口。
我有不同的动物类实现 IAnimal 接口(狗、猫等)
您是否迭代记录检查类型,然后根据类型实例化正确的对象,然后调用它们的 Speak 方法。
这是使用接口的典型方式吗?
我的数据库中的 Animals 表中有不同类型的动物行。
我有一个带有 Speak 方法的 IAnimal 接口。
我有不同的动物类实现 IAnimal 接口(狗、猫等)
您是否迭代记录检查类型,然后根据类型实例化正确的对象,然后调用它们的 Speak 方法。
这是使用接口的典型方式吗?
不,这不是典型的方式,基本上你会有一个方法来获取接口的一个实例,然后你可以Speak
在那里调用该方法。您不必关心传入的对象是什么具体类型,这样做的好处是您可以及时添加更多类型,而不必更改您的实现。
像这样的东西:
public void Speak(IAnimal animal)
{
animal.Speak();
}
如果您尝试在关系数据库中表示派生类型,您有以下选择:
您似乎选择了选项 2。
您通常会将 IAnimal 接口用作方法的返回类型或另一个方法的参数,而不是在实例化后立即调用 speak 方法。
例如,以下代码可能对接口使用有意义:
public IList<IAnimal> GetAnimals()
{
var animals = new List<IAnimal>();
foreach(var animal in db.Animals)
{
animals.add( // instantiate new animal here)
}
return animals;
}
这将允许调用者让所有动物说话,无论它们的潜在类型如何。当然,如果界面只有一个 speak 方法,它可能不是很有用。
在这种情况下,您所说的关系类型是“是”关系。狗是一种动物。面向对象设计中的“是”关系是使用基类实现的,而不是接口。
所以你有一个Animal的基类。然后你有一个继承自 Animal 的 Dog 类。
当您从数据库中检索数据时,您将创建每个动物的类型,但添加到动物列表中。
然后,您的调用函数可以遍历 Animal 对象列表并调用 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;
}