2013-12-04 4 views
0

Его очень ясно видно, что это проблема, с которой столкнулись другие. Тем не менее, я просто не могу найти решения, которые другие предложили для компиляции с использованием дженериков, а не подстановочных знаков из-за дополнительной сложности интерфейса здесь.Ошибки, получающие абстрактный класс, интерфейс и расширяющий класс для реализации дженериков без подстановочных знаков

Код ниже компилируется, но мне не нравится, что я использую подстановочный знак, а не общий.

ListSorter.Java

import java.util.List; 
public interface ListSorter <T> { 
    public List<T> sort(List<T> list); 
} 

AbstractListSorterTest.java

package com.learning.test.algorithms; 

import com.learning.algorithms.sorting.ListSorter; 


import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 

import junit.framework.TestCase; 

public abstract class AbstractListSorterTest extends TestCase { 
    private List<String> unsortedStringList; 
    private List<String> sortedStringList; 

    // Eclipse shows "ListSorter is a raw type. References to generic type ListSorter<T> should be parameterized" 
    protected abstract ListSorter createListSorter(); 

    public void testSortSimpleStrings() { 
     ListSorter sorter = createListSorter(); 
     List<?> result = sorter.sort(unsortedStringList); 

     assertEquals(unsortedStringList.size(), result.size()); 

     Iterator<?> actual = result.iterator(); 
     Iterator<?> expected = sortedStringList.iterator(); 

     while (actual.hasNext() && expected.hasNext()) { 
      assertEquals(expected.next(), actual.next()); 
    } 
} 

Если я стараюсь следующее:

List<T> result = sorter.sort(unsortedStringList); 

Я получаю ошибку компилятора «T не может быть разрешен к типу »(который я получаю для множества разных типов решений).

UPDATE

Ответим Стюарт был на месте, и теперь у меня есть одно предупреждение осталось.

В BubblesortListSorterTest.java, я получаю следующее предупреждение:

The return type ListSorter<T> for createListSorter() from the type BubblesortListSorterTest<T> needs unchecked conversion to conform to ListSorter<Object> from the type AbstractListSorterTest 

BubblesortListSorterTest.java

public class BubblesortListSorterTest<T extends Comparable<? super T>> extends AbstractListSorterTest { 

    @Override 
    protected ListSorter<T> createListSorter() { 
    return new BubblesortListSorter<T>(); 
    } 
} 

Update 2

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

BubblesortListSorterTest.java

public class BubblesortListSorterTest extends AbstractListSorterTest { 

    @Override 
    protected <T extends Comparable<? super T>> ListSorter<T> createListSorter() { 
    return new BubblesortListSorter<T>(); 
    } 
} 

AbstractListSorterTest.java

protected abstract <T extends Comparable<? super T>> ListSorter<T> createListSorter(); 


    public void testSortSimpleStrings() { 
    ListSorter<String> sorter = createListSorter(); 
    List<String> result = sorter.sort(unsortedStringList); 

    assertEquals(unsortedStringList.size(), result.size()); 

    Iterator<String> actual = result.iterator(); 
    Iterator<String> expected = sortedStringList.iterator(); 

    while (actual.hasNext() && expected.hasNext()) { 
     assertEquals(expected.next(), actual.next()); 
    } 
    } 

ListSorter.java

public interface ListSorter <T> { 
    public List<T> sort(List<T> list); 
} 

BubblesortListSorter.java

public class BubblesortListSorter <T extends Comparable<? super T>> implements ListSorter<T> { 

    @Override 
    public List<T> sort(List<T> list) { 
    for (int outer = 1; outer < list.size(); outer++) { 
     for (int left = 0; left < (list.size() - outer); left++) { 
     int right = left + 1; 
     if (list.get(left).compareTo(list.get(right)) > 0) { 
      swap(list, left, right); 
     } 
     } 
    } 
    return list; 
    } 

    private void swap(List<T> list, int leftPos, int rightPos) { 
    T temp = list.get(leftPos); 
    list.set(leftPos, list.get(rightPos)); 
    list.set(rightPos, temp); 
    } 
} 

ответ

1

AbstractListSorterTest хочет протестировать реализацию ListSorter, используя список строк. Поэтому тест должен рассказать, кто создает ListSorter, что T должен быть String. Если один были инстанцировании ListSorter непосредственно (например, как анонимный внутренний класс) можно было бы написать что-то вроде

ListSorter<String> sorter = new ListSorter<String>() { ... }; 

Вместо этого, вы хотите, чтобы экземпляр сортировщик, который будет создан абстрактный метод createListSorter(). Предположительно, что-то внутри этого метода будет строить реализацию ListSorter. Поэтому вам нужно передать аргумент типа через createListSorter(), чтобы он мог передать этот аргумент в конструктор ListSorter.Способ сделать это, чтобы сделать createListSorter() общий метод:

abstract <T> ListSorter<T> createListSorter(); 

Затем изменить точку вызова в тесте на это:

ListSorter<String> sorter = createListSorter(); 

(компилятор делает вывод, что T является String в этом случае так что вам не нужно передавать явный аргумент типа.)

На этом этапе вы можете изменить последующие объявления от Iterator<?> до Iterator<String>.

Следующая проблема, с которой вы столкнетесь, заключается в том, что реализация ListSorter не сможет сортировать объекты произвольного типа T, так как нет возможности их сравнить. Либо вам нужно будет передать объект-компаратор в абстрактную фабрику и конструктор ListSorter, либо вам придется добавлять ограничения типов, чтобы гарантировать, что T является подтипом Comparable. Посмотрите на перегрузки Collections.sort() в JDK documentation для идей сигнатур общего типа, которые необходимо добавить.

+0

Супер полезно! Осталось только одно предупреждение компилятора. «Возвращение типа ListSorter для createListSorter() от типа BubblesortListSorterTest потребности бесконтрольно преобразования, чтобы соответствовать ListSorter от типа AbstractListSorterTest \t BubblesortListSorterTest.java» – eb80

+0

Не знаю, где '' ListSorter откуда. Мне нужно будет увидеть код. Возможно, вам придется указать явный тип в вызове create, например, 'ListSorter sorter = this. createListSorter() '. –

+0

Я опубликовал два обновления, и теперь он работает на 100%. Большая часть кода выше. Бесконечно благодарен! – eb80

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