2013-10-11 3 views
0

Я безумно рад сказать, что я только что реализовал общий список ссылок из нескольких недель назад в проекте и IT WORKS! Одна проблема. Я вынужден сделать бросок (и не ожидал).Использование обобщенного связанного списка, но принудительного использования (приведение) при появлении

Вот некоторые фрагменты, я надеюсь, достаточно, чтобы определить проблемы, начиная с общим стеком:

public class GenericStack<E> { 

     public LinkedList <E> stack = new LinkedList<>(); 

     public void push (E obj){ 
     stack.add(obj); 
     } 

     public E pop() { 
     if (stack.isEmpty()) return null; 
     return stack.removeLast(); 
     } 
     ... 
} 

Вот класс Defintion, в котором я использую общий стек:

public class Grid extends GenericStack<JTextField> implements ActionListener, KeyListener, KeyCodes 

Вот мне определяя stack и то, что я нажимаю и выскакиваю:

GenericStack stack = new GenericStack(); 
    public static JTextField[][] cells = new JTextField[11][11]; 

Вот я толкая на stack:

stack.push(Grid.cells[currentCell.row][currentCell.col]); 

Вот где я выскочить из stack, который работает ТОЛЬКО ЕСЛИ ДЕЛАТЬ CAST показано ниже:

private void calculate(){ 
    JTextField w = new JTextField(); 
    while(stack.size()>0){ 
     w = (JTextField) stack.pop(); 
     System.out.println("stack element " + w.getText()); 
    } 
    } 

Теперь я не жалуюсь; Я даже не уверен, что есть проблема с этим, но без броска (JTextField) я получаю «НЕОБХОДИМЫЕ ТИПЫ - ТРЕБУЕТСЯ: JTextField; НАЙДЕН: Объект», но stack.pop() четко определен, чтобы вернуть общий тип, который является JTextField , так зачем мне бросать?

ответ

4

Это проблема:

GenericStack stack = new GenericStack(); 

Вот с помощью сырого типа из GenericStack. Непонятно, почему у вас это вообще есть, если вы уже расширили GenericStack<JTextField>, чтобы быть честным.Я бы ожидать вас либо использования композиции:

public class Grid implements ActionListener, KeyListener, KeyCodes { 
    private final GenericStack<JTextField> stack = new GenericStack<JTextField>(); 

    private void calculate() { 
     while (stack.size() > 0) { 
      JTextField w = stack.pop(); 
      System.out.println("stack element " + w.getText()); 
     } 
    } 
} 

или использовать наследование:

public class Grid extends GenericStack<JTextField> 
    implements ActionListener, KeyListener, KeyCodes { 

    private void calculate() { 
     while (size() > 0) { 
      JTextField w = pop(); 
      System.out.println("stack element " + w.getText()); 
     } 
    } 
} 

На данный момент вы смешиваете два, который действительно странно.

1

Вы использовали необработанный тип вашего общего типа в следующей конкретизации:

GenericStack stack = new GenericStack(); 

При использовании сырья типов, все общий тип внутри класса заменяются сыр типа контрагентом, а параметры типа заменяются их стираниями. Поскольку стирание E в вашем случае - Object, так как оно не имеет никаких ограничений. Таким образом, связанный список, и методы:

public LinkedList <E> stack = new LinkedList<>(); 
public void push (E obj) { ... } 
public E pop() { ... } 

будут стерты с:

public LinkedList stack = new LinkedList(); 
public void push(Object obj) { ... } 
public Object pop() { ... } 

, следовательно, вы получите обратно Object типа, при вызове метода pop().

Что вам нужно, это параметризованных конкретизации:

GenericStack<JTextField> stack = new GenericStack<>(); 

И, конечно же, что сказал JonSkeet в своем ответе. Не смешивайте наследование и состав. У вас есть ссылка типа GenericStack, а также распространяется на него. Это не имеет смысла. Следуйте совету в ответе Джона.

0

D'OH !!

Так счастливы, что работал я проглядел несколько очевидных (для опытного народа) вещей (что я действительно не повода для вида), так что да, я сделал изменения Рохят Jain предложенных (отметив же от Jon тарелочек) и у меня есть изящнее метод выскакивают:

private void calculate(){ 
    while(stack.size()>0){ 
     System.out.println("stack element " + stack.pop().getText()); 
    } 
    } 

(метод называеться calculate, потому что он собирается сделать это в ближайшее время.)

Но, Джон, я не вижу, как мой код указывает что я смешиваю состав и наследование, но может быть, это потому, что я не совсем понимаю сейчас!

Я расскажу вам об этом: ежедневное (дневное?) Разочарование просто для того, чтобы получить еще одну строку кода для работы: более. Java камни! (как только вы доберетесь до определенной точки на кривой обучения!) Я ошеломлен тем, как далеко я пришел сюда всего за пару дней! (Хорошо, возможно, кофе помог!)

+0

Вы можете отметить один из ответов, как принято. Что касается путаницы композиции и наследования, мы думали, что ваша декларация «GenericStack» находится внутри класса «Grid». Если это не так, тогда все в порядке. –

+0

Я печатал, когда Rojit отправил второй раз. Это отличное объяснение, так как стирание подняло голову днем ​​или два назад, и я решил подождать до поры до времени. Ну, это позже, и я думаю, что понял. БЛАГОДАРЮ. Но теперь я должен снова попытаться справиться с «дублированием», так как теперь вы оба говорили об этом. Я получу его, может быть, даже сегодня. И я просто перечитываю обе записи. Я могу иметь его, даже когда я печатаю. Еще раз спасибо. – DSlomer64

+0

Я ПОЛУЧИЛ ЭТО! Я удалил предложение extends и, конечно же, сработал. Я не понимал (не думал), что, когда GenericStack является частью одного и того же пакета, расширения являются излишними. Но обратите внимание: одна причина расширилась, в первую очередь, было то, что я был HOPING для импорта genericstack, но я не мог заставить его работать, поэтому я сдался и просто скопировал пакет genericstack в текущий. (Думаю, я вернусь к попытке импортировать, так как это очень важно, чтобы иметь возможность делать, особенно с собственным классом!) – DSlomer64

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