2012-05-24 25 views
7

Wygląda na to, że nie można tego zrobić, ale czy ktoś ma sprytny sposób na obejście tego problemu?Wymusza typ ogólny na interfejs?

public class SomeClassIterableWrapper<S, T extends SomeClass & S> implements Iterable<S> 

przypadku S ma być interfejs nieznanego typu i SomeClass jest 2D tablicę z indeksem wiersza, działa podobnie do dwukierunkowego JDBC wynikowego. Podklasy SomeClass mają niestandardowe moduły pobierające i ustawiające dla każdej kolumny. Chcę móc powtarzać tę strukturę, tak jakbym robił listę. Chcę zaimplementować wspólny interfejs między moimi SomeClass i Bean, aby mieć dostęp do modułów pobierających i ustawiających. Jako taki S musi być tym interfejsem. Jednak deklaracja, którą podałem, nie działa. Czy istnieje sposób obejścia tego?

edit pokazać mój pożądany realizacji:

public class SomeClassIterableWrapper<S, T extends SomeClass & S> implements Iterable<S>{ 

T object; 

public SomeClassWrapper(T object){ 
    this.object = object; 
} 

@Override 
public Iterator<S> iterator() { 
    object.setIndex(-1); 
    return new SomeClassIterator<S>(); 
} 

private class SomeClassIterator<S> implements Iterator<S> { 

    @Override 
    public boolean hasNext() { 
     return object.index() < object.rowSize() - 1; 
    } 

    @Override 
    public S next() { 
     object.next(); 
     //safe because only interface methods allowed, can't further manipulate index 
     return object; 
    } 

    @Override 
    public void remove() { 
     object.deleteRow(); 
    } 
} 
+2

Co masz na myśli przez ? Java nie obsługuje dziedziczenia wielokrotnego. Czy chcesz uzyskać gwarancję, że T rozszerza SomeClass I implementuje S? –

+0

Zgodnie z opisem, S jest interfejsem –

+1

@LudwigMagnusson, można używać tylko 'extends X' w ogólnej definicji parametru typu, niezależnie od tego, czy' X' jest klasą czy interfejsem. –

Odpowiedz

0

nie można sparametryzować SomeClass z S? Wtedy można mieć

public class SomeClassIterableWrapper<S, T extends SomeClass<S>> 
     implements Iterable<S>{ 
+0

Rozważam parametryzowanie SomeClass jako zupełnie innego rozwiązania. Jeden, w którym SomeClass sam wdroży Iterable. Jednak nie chcę używać tego rozwiązania, ponieważ SomeClass jest często używany w istniejącej bazie kodu. –

+0

Można również rozważyć użycie kompozycji zamiast dziedziczenia, aby istniejące podklasy mogły zamiast tego zawierać odniesienie do 'SomeClass' i być sparametryzowane. – artbristol

-1

Przyznaję, że nie w pełni zrozumieć ten problem, ale to, co proponuję: Załóż interfejs S. Zawiera jedną reklamę metody, która zwraca obiekt S.

public interface SWrapper<S> { 

    S getS(); 

} 

Następnie utwórz realizacji:

public class SImpl implements SWrapper<SImpl> { 

    @Override 
    public SImpl getS() { 
     return this; 
    } 

} 

Teraz można utworzyć:

public class SomeClass<T extends SomeClass & SWrapper<T>> { 

    private final T object; 

    public SomeClass(T object) { 
     this.object = object; 
    } 
} 

trzeba będzie zmodyfikować Wykorzystanie trochę ale być może to działa.

0

myślę S w rozciąga SomeClass & przyjmuje S

public class SomeClassIterableWrapper

musi być określona klasa ponieważ w tym kontekście S musi być klasa, która rozszerza coś.

Czy istnieje sposób, aby zawęzić potencjalne klasy używane zamiast S? Możesz użyć wielu ampersandów, jeśli masz wiele klas , które T powinno rozszerzyć

+0

Tak, to poprawnie identyfikuje problem. Niestety liczba interfejsów S, które opisują, nie jest czymś, co można zawęzić, a w rzeczywistości będzie rosnąć z czasem. –

Powiązane problemy