2014-12-03 3 views
0

Так у меня есть класс:Почему это не будет?

public static class AVLTreeNode <E extends Comparable<E>> extends BST.TreeNode<E> { 
    protected int height; 

    public AVLTreeNode(E e) { 
     super(e); 
    } 
} 

Это расширяет другой класс:

public static class TreeNode<E extends Comparable<E>> { 
    protected E element; 
    protected TreeNode<E> left; 
    protected TreeNode<E> right; 

    public TreeNode(E e) { 
     element = e; 
    } 
} 

И я создаю ArrayList типа TreeNode, и пытается бросить его AVLTreeNode:

public void balancePath(E e) { 
    ArrayList<TreeNode<E>> path = path(e); 
    for (int i = path.size() - 1; i >= 0; i--) { 
     AVLTreeNode<E> a = (AVLTreeNode<E>)(path.get(i)); 
    //continued code not important... 

Обратите внимание, что мой метод пути возвращает ArrayList типа TreeNode<E>. Но когда я пытаюсь запустить узел, который я получаю в позиции i в списке, AVLTreeNode<E> (подтип TreeNode) Я получаю ClassCastException.

В чем проблема?

Редактировать Вот полный трассировки стека

Exception in thread "main" java.lang.ClassCastException: com.jeffsite.chapter27.BinarySearchTree$TreeNode cannot be cast to com.jeffsite.chapter29.AVLTree$AVLTreeNode 
at com.jeffsite.chapter29.AVLTree.balancePath(AVLTree.java:102) 
at com.jeffsite.chapter29.AVLTree.insert(AVLTree.java:19) 
at com.jeffsite.chapter29.TestAVLTree.main(TestAVLTree.java:10) 
+0

Рассмотрим обеспечение [работоспособный пример] (https: // StackOverflow .com/help/mcve), который демонстрирует вашу проблему. Это приведет к меньшему путанице и лучшим ответам – MadProgrammer

+0

Опубликуйте все свое исключение, включая трассировку стека. –

ответ

0

Это зависит от того, какой путь возвращения. Если метод path/func возвращает List of TreeNode, то преобразование невозможно, так как AVLTreeNode имеет дополнительные параметры.

Вы можете создать ArrayList или List of AVLTreeNode, который должен помочь решить проблему под рукой (Только в случае путь (метод) возвращает то же самое).

ArrayList<AVLTreeNode<E>> path = path(e); 
+0

путь возвращает ArrayList типа TreeNode – Backwardsman

+1

Так что в этом случае приведение приведет к возникновению проблемы. Поскольку каждый AVLTreeNode является TreeNode, но не другим. –

1

Это не безопасно, что нужно бросить, потому что это правда, что каждый AVLTreeNode является TreeNode, но это не обязательно, что каждый TreeNode является AVLTreeNode. Вы могли бы ваш List держать только AVLTreeNode (s), путем изменения от

ArrayList<TreeNode<E>> path = path(e); 

в

List<AVLTreeNode<E>> path = path(e); 

Но я вам следует запрограммировать на интерфейс (именно поэтому List вместо ArrayList), так что я думаю, вы действительно хотите

List<TreeNode<E>> path = path(e); 

а затем вы можете использовать

TreeNode<E> a = path.get(i); 

И если вы должны знать,

if (a instanceof AVLTreeNode) { 
    // now you can cast a 
AVLTreeNode<E> b = (AVLTreeNode<E>) a; 
} 
+1

AHA! Это сработало .. Большое вам спасибо! Я просто проверил, чтобы убедиться, что a является экземпляром AVLTreeNode. И затем я создал b и использовал это для своих операций. – Backwardsman

0

Можете ли вы показать метод путь, этот манекен метод работы:

public ArrayList<? extends TreeNode<E>> path(E e) { 
     AVLTreeNode<E> tn = new AVLTreeNode<E>(e); 
     ArrayList<AVLTreeNode<E>> list = new ArrayList<AVLTreeNode<E>>(); 
     list.add(tn); 
     return list; 
    }