2010-03-28 1 views
0

Par exemple, disons que ceci est ma classe abstraite:Comment puis-je m'assurer que la fonction de ma classe abstraite ne peut fonctionner que sur des extendeurs du même type que l'appelant?

abstract class A{ 
    int x; 
    int y; 

    void foo(A fooMe); 
} 

... et B et C sont deux classes qui se prolongent A.

Ce que je veux est pour B être seulement capable d'appeler foo() sur d'autres B s, et pour C être seulement capable d'appeler foo() sur d'autres C s. Mais je veux que ce soit hors des mains du programmeur qui étend ma classe A - c'est-à-dire, je veux un moyen d'assurer cette fonctionnalité dans le code A seul.

Que puis-je faire? (Si possible) Je voudrais éviter tout piratage ou génériques solution qui est trop désordonné - je veux encore foo pour pouvoir être appelé comme celui-ci, par exemple:

B b=new B(); 
B bb=new B(); 
bb.foo(b); 

Modifier: I Je suis maintenant prêt à accepter une solution qui utilise des génériques, si quelqu'un a des idées ... (je ne pouvais pas penser à un)?

Répondre

1

Vous pouvez faire foo être final dans A, et mettre en œuvre comme suit: il a lever une exception à moins fooMe.getClass() égal this.getClass(), et par ailleurs appeler la méthode abstraite fooHook. Bien sûr, les sous-classes devront remplacer fooHook, pas foo.

Je crois que l'approche finale-plus-crochet est inévitable: si une sous-classe pourrait passer outre foo, il n'y a aucun moyen A est seul code pourrait garantir que les contrôles effectués dans son foo ne sont pas seulement vont être contournée allègrement par une sous-classe.

+0

(+1) C'est une bonne idée. J'utiliserai certainement ceci si je ne peux pas trouver une autre solution - bien que de façon optimale je voudrais avoir une telle erreur repérée au moment de la compilation, et pas au moment de l'exécution. – Cam

+0

@incrediman, malheureusement je ne crois pas que vous puissiez l'obtenir au moment de la compilation, au moins sans les génériques désordonnés que vous voulez éviter, c'est-à-dire de manière à laisser votre simple exemple de code fonctionner (mais je vous écouterai j'espère que j'ai tort! -) –

+0

Hm. Bien que votre solution évite les génériques comme je l'ai demandé, je pense que je préférerais qu'il utilise des génériques (même malpropres) que de ne pas attraper des choses au moment de la compilation. Je vais regarder un peu moi-même et poster si je trouve quelque chose. Merci encore! – Cam

0

Voici un hack, mais ce n'est pas le temps de compilation. Je ne pense pas que les génériques Java n'ont pas assez de support de type covariant/contravariant.


class B extends A { 
    @Override 
    void foo(A foome) { 
     if (foome.getClass() != getClass()) { 
      throw new UnsupportedOperationException("..."); 
     } 
    } 
} 
0

Vous pouvez appliquer une telle chose si vous utilisez la programmation orientée aspect. Avant le conseil pourrait vérifier et lancer une exception pour les cas qui ont violé vos exigences.

Questions connexes