我们在办公室进行了讨论,但双方都不相信。让我们说我们有
enum Food {
CHICKEN, HAMBURGER, FISH;
}
我们需要Dog的多个实现,需要回答,他们是否满意,这取决于他们是否喜欢给他们的食物以及其他一些东西。它需要非常灵活。哪个更好: 答
abstract class Dog {
//not sure if this can be abstract in reality, but does it matter?
abstract Set<Food> getFavoriteFoods();
boolean isFoodOk(){
return getFavoriteFoods().contains(Food.CHICKEN);
}
//in reality sometimes more conditions are needed here...
boolean isHappy(){
return isFoodOk();
}
}
public class BullDog extends Dog {
static final Set<Food> FAVORITE_FOODS = new HashSet<Food>();
static {
FAVORITE_FOODS.add(Food.CHICKEN);
FAVORITE_FOODS.add(Food.FISH);
}
Set<Food> getFavoriteFoods(){
return FAVORITE_FOODS;
}
}
或B:
abstract class Dog {
abstract boolean isHappy();
boolean isFoodOk(Set<Food> f){
return f.contains(Food.CHICKEN);
}
}
public class BullDog extends Dog {
static final Set<Food> FAVORITE_FOODS = new HashSet<Food>();
static {
FAVORITE_FOODS.add(Food.CHICKEN);
FAVORITE_FOODS.add(Food.FISH);
}
@Override
boolean isHappy() {
return isFoodOk(FAVORITE_FOODS);
}
}
如果答案是A,我会有另一个问题。
注意:我编辑了代码,因为那里有一个愚蠢的错误 - 当然FAVORITE_FOODS应该在BullDog中声明,而不是Dog。但这并没有回答这个问题。
答案 0 :(得分:2)
我会说没有,因为在所有方法中Set<Food>
被标记为static final
,因此同一组将在Dog
类的所有实例之间共享。此外,通过将Set
声明为static final
并不意味着其内容无法修改,因此实际上Dog
类或任何子类的任何客户端都可以添加新的食物,甚至可以清除它所有Dog
都会受到影响。
这种方法可以做到:
public abstract class Dog {
//this field should be final only so the variable cannot be modified
protected final Set<Food> favoriteFood;
protected Dog(Food ... food) {
//now the Set cannot be modified as well
favoriteFood = Collections.unmodifiableSet(new HashSet<Food>(Arrays.asList(food)));
}
//no need to be abstract, and clients cannot modify this set
public Set<Food> getFavoriteFoods() {
//I would recommend returning a new set that
return favoriteFood;
}
//You need to check if the dog likes the food to see if its ok
public boolean isFoodOk(Food food){
//not sure if your requirement is that it always should compare with CHICKEN, really odd...
return getFavoriteFoods().contains(food); //Food.CHICKEN);
}
//IMO this method needs a complete redesign, since I don't know the details I can't provide a solution =\
//at most it can be an abstract method and let each dog subclass implement it
public abstract boolean isHappy();
//boolean isHappy(){
// return isFoodOk();
//}
}
public class BullDog extends Dog {
public BullDog() {
super(Food.CHICKEN, Food.FISH);
}
@Override
public boolean isHappy() {
//define how the bulldog is happy
return ...;
}
}
答案 1 :(得分:1)
你会得到一个非常逼真的世界模型:无论有什么食物,所有的狗都会很开心。
说真的:A和B都不好,因为FAVORITE_FOOD是抽象Dog类的class属性。将它作为每个种族的类属性是有道理的。或者,更现实,作为每只狗的实例属性。
答案 2 :(得分:0)
Dog
类型的具体内容是最喜欢的食物。所以他们需要回答“你最喜欢的食物是什么?”这个问题。实施getFavoriteFoods
。快乐并不是一个要求所有Dog
类型不同的问题。在我看来,A更好。