Supongamos que tiene dos interfaces:
interface Readable {
public void read();
}
interface Writable {
public void write();
}
En algunos casos, los objetos de implementación solo pueden soportar uno de estos, pero en muchos casos las implementaciones admitirán ambas interfaces. Las personas que usan las interfaces tendrán que hacer algo como:
// can't write to it without explicit casting
Readable myObject = new MyObject();
// can't read from it without explicit casting
Writable myObject = new MyObject();
// tight coupling to actual implementation
MyObject myObject = new MyObject();
Ninguna de estas opciones es terriblemente conveniente, aún más cuando se considera que desea esto como un parámetro de método.
Una solución sería declarar una interfaz de ajuste:
interface TheWholeShabam extends Readable, Writable {}
Pero esto tiene un problema específico: todas las implementaciones que admiten tanto Readable como Writable tienen que implementar TheWholeShabam si quieren ser compatibles con las personas que usan la interfaz. Aunque no ofrece nada aparte de la presencia garantizada de ambas interfaces.
¿Existe una solución limpia para este problema o debería elegir la interfaz de contenedor?
ACTUALIZAR
De hecho, a menudo es necesario tener un objeto que sea legible y escribible, por lo que simplemente separar las preocupaciones en los argumentos no siempre es una solución limpia.
ACTUALIZACIÓN2
(extraído como respuesta para que sea más fácil comentarlo)
ACTUALIZACIÓN3
Tenga en cuenta que el caso de uso principal para esto no son las transmisiones (aunque también deben ser compatibles). Las transmisiones hacen una distinción muy específica entre entrada y salida y existe una clara separación de responsabilidades. Por el contrario, piense en algo así como un bytebuffer donde necesita un objeto en el que pueda escribir y leer, un objeto que tiene un estado muy específico adjunto. Estos objetos existen porque son muy útiles para algunas cosas como E / S asíncronas, codificaciones, ...
ACTUALIZACIÓN4
Una de las primeras cosas que probé fue la misma que la sugerencia dada a continuación (verifique la respuesta aceptada) pero resultó ser demasiado frágil.
Supongamos que tiene una clase que debe devolver el tipo:
public <RW extends Readable & Writable> RW getItAll();
Si llama a este método, el RW genérico está determinado por la variable que recibe el objeto, por lo que necesita una forma de describir esta var.
MyObject myObject = someInstance.getItAll();
Esto funcionaría, pero una vez más lo vincula a una implementación y, en realidad, puede arrojar ideas de clase en tiempo de ejecución (dependiendo de lo que se devuelva).
Además, si desea una variable de clase del tipo RW, debe definir el genérico a nivel de clase.