2014-06-10 2 views
0

Я не написал Java-код более 10 лет. Мне это нравится, но я не думаю, что я получу некоторые детали полиморфного программирования. У меня есть абстрактный класс Node, у которого есть подклассы меток и данных (среди прочих), и я храню их в ArrayList.Понимание полиморфизма в Java

Но когда я получаю их из ArrayList через Iterator, я возвращаю объекты Node. Я не уверен, как лучше иметь дело с объектами, которые я получаю от итератора.

Вот пример:

// initialize the list 
TagNode tag = new TagNode(); 
ArrayList<Node> list = new ArrayList<>(); 
list.add(tag); 
// And many more go into the list, some TagNodes, some DataNodes, etc. 

, а затем я использую итератор для их обработки:

Iterator<Node> i = list.iterator(); 
Node n = i.next(); 
// How do I tell if n is a TagNode or a DataNode? 

Я знаю, что я могу бросить в один из узлов подклассов, но, как я знаю, какой подкласс использовать? Нужно ли вводить информацию типа внутри классов Node?

+8

Весь смысл полиморфизма заключается в том, что вы ** не ** должны знать, какой подкласс у вас есть. Вы используете переопределения методов для обеспечения отличительного поведения. –

ответ

5

Вам не нужно знать, какой именно класс детей, в большинстве случаев.

Именно это преимущество при полиморфизме.

Если иерархическая конструкция твердая, Node будет иметь все поведение (== методы), необходимые для выполнения операций над List пунктов, не заботясь о том, какой ребенок класса они являются примером: переопределены методы разрешения во время выполнения.

В некоторых случаях вы можете захотеть использовать оператор instanceof на самом деле проверить, какой ребенок class ваших Node принадлежит, но я хотел бы рассмотреть это редкий случай, лучше всего избегать в общих принципах.

+0

Если вам нужна точка if (instanceof) или, в более общем плане, переключатель (тип), вы можете подумать о том, чтобы рефакторинг кода имел правильный полиморфизм http://refactoring.com/catalog/replaceConditionalWithPolymorphism.html, или если вы не может изменить иерархию, чтобы включить поведение, в котором вы нуждаетесь, вы можете экстеризировать это поведение http://refactoring.com/catalog/replaceTypeCodeWithStateStrategy.html и иметь шаблон посетителя, принимающий узел, и динамическое применение правильной стратегии к правильному типу объекта. –

1

В идеале вам don't want to treat them differently, но если вы хотите, чтобы определить тип, вы можете проверить с помощью InstanceOf:

Node n = i.next(); 
if (n instanceof Tag) { 
    // behavior 
} 
0

Как другие сказали, проверка явно которой подклассы ваш объект принадлежит не должно быть необходимым и также плохой стиль. Но если вам это действительно нужно, вы можете использовать instanceof operator.

0

Полиморфное поведение будет означать, что вам все равно, знаете ли вы, какой тип Node. Вы просто называете API, и поведение будет выполняться в соответствии с реализацией конкретного типа.

Но если вам действительно нужно знать, один из способов - использовать instanceof, чтобы узнать, какой именно тип. Напр.

if(i instanceof tag) 
    // handle tag 
    else if(i instanceof data) 
    //handle data 
Смежные вопросы