面向对象的设计访谈

jai*_*jai 9 oop

有关解决这个问题的建议吗?

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)

好了,最后一个问题是,当你指定deerHerbivore,你不能使它成为Meattiger吃.然而,在一天结束时,这应该足以解决面试问题,同时不让面试官入睡.

  • Downvoted,因为你在一个地方将鹿分类为动物,在另一个地方分类为食物.同样的鹿可以是两个; 老虎可以攻击鹿,而它正在吃你的灌木. (2认同)

Cyl*_*Cat 8

Liskov替代原则有一个很棒的海报,上面写着:"如果它看起来像一只鸭子,像鸭子一样嘎嘎叫,但需要电池,你可能得到了错误的抽象." 这是快速的答案 - 一些对象可以是动物和食物,所以除非你愿意走多重继承的路线,否则分类模式都是错误的.

一旦你清除了这个障碍,剩下的就是开放式的,你可以引入其他设计原则.例如,您可以添加允许使用对象的IEdible接口.您可能会面向方面,并为食肉动物和食草动物添加装饰器,这将允许仅使用正确类别的对象.

重点是能够思考你的脚,看到并解释问题的各个方面,并进行良好的沟通.也许不会陷入"一个正确答案"的限制.


has*_*sen 6

我告诉他要抓一点.这是一个可怕的抽象.更不用说我们没有任何背景.抽象不是凭空而出,也不是出于对"正确"的"想法".告诉我你首先要解决的是什么问题,所以我们可以评估这个抽象.

如果没有提供上下文,那么我将假设/化妆我自己:你希望某些类型的对象能够吃掉其他类型的对象.没有更多,没有更少.

创建一个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)

  • -1.多态性是这样我们不需要编写在运行时检查类型的代码,例如isXFoodType方法. (2认同)