9
votes

Java: substituer une sous-classe / sous-type d'un paramètre lors du remplacement d'une méthode?

Alors j'ai déjà posé cette question, mais j'ai eu une erreur dans le code que la plupart des gens ont prises, plutôt que le problème lui-même.

Quoi qu'il en soit, j'essaie de remplacer une méthode d'interface dans une classe. Cependant, je souhaite que le type de paramètre dans la méthode primordiale soit une sous-classe du type du paramètre tel que défini dans la méthode de remplacement. P>

L'interface est la suivante: p> xxx

Bien que la classe qui remplace cette méthode est la suivante: P>

public class ConsoleDrawer extends Drawer {

//...

 @Override
 public void update(ConsoleUpdateEvent updateEvent) throws Exception {
  if (this.componentType != updateEvent.getComponentType()) {
   throw new Exception("ComponentType Mismatch.");
  }
  else {
   messages = updateEvent.getComponentState(); 
  }
 }

//...

}


1 commentaires

Je ne crois pas que cela soit possible car il va à l'encontre du principe d'une interface (c'est-à-dire des classes qui implémentent une interface correspondra exactement à toutes les signatures de méthodes spécifiées par l'interface). Cependant, je vais regarder cette question comme je suis très intéressé de voir si quelqu'un d'autre me prouvera mal.


3 Réponses :


2
votes

Vous pouvez essayer ce qui suit. Le @depecated produit un avertissement si le compilateur sait que vous appellerez la première méthode plutôt que la seconde.

public class ConsoleDrawer extends Drawer {
 @ObserverCallback
 public void onConsoleUpdateEvent(ConsoleUpdateEvent updateEvent) {
   messages = updateEvent.getComponentState(); 
 }
}

public class DeviceDrawer extends Drawer {
 @ObserverCallback
 public void onDeviceUpdateEvent(DeviceUpdateEvent updateEvent) {
   // do something.
 }
}


3 commentaires

Personnellement (et beaucoup d'autres que j'ai parlé) n'aiment pas utiliser l'étiquette obsolète pour autre chose que l'intention d'origine: méthodes de marquage qui étaient valides mais sont maintenant obsolètes. En utilisant quelque chose d'autre comme ça ressemble à Hacker-ish.


@DGH, la méthode utilisée pour être valide (pour le parent) mais n'est plus valide pour cette classe. ;) Je prends ton point cependant. Idéalement, il y aurait une balise qui produisait une erreur de compilateur. Mieux vaut mieux concevoir la méthode de mise à jour () afin que toute la mise en œuvre a honoré le contrat.


Merci pour la suggestion. En utilisant la première solution; J'ai renommé la deuxième méthode de mise à jour sur VOID PRIVÉE AddEventMessages (ConsoleUpDateTevent) {// ...} et cela semble fonctionner de manière raisonnable.



9
votes

vous ne pouvez pas. Ce n'est pas Eiffel. Le problème étant que vous pouvez utiliser l'interface pour appeler la méthode de mise en œuvre avec un type incompatible. Les paramètres de covariant ne sont donc pas autorisés. Les paramètres ContravarianT ne sont pas autorisés non plus, mais il est plus facile de fournir une surcharge. Le type de retour de Covariant est autorisé (puisque 1.5).

Vous pouvez paramétrer l'interface: xxx

Alternativement, utilisez une interface plus significative: xxx


0 commentaires

3
votes

Aller des principes du POOP, une sous-classe doit être utilisable exactement de la même manière que la classe mère. par exemple. xxx

Cependant, si Java vous permettait d'utiliser un sous-type du paramètre lors du remplacement d'une méthode, il exposerait votre code dans des cas où la méthode de dépassement (dans la sous-classe) rejeterait Le paramètre d'entrée (composantUpdateEvent dans le cas ci-dessus). Ainsi, vous ne seriez jamais sûr de savoir si sa mise à jour d'appel sécuritaire () ou non sur une référence d'observateur.

Par conséquent, la seule solution logique consiste à accepter le paramètre Classe parent, vérifiez-le, puis à le jeter au sous-type requis.


0 commentaires