2013-05-20 3 views
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, кажется, плохая идея, потому что винты идеи оо вверх. Итак, как с этим справиться?

+0

Как это отличается от [вашего предыдущего вопроса?] (Http://stackoverflow.com/q/16658109/139010) –

+0

Я не видит проблемы с использованием InstanceOf в данном конкретном случае. –

+0

Предыдущий вопрос был переполнен множеством общих бла-бла, я подумал, что было бы лучше спросить новый вопрос прямо. – freakout

ответ

-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по большой цене до нужной техники.

+3

Использование исключений для нормального выполнения потока..но нет нет! – JamesB

+0

Эй, я сказал, что это плохая идея, не так ли? Sheesh. – cabbagery

0

Прежде всего, когда мы говорим об OO, мы не должны использовать публичные поля. Я понимаю, почему вы хотите избежать использования экземпляра. В этом случае вы можете использовать полиморфизм и динамическое связывание. Вы можете добавить абстрактный метод isshake к базовому классу, встряхнуть как приватный в CoffeeMix и переопределить isShaken (return shaken)

0

Вы действительно должны использовать полиморфизм. Это лучший способ пойти сюда. Но вы хотите, чтобы вы также могли использовать getclass en, если он равен классу, на который ссылается.

+0

Оператор экземпляра имеет различную семантику, чем сравнение классов двух объектов. См. Http://stackoverflow.com/a/596507/467874 – prasopes

+0

Я не сказал, что они такие же, но в описанной выше ситуации кажется, что он дает ему желаемое решение и эффективность. Вы не согласны? – docDevil

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

Смежные вопросы