方法参数与子类中的getter

时间:2013-11-07 14:48:43

标签: java

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

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。但这并没有回答这个问题。

3 个答案:

答案 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更好。