Existe-t-il un moyen en Java de spécifier que le paramètre de type d'une classe générique doit être une interface (et non simplement l'étendre!)?
Ce que je veux faire est le suivant:
public class MyClass
Signifiant que Y doit être une sous-classe de SomeOtherClass ET implémenter X. Ce que j'obtiens actuellement du compilateur est
Le type X n'est pas une interface; il ne peut pas être spécifié en tant que paramètre borné
Alors, comment puis-je dire au compilateur que X doit toujours être une interface?
Éditer:
D'accord, je suppose que j'ai simplifié un peu mon problème. Utilisons mon domaine d'application réel pour le rendre plus clair:
J'ai une API pour représenter des diagrammes. Un Diagramme contient des objets Noeud et Arête. Ces trois classes implémentent toutes l'interface Forme. Les formes peuvent avoir des formes enfants, une forme parent et appartiennent à un diagramme.
Le problème est que j'ai besoin de créer deux versions de cette API: une open-source avec juste des fonctionnalités de base et une étendue avec plus de fonctionnalités. Cependant, l'API étendue ne doit fournir que des méthodes qui renvoient les types étendus (DiagrammeEtendu, NoeudEtendu, ArêteEtendue et (voici le problème) FormeEtendue).
Donc j'ai quelque chose comme ceci:
/* CLASSES DE BASE */
public interface Forme, Y extends Diagramme>{
public List getFormesEnfant();
public X getParent();
public Y getDiagramme();
...
}
public class Diagramme, Y extends Diagramme> implements Forme{...}
public class Arete, Y extends Diagramme> implements Forme{...}
...
/* CLASSES ÉTENDUES */
public interface FormeEtendue extends Forme { ... }
public class DiagrammeEtendu extends Diagramme implements FormeEtendue { ... }
public class AreteEtendue extends Arete implements FormeEtendue { ... }
...
L'API étendue fonctionne bien et le code de l'API de base donne quelques avertissements, mais le principal problème survient lors de l'utilisation de l'API de base:
public class SomeImporter, Y extends Diagramme, E extends Arete>{
private Y diagramme;
public void ajouterNouvelleArete(E nouvelleArete){
diagramme.ajouterFormeEnfant(nouvelleArete);
...
Cette dernière ligne me donne l'avertissement suivant:
La méthode ajouterFormeEnfant(X) dans le type Diagramme n'est pas applicable pour les arguments (E)
Alors maintenant, j'aimerais simplement spécifier que E doit également implémenter X et tout serait parfait - du moins je l'espère ;)
Tout ceci a-t-il du sens? Connaissez-vous un moyen de le faire? Ou existe-t-il même une meilleure façon d'obtenir l'API étendue avec les restrictions mentionnées?
Merci de m'avoir suivi, toute aide est grandement appréciée!
5 votes
stackoverflow.com/questions/132353/…
0 votes
Cette erreur est un peu incorrecte. Cela signifie vraiment que vous devez vous référer à une classe ou une interface réelle et NON à un autre type générique (c'est-à-dire
Y étend SomeOtherClass & SomeInterface
, comme indiqué dans le lien fourni par @Yochai Timmer)0 votes
Mais c'est là le problème : j'ai besoin d'une interface générique, car j'ai déjà une sous-interface de SomeInterface (appelons-la ExtendedInterface). MyClass est parfois utilisé avec SomeInterface et parfois avec ExtendedInterface. De plus, il pourrait bien y avoir d'autres extensions de SomeInterface à l'avenir... Peut-être ai-je simplifié un tantinet trop ma déclaration de problème, je vais modifier ma question d'origine.
0 votes
Pouvez-vous ajouter la signature de méthode pour votre addNewEdge? - note latérale: Ce sont des ensembles de génériques très compliqués que vous utilisez là, ne vous donnez-vous pas le vertige?
0 votes
Vous pouvez voir la signature de la méthode addNewEdge dans mes messages édités. Si vous voulez dire addChildShape alors ce serait: public void addChildShape(X newShape); (dans l'interface Shape définie ci-dessus)
0 votes
Et oui, c'est assez complexe. Surtout si l'on considère le fait que je veux seulement obtenir les bons types de retour ;)