0

我们在办公室进行了讨论,但双方都不相信。可以说我们有

enum Food {
    CHICKEN, HAMBURGER, FISH;
}

我们需要 Dog 的多个实现,它们需要回答,他们是否快乐,这取决于他们是否喜欢给他们的食物,也许还有其他一些东西。它需要非常灵活。哪个更好: A:

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;
    }
}

或乙:

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);
    }
}

如果答案将是人工智能将有另一个问题。

注意:我编辑了代码,因为那里有一个愚蠢的错误——当然 FAVORITE_FOODS 应该在 BullDog 中声明,而不是 Dog。但这并不能回答问题。

4

3 回答 3

2

我会说没有,因为在所有方法中都Set<Food>被标记为,static final因此相同的集合将在Dog类的所有实例之间共享。另外,声明Setasstatic final并不意味着它的内容不能被修改,所以实际上任何Dog类或任何子类的客户端都可以添加新的 Food 甚至清除它,所有的Dogs 都会受到影响。

这种方法可以做到:

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 ...;
    }
}
于 2013-11-07T14:58:07.740 回答
1

你会得到一个非常真实的世界模型:所有的狗都会很开心,不管有什么食物。

说真的:A 和 B 都不好,因为 FAVORITE_FOOD 是抽象 Dog 类的类属性。将它作为每个种族的类属性是有道理的。或者,更现实的是,作为每只狗的实例属性。

于 2013-11-07T14:54:48.270 回答
0

特定Dog类型是最喜欢的食物。所以他们需要回答“你最喜欢的食物是什么?”这个问题。随着getFavoriteFoods. 快乐不是对所有Dog类型都提出不同要求的问题。所以我认为A更好。

于 2013-11-07T14:56:22.040 回答