2012-05-05 2 views
1

пытаются найти прямой ответ/решение для этого в течение последних 3-х часов без удачи, надеясь, что вы, ребята могут помочь:Дженерик и понижающее приведение (Java)

У меня есть следующие классы, которые реализуют дерево интервала, используя бинарное дерево поиска:

public class Node<T extends Comparable<T>> implements Comparable<Node<T>> {...} 

public class BinarySearchTree<T extends Comparable<T>> { 
protected Node<T> root; 
...} 

public class IntervalNode extends Node<Interval> {...} 

public class IntervalTree extends BinarySearchTree<Interval> {...} 

При попытке следующий бросок на корневом элементе экземпляра IntervalTree я получаю ClassCastException:

IntervalNode CurrentNode = (IntervalNode)root; //root being of type Node<Interval> 
which IntervalNode extends. 

Я довольно новый в java, но из того, что я прочитал и googled, это понижение должно быть возможным, поэтому я немного потерял причину этого исключения. До сих пор я догадываюсь, что это вызвано стиранием типа, но я не смог найти прямой ответ на этот вопрос. Любые идеи относительно причины этого исключения или еще лучше обходного пути?

+1

из вашего кода, каждый 'IntervalNode' является' Node', но 'Node' может быть' IntervalNode' (не каждый). Когда вы вставляете элемент в свое дерево, он будет 'Node', может быть, делать что-то вроде' if (root == null) root = new Node(); 'если это так, тогда ваш тип кастинг будет всегда недействительным. –

ответ

7

Вы здесь не в ожидании, а в понижении. IntervalNode - это Node<Interval> (потому что он расширяет его), но Node<Interval> не обязательно является IntervalNode.

Как банан - это плод, потому что он его расширяет, но плод не всегда является бананом. Если у вас есть Фрукты и бросить его на банан, он будет работать только в том случае, если плод фактически является бананом. Если это яблоко, это провалится.

+0

Да, я только что понял, что должен был сказать, что я сбиваю с толку. Я отредактирую вопрос, спасибо за головы. – Alon

+0

Еще раз спасибо, что понял мою ошибку. – Alon

1

Если вам нужно в вашем IntervalTree в IntervalNode, то как насчет:

public class BinarySearchTree<T extends Node<?>> { 
    protected T root; 
} 

public class IntervalTree extends BinarySearchTree<IntervalNode> { 

} 
+0

не думал об этом, мог бы сэкономить мне какую-то работу, спасибо! – Alon

0

Если вы Node интерфейс (и, возможно, поместить общую реализацию в базовом классе), вы могли бы сделать почти то, что вы были пытается сделать в первую очередь:

public interface Node<T extends Comparable<T>> extends Comparable<Node<T>> {...} 
public class BaseNode<T extends Comparable<T>> implements Node<T> {...} 

public class IntervalNode extends BaseNode<Interval> implements Node<Interval> {...} 

все должно работать нормально до тех пор, как вы сделаете все Node s IntervalTree использует экземпляры IntervalNode.

В любом случае (с или без интерфейсов), вы должны убедиться, чтобы отменить что-либо в BinarySearchTree, что создает Node с в IntervalTree для создания IntervalNode с.