0

我偶然发现了这种情况,但我不知道如何以正确的方式处理它:

class Coffee { }
class CoffeeMix extends Coffee {
  public boolean shaken;
}

我将咖啡项目保存在数组列表中:

ArrayList<Coffee> coffees = new ArrayList<Coffee>();

所以在这个数组列表中存在普通咖啡对象和咖啡混合对象。现在我想显示所有摇晃的咖啡混合对象:

for(Coffee c : coffees) {
  //here is the same problem as above
}

正如我在 stackoverflow 上读到的一些答案:instanceof 似乎是一个坏主意,因为它把 oo 背后的想法搞砸了。那么如何处理呢?

4

4 回答 4

0

首先,当我们谈论 OO 时,我们不应该使用公共字段。我理解你为什么要避免使用实例。在这种情况下,您可以使用多态性和动态绑定。您可以将抽象 isShaken 方法添加到基类中,在 CoffeeMix 将 Shaken 设为私有并覆盖 isShaken(返回 Shaken)

于 2013-05-20T21:40:36.590 回答
0

您确实应该使用多态性。这是去这里的最佳方式。但是你希望你也可以使用 getclass 检查它是否等于所引用的类。

于 2013-05-20T22:00:48.090 回答
0

您可以使用访客模式。

这是一个如何将其应用于您的案例的示例:

interface CoffeeElement {
    void accept(CoffeeVisitor visitor);
}

interface CoffeeVisitor {
    void visit(Coffee coffee);
    void visit(CoffeeMix coffee);   
}


class Coffee implements CoffeeElement {

    private final String name;

    public Coffee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void accept(CoffeeVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String toString() {
        return "Coffee [name=" + getName() + "]";
    }
}

class CoffeeMix extends Coffee {

    public CoffeeMix(String name) {
        super(name);
    }

    @Override
    public void accept(CoffeeVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String toString() {
        return "CoffeeMix [name=" + getName() + "]";
    }

}

class PrintingCoffeeVisitor implements CoffeeVisitor {

    @Override
    public void visit(Coffee coffee) {
        // ignore regular coffee
    }

    @Override
    public void visit(CoffeeMix mix) {
        System.out.println(mix);
    }

}

class CoffeeTest {

    public static void main(String[] args) {
        List<Coffee> coffee = new ArrayList<Coffee>();
        coffee.add(new Coffee("Java"));
        coffee.add(new Coffee("Molokai"));
        coffee.add(new CoffeeMix("Season Blend"));

        CoffeeVisitor v = new PrintingCoffeeVisitor();
        for (Coffee c : coffee) {
            c.accept(v);
        }
    }

}

您还可以阅读访问者模式的说明。我发现它非常有用。

https://stackoverflow.com/a/2604798/467874

于 2013-05-20T22:02:36.767 回答
-2

instanceof在这里似乎很合适,但如果你真的不想使用它,你可以尝试一些丑陋的东西:

for (Coffee c : coffees) {
    try {
        CoffeeMix blend = (CoffeeMix) c;
        //whatever you want to do with CoffeeMix objects
    } catch (ClassCastException cce) {
        //whatever you want to do with Coffee objects
    }
}

这似乎是一种治疗比疾病更糟糕的情况,但是只要CoffeeMix对象有一些对象不可用的字段或属性,就Coffee应该抛出异常,并且您将在没有使用的情况下完成按类排序instanceof 以适当的技术为代价

于 2013-05-20T21:35:22.827 回答