66 votes

Java Abstraite de la Classe Implémentant une Interface avec les Génériques

Je suis en train de définir une classe abstraite de la mise en œuvre de Comparable. Quand j'définir la classe avec la définition suivante:

public abstract class MyClass implements Comparable <MyClass>

les sous-classes doivent implémenter compareTo(MyClass object). Au lieu de cela, je veux que chaque sous-classe pour mettre en oeuvre compareTo(SubClass object), en acceptant un objet de son propre type. Lorsque j'essaie de définir la classe abstraite avec quelque chose comme:

public abstract class MyClass implements Comparable <? extends MyClass>

Il se plaint que "Un supertype ne pouvez pas spécifier un caractère générique."

Est-il une solution?

46voto

whiskeysierra Points 2175

C'est un peu trop bavard à mon avis, mais qui fonctionne:

public abstract class MyClass<T extends MyClass<T>> implements Comparable<T> {

}

public class SubClass extends MyClass<SubClass> {

    @Override
    public int compareTo(SubClass o) {
        // TODO Auto-generated method stub
        return 0;
    }

}

19voto

seh Points 8533

Outre les difficultés mécaniques vous êtes à la rencontre de déclarer les signatures, l'objectif n'a pas beaucoup de sens. Vous êtes en train d'établir un covariant fonction de comparaison, ce qui annule l'idée de la création d'une interface que les classes dérivées peuvent adapter.

Si vous définir une sous-classe SubClass de telle sorte que son cas ne peut être comparé à d'autres SubClass des cas, alors comment est - SubClass satisfaire le contrat défini par MyClass? Rappelons qu' MyClass , c'est dire qu'elle et tous les types de dérivés, peuvent être comparées avec les autres MyClass des cas. Vous êtes en essayant de le faire n'est pas vrai pour SubClass, ce qui signifie qu' SubClass ne permet pas de satisfaire MyClasss'contrat: Vous ne pouvez pas remplacer SubClass pour MyClasscar SubClasss'exigences sont plus strictes.

Ce problème centres de la covariance et la contravariance, et comment ils permettent de signatures de fonction pour changer le type de dérivation. Vous pouvez vous détendre à une exigence sur un argument du type d'accepter un plus grand type de la supertype signature de la demande-et vous pouvez renforcer l'obligation d'un retour de type promettant de revenir un étroit type que le supertype de la signature. Chacune de ces libertés permet encore de substitution parfaite du type dérivé pour le supertype; un appelant ne peut pas faire la différence lors de l'utilisation du type dérivé à travers le supertype de l'interface, mais un appelant à l'aide de la dérivée de type concrète peut profiter de ces libertés.

Willi réponse de l' enseigne quelque chose à propos de déclarations génériques, mais je vous invite à reconsidérer votre objectif avant d'accepter la technique au détriment de la sémantique.

3voto

irreputable Points 25577

voir Java propre exemple:

public abstract class Enum<E extends Enum<E>> implements Comparable<E>
    public final int compareTo(E o)

sur seh commentaire: généralement, l'argument est correct. mais les génériques rend le type de relations plus complexes. une sous-classe peut ne pas être un sous-type de MyClass dans Willi solution....

SubClassA est un sous-type d' MyClass<SubClassA>, mais pas un sous-type d' MyClass<SubClassB>

type MyClass<X> définit un contrat d' compareTo(X) tous ses sous-types doivent honorer. il n'y a pas de problème.

1voto

zevra0 Points 261

Je ne suis pas sûr que vous avez besoin de la capture:

Tout d'abord, ajoutez le compareTo à la classe abstraite...

public abstract class MyClass implements Comparable <MyClass> {

@Override
public int compareTo(MyClass c) {
...
}    
}

Puis ajouter les implémentations...

public class MyClass1 extends MyClass {
...
}

public class MyClass2 extends MyClass {
...
}

L'appel à comparer appeler le super type de méthode...

MyClass1 c1 = new MyClass1();
MyClass2 c2 = new MyClass2();

c1.compareTo(c2);

1voto

newacct Points 42530
public abstract class MyClass<T> implements Comparable<T> {

}

public class SubClass extends MyClass<SubClass> {

    @Override
    public int compareTo(SubClass o) {
        // TODO Auto-generated method stub
        return 0;
    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X