8
votes

Objet de sous-classe de retour de la méthode Superclass

Je continue de revenir à des variantes de ce problème: il a probablement une solution très simple, mais je ne peux pas sembler comprendre ...

J'ai un tas de classes de la forme xquantité, par exemple. DistanceQuanity, AreaQuanity, etc., qui prolonge une qualité de dimensions. Maintenant, vous pouvez ajouter ou soustraire de la distanciation ou de la région, etc., etc., mais vous ne pouvez pas les mélanger, alors je pense que je dois avoir (court) ajouter, soustraire, etc., méthodes dans les sous-classes, mais je veux réduire toute logique duplication au minimum. Cependant, je dois retourner un objet de la sous-classe, ce qui semble difficile à faire de la méthode de la superclasse. Je crois que cela peut être fait à l'aide de la réflexion, mais afaik, vous devez toujours faire une fonte à la fin de la méthode de la sous-classe, et on me dit que la réflexion peut être chère ... Le meilleur que je suis arrivé jusqu'à présent est:

dans latitude de distance (et les autres similaires): p> xxx pré>

dans la dimensionQuantité (moins certaines déclarations pertinentes): p>

public Object add(DimensionQuantity dn, DimensionQuantity d1, DimensionQuantity d2, 
  AbstractUnit au) {
    dn.unit = au;
    dn.scalar = d1.scalar + d2.scalar;
    dn.units = dn.scalar;    
    return dn;   
}


0 commentaires

3 Réponses :


10
votes

Vous pouvez utiliser des génériques comme ceci: xxx

et vous l'étendre comme ceci: xxx

et pour la question initiale, c'est une mauvaise idée vraiment


ressources: < / p>


11 commentaires

C'est mieux (plus claire une fois que vous avez beaucoup de génériques) pour nommer les génériques quelque chose de plus proche de t_dimensionsquantité


Vous avez oublié le mot-clé abstrait. ;) Il suffit d'utiliser «T» est une pratique standard, je pense.


@Mangst Merci, c'est abstrait maintenant. @Egwor, comme @Mangst a dit, t est commun. T Pour type, dans la collecte, c'est E pour l'élément, dans la carte, il est k et V pour la clé et la valeur. Habituellement, c'est la première lettre de votre sens des génériques.


@Colin Considérez-vous la conception de la classe de la classe de GUAVA, car elle s'appuie directement sur les sous-classes ( nullslast , inverse ,. ..)? Juste curieux.


@Willi Schönborn est bien, pour être précis tant que les sous-classes ne font pas partie de l'interface publique du parent, ce n'est pas si mal. Et je n'aurais pas dû utiliser "la faille de conception" mais plutôt "mauvaise pratique".


@Colin Hebert et @benoit Courtine semblent aimer les génériques, mais vous avez apparemment manqué (et j'ai oublié de le pointer) que je veux le «+» dans la superclasse, pas dans la sous-classe. Et @ Colin's Code renvoie Null, ce qui est exactement la mauvaise réponse! Donc, peut-être que SUPER / SUBLASSING n'est pas la bonne approche ...


"Il retourne null" ... tu te moques de moi?!?


Vous voulez la méthode Ajouter () dans la superbe classe? Que cela veut-il dire ? Donner quelques exemples.


@Colin - Je vois // Quel que soit le retour nul; }} N'es-tu pas?


Je veux mettre la logique partagée dans un lieu commun - je soupçonne que la sous-classe / superclasse est la mauvaise technique. Il serait probablement préférable d'utiliser une classe d'assistance. Je vais essayer ça ...


@Paul Morrison, bien sûr, vous devez remplacer le contenu de ajouter () avec votre propre logique et renvoyez votre résultat. Et je pense que vous essayez de résoudre un problème de conception en ajoutant un autre problème de conception. Vous ne devriez pas mettre tous les éléments possibles ajouter () variant dans un lieu commun, il est vraiment difficile de maintenir et ce n'est pas du tout évolutif. Et si vous créez une nouvelle sous-classe de dimensionsQuanity ? Que se passe-t-il si un autre développeur qui ne peut pas accéder à votre code d'assistance souhaite créer sa sous-classe? Vous devriez vraiment regarder cette solution en premier.



0
votes

en Java 6, vous pouvez essayer quelque chose comme ça. Mais utiliser des génériques est également une bonne idée:

public abstract class DimensionQuantity {

    protected int quantity;

    public DimensionQuantity (int quantity) {
        this.quantity = quantity;
    }

    public abstract DimensionQuantity add(DimensionQuantity dq);
}

public class DistanceQuantity extends DimensionQuantity {

    public DistanceQuantity(Quantity quantity) {
        super(quantity);
    }

    /* 
     * A sub-class as return type is authorized.
     * If dq is not a DistanceQuantity, a ClassCastException is thrown, but you can change this.
     */
    @Override 
    public DistanceQuantity add(DimensionQuantity dq) throws ClassCastException {
        return new DistanceQuantity(this.quantity + (DistanceQuantity) dq.quantity);
    }
}


3 commentaires

Mais maintenant, vous pouvez ajouter une entreprise à votre distance.


Oui, mais cela aboutira à une exception classique. Cette action est donc interdite et sera détectée rapidement (mais à l'exécution et non une compilation).


C'est vraiment dangereux, et si vous lancez votre approbation dans une dimensionQuanity, vous ne savez même pas quoi faire sans risquer un CCE.



0
votes

Créer un Enum pour les dimensions:

Dimension de l'énum public {zone, distance, ...}

Jetez vos sous-classes. Au lieu de créer uniquement des objets de dimensions et forcer chacun à avoir une dimension (immuable), définie au temps de création.

Mise en œuvre de l'addition de dimensionsQuanity, vérifiant d'abord que les dimensions des deux quantités ajoutées sont les mêmes.

voila! Moins de classes, type de sécurité, aucun code en double.


1 commentaires

"Premier vérification que les dimensions des deux quantités ajoutées sont les mêmes." - Cela ressemble à un temps d'exécution pour moi!