Supposons que vous ayez deux interfaces:
interface Readable {
public void read();
}
interface Writable {
public void write();
}
Dans certains cas, les objets d'implémentation ne peuvent prendre en charge que l'un d'entre eux, mais dans de nombreux cas, les implémentations prendront en charge les deux interfaces. Les personnes qui utilisent les interfaces devront faire quelque chose comme:
// 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();
Aucune de ces options n'est terriblement pratique, d'autant plus si l'on considère que vous le souhaitez comme paramètre de méthode.
Une solution serait de déclarer une interface d'encapsulation:
interface TheWholeShabam extends Readable, Writable {}
Mais cela a un problème spécifique: toutes les implémentations qui prennent en charge Readable et Writable doivent implémenter TheWholeShabam si elles veulent être compatibles avec les personnes utilisant l'interface. Même s'il n'offre rien à part la présence garantie des deux interfaces.
Existe-t-il une solution propre à ce problème ou dois-je opter pour l'interface wrapper?
MISE À JOUR
En fait, il est souvent nécessaire d'avoir un objet à la fois lisible et inscriptible, donc séparer simplement les préoccupations dans les arguments n'est pas toujours une solution claire.
UPDATE2
(extrait comme réponse, il est donc plus facile de commenter)
UPDATE3
Veuillez noter que le principal cas d'utilisation n'est pas les flux (bien qu'ils doivent également être pris en charge). Les flux font une distinction très spécifique entre les entrées et les sorties et il y a une séparation claire des responsabilités. Pensez plutôt à quelque chose comme un bytebuffer où vous avez besoin d'un objet sur lequel vous pouvez écrire et lire, un objet qui a un état très spécifique qui lui est attaché. Ces objets existent car ils sont très utiles pour certaines choses comme les E / S asynchrones, les encodages, ...
UPDATE4
L'une des premières choses que j'ai essayées était la même que la suggestion donnée ci-dessous (vérifiez la réponse acceptée) mais elle s'est avérée trop fragile.
Supposons que vous ayez une classe qui doit retourner le type:
public <RW extends Readable & Writable> RW getItAll();
Si vous appelez cette méthode, le RW générique est déterminé par la variable qui reçoit l'objet, vous avez donc besoin d'un moyen de décrire cette var.
MyObject myObject = someInstance.getItAll();
Cela fonctionnerait, mais une fois de plus le lie à une implémentation et peut en fait lever des exceptions classcastex au moment de l'exécution (en fonction de ce qui est retourné).
De plus, si vous souhaitez une variable de classe de type RW, vous devez définir le générique au niveau de la classe.