mau*_*ris 13
好吧,这是我提出的一个好的 - 利用OOP覆盖,子类和超类:
namespace Animals{
// base class Animal
class Animal{
public void eat(Food f){
}
}
class Carnivore extends Animal{
public void eat(Meat f){
}
}
class Herbivore extends Animal{
public void eat(Plant f){
}
}
class Omnivore extends Animal{
public void eat(Food f){
}
}
}
namespace Food{
// base class Food
class Food{
}
class Meat extends Food{
}
class Plant extends Food{
}
}
Run Code Online (Sandbox Code Playgroud)
我从超类Animal创建了Herbivore,Carnivore和Omnivore的子类,并eat使用它实际可以吃的食物类型覆盖该方法.
所以:
Plant grass = new Plant();
Herbivore deer = new Herbivore();
deer.eat(grass); // ok
Plant grass2 = new Plant();
Carnivore tiger = new Carnivore();
tiger.eat(grass2); // not ok.
Meat deer2 = new Meat();
tiger.eat(deer2); // ok
Run Code Online (Sandbox Code Playgroud)
好了,最后一个问题是,当你指定deer是Herbivore,你不能使它成为Meat了tiger吃.然而,在一天结束时,这应该足以解决面试问题,同时不让面试官入睡.
Liskov替代原则有一个很棒的海报,上面写着:"如果它看起来像一只鸭子,像鸭子一样嘎嘎叫,但需要电池,你可能得到了错误的抽象." 这是快速的答案 - 一些对象可以是动物和食物,所以除非你愿意走多重继承的路线,否则分类模式都是错误的.
一旦你清除了这个障碍,剩下的就是开放式的,你可以引入其他设计原则.例如,您可以添加允许使用对象的IEdible接口.您可能会面向方面,并为食肉动物和食草动物添加装饰器,这将允许仅使用正确类别的对象.
重点是能够思考你的脚,看到并解释问题的各个方面,并进行良好的沟通.也许不会陷入"一个正确答案"的限制.
我告诉他要抓一点.这是一个可怕的抽象.更不用说我们没有任何背景.抽象不是凭空而出,也不是出于对"正确"的"想法".告诉我你首先要解决的是什么问题,所以我们可以评估这个抽象.
如果没有提供上下文,那么我将假设/化妆我自己:你希望某些类型的对象能够吃掉其他类型的对象.没有更多,没有更少.
创建一个Eatable界面(或者你可以调用它Food,如果你想的话),因为我们没有任何上下文,所以我认为它是一个玩具控制台程序,它只是打印:
<X> ate <Y>
Run Code Online (Sandbox Code Playgroud)
所以我们所需要的这个接口就是一个getFoodName()方法.
对于错误检查,您可以创建一堆的isXFoodType方法,例如isGrassFoodType(),isMeatFoodType()等Cow的的实现Eat(Eatable e)会检查isGrassFoodType(),当出现故障时,打印:
"Cow can't eat " + e.getFoodName()
Run Code Online (Sandbox Code Playgroud)