2012-05-24 11 views
7

Parece que esto es imposible de hacer, pero ¿alguien tiene una forma inteligente de resolver este problema?¿Obliga a un tipo genérico a ser una interfaz?

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

donde se supone que S a ser una interfaz de algún tipo desconocido y SomeClass es una matriz 2D con un índice de fila, similar en funcionalidad a un conjunto de resultados JDBC bidireccional. Las subclases de SomeClass tienen getters y setters personalizados para cada columna. Quiero ser capaz de iterar a través de esta estructura como lo haría con una lista. Quiero implementar una interfaz común entre mi SomeClass y Bean para tener acceso a getters y setters. Como tal, S necesita ser esa interfaz. Sin embargo, la declaración que proporcioné no funciona. ¿Hay alguna manera de evitar esto?

de edición para mostrar mi aplicación deseada:

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

¿Qué quiere decir por ? Java no es compatible con herencia múltiple. ¿Desea una garantía de que T extienda SomeClass Y implemente S? –

+0

Como dice en la descripción, S es una interfaz –

+1

@LudwigMagnusson, solo puede usar 'extends X' dentro de una definición de parámetro de tipo genérico, independientemente de si' X' es una clase o una interfaz. –

Respuesta

0

No puedes parametrizar SomeClass con S? Entonces usted podría tener

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

Estoy considerando parametrizar SomeClass como una solución completamente diferente. Uno en el que SomeClass implementaría Iterable. Sin embargo, no quiero utilizar esta solución ya que SomeClass se usa mucho en la base de código existente. –

+0

También podría considerar el uso de la composición en lugar de la herencia, por lo que las subclases existentes podrían contener una referencia a 'SomeClass' y estar parametrizadas. – artbristol

-1

Confieso que no comprendo totalmente el problema, pero esto es lo que sugieren: Crear una interfaz de S. Contiene un método y devuelve el objeto S.

public interface SWrapper<S> { 

    S getS(); 

} 

A continuación, cree una implementación:

public class SImpl implements SWrapper<SImpl> { 

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

} 

Ahora puede crear:

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

    private final T object; 

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

Usted tendrá que modificar su uso de un poco, pero tal vez funciona.

0

creo que el S se extiende en SomeClass & S

SomeClassIterableWrapper clase pública

tiene que ser una clase determinada porque en este contexto, S tiene que ser una clase que se extiende algo.

¿Hay alguna manera de reducir las clases de potencial que se utilizan en lugar de S? podría utilizar varios símbolos de unión si tiene varias clases que T debe extenderse

+0

Sí, eso identifica correctamente el problema. Desafortunadamente, la cantidad de interfaces que describiría S no es algo que pueda reducirse, y de hecho solo crecerá con el tiempo. –

Cuestiones relacionadas