假设您有一个名为 Food 的类,并且您有一个名为 Banana、Apple 和 Orange 的派生类。您在某处有一个 FoodProcessor 方法,在大多数情况下,它可以处理任何类型的食物,但有时需要知道它正在处理什么类型的食物,以便执行特定类型的操作,例如剥香蕉皮、去核苹果,或者挤橙子。
所以你的 FoodProcessor 接受 Food 参数。您的 FoodProcessor 检测 Food 实例的特定衍生类型的最佳方法是什么?
假设您有一个名为 Food 的类,并且您有一个名为 Banana、Apple 和 Orange 的派生类。您在某处有一个 FoodProcessor 方法,在大多数情况下,它可以处理任何类型的食物,但有时需要知道它正在处理什么类型的食物,以便执行特定类型的操作,例如剥香蕉皮、去核苹果,或者挤橙子。
所以你的 FoodProcessor 接受 Food 参数。您的 FoodProcessor 检测 Food 实例的特定衍生类型的最佳方法是什么?
您应该使用多态性,每个Food
子类将定义一个方法process()
,并且FoodProcessor
该类将简单地调用该方法。
食品加工机
public void process(Food f) {
f.process();
}
苹果
public void process() {
Console.WriteLine("Core the apple.");
}
香蕉
public void process() {
Console.WriteLine("Peel the banana.");
}
橙子
public void process() {
Console.WriteLine("Squeeze the orange.");
}
通过这种方式,您可以利用 Food 及其子类之间的继承关系。
我会将其抽象化并在每种食物中实施:
abstract class Food {
public abstract void Prepare();
}
class Banana : Food {
public override void Prepare() {
Peel();
}
}
class Apple : Food {
public override void Prepare() {
Core();
}
}
然后你会有:
class FoodProcessor {
public void Process(Food food) {
food.Prepare(); // preparation of the food
food.Process();
}
}
在测试对象的类型时,我喜欢使用is
关键字,像这样:
if(myFood is Bannana)
Peel((Bannana)myFood);
我更喜欢is
它,因为它还会检查对象是否实现了接口。
说到接口,如果您有执行特定操作的某些类型,您可能需要考虑使用接口。检查特定类型需要了解可能使用的不同类型,但是,如果您检查接口,则可能会出现实现此接口的新类型,而无需更改代码来处理它们:
if(myFood is IPeelable)
Peel((IPeelable)myFood)
else if(myFood is ICoreable)
Core((ICoreable)myFood)
如果您寻找特定的类型,您现在和将来都需要知道所有可能的类型,这不是很可扩展的。
这当然假设您不想使用直接多态性,正如其他答案之一所描述的那样。
void FoodProcessor(Food food)
{
if(food is Banana)
...
else if(food is Apple)
...
...
etc
}
编辑:如果您可以使用其他答案中提到的多态性,则忽略此