2

假设您有一个名为 Food 的类,并且您有一个名为 Banana、Apple 和 Orange 的派生类。您在某处有一个 FoodProcessor 方法,在大多数情况下,它可以处理任何类型的食物,但有时需要知道它正在处理什么类型的食物,以便执行特定类型的操作,例如剥香蕉皮、去核苹果,或者挤橙子。

所以你的 FoodProcessor 接受 Food 参数。您的 FoodProcessor 检测 Food 实例的特定衍生类型的最佳方法是什么?

4

4 回答 4

2

您应该使用多态性,每个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 及其子类之间的继承关系。

于 2013-02-13T21:57:38.090 回答
1

我会将其抽象化并在每种食物中实施:

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();
    }
}
于 2013-02-13T21:59:58.580 回答
1

在测试对象的类型时,我喜欢使用is关键字,像这样:

if(myFood is Bannana)
  Peel((Bannana)myFood);

我更喜欢is它,因为它还会检查对象是否实现了接口。

说到接口,如果您有执行特定操作的某些类型,您可能需要考虑使用接口。检查特定类型需要了解可能使用的不同类型,但是,如果您检查接口,则可能会出现实现此接口的新类型,而无需更改代码来处理它们:

if(myFood is IPeelable)
  Peel((IPeelable)myFood)
else if(myFood is ICoreable)
  Core((ICoreable)myFood)

如果您寻找特定的类型,您现在和将来都需要知道所有可能的类型,这不是很可扩展的。

这当然假设您不想使用直接多态性,正如其他答案之一所描述的那样。

于 2013-02-13T22:00:23.200 回答
-1
void FoodProcessor(Food food)
{
    if(food is Banana)
        ...
    else if(food is Apple)
        ...

    ...
    etc
}

编辑:如果您可以使用其他答案中提到的多态性,则忽略此

于 2013-02-13T21:57:18.213 回答