Lorsque le remplacement est égal à Java, pourquoi ne pas utiliser un paramètre autre que Object?
Je suis tombé sur un problème intéressant récemment. Il semble que, si je remplace .equals() prend un paramètre autre que l'Objet, il n'est pas appelée. Quelqu'un peut-il m'expliquer pourquoi ce qui se passe? Il semble violer ma compréhension du polymorphisme programmation orientée objet, mais peut-être que je suis absent quelque chose.
Ici est beaucoup plus simple de code qui montre ce que je vois:
public class MyClass {
private int x;
public MyClass(int n) { x = n; }
public boolean equals(Object o) { return false; }
public boolean equals(MyClass mc) { return x == mc.x; }
public static void main(String[] args) {
List<MyClass> list = new ArrayList<MyClass>();
list.add(new MyClass(3));
System.out.println("Contains 3? " + list.contains(new MyClass(3)));
}
}
Lorsque cela est exécuté, il affiche "Contains 3? false
". Il ressemble à la equals(Object) la fonction est appelée, même si il y a un autre qui serait à l'œuvre. Par contre, si j'écris est égal à l'instar de ce que le code fonctionne comme prévu:
public boolean equals(Object o) {
if(!(o instanceof MyClass))
return false;
MyClass mc = (MyClass)o;
return x == mc.x;
}
Pourquoi n'est-il pas de trouver la version de la fonction à appeler en fonction du type du paramètre?
source d'informationauteur Kip | 2008-11-21
Vous devez vous connecter pour publier un commentaire.
Vous avez mélangé "substitution" et de "surcharge".
Prépondérant-ajout d'un remplacement de la définition d'une méthode existante pour les fins de polymorphisme. La méthode doit avoir la même signature. La signature consiste dans le nom et les types d'argument. Méthodes de remplacement sont sélectionnés au moment de l'exécution basé sur le moteur d'exécution type de l'objet cible.
Surcharge -- ajout d'une méthode avec le même nom mais une signature différente. Les méthodes surchargées sont sélectionnés au moment de la compilation basée sur le temps de compilation du type de l'objet cible.
equals(Object) est remplacer une super méthode; vous pouvez pas remplacer une super méthode sans utiliser exactement la même signature (Bien, il y a des exceptions, comme covariants returntypes et d'exception).
Avis que la méthode que vous appelez est défini dans la javadoc de ArrayList
<E
> commeau lieu de
Mise en œuvre de ArrayList.java:
Il utilise la méthode equals définies dans l'Objet de la superclasse depuis la méthode equals n'est pas remplacée dans les ArrayList
<E
>'s la mise en œuvre.Lors de la substitution de l'Objet est égale à java, vous devez remplacer l'Objet de la méthode hashCode.
De toute façon, vous pourriez vouloir essayer le code suivant:
il existe différents types de http://en.wikipedia.org/wiki/Polymorphism_(computer_science). java ne permet pas de faire http://en.wikipedia.org/wiki/Double_dispatch.
La liste de tableaux de mise en œuvre de la contains(Object) de la méthode est lié à l'utilisation de l'Objet.equals(Object) méthode interne, de sorte qu'il ne serez jamais savoir à propos de votre surcharge de l'est égal à(Maclasse) de la méthode. Seulement une méthode de remplacement (avec signature correspondante).
Ok permettez-moi de reformuler.
(1), Car le compilateur élimine toutes les informations relatives aux médicaments Génériques (effacement, voir ici), et (2) parce que vous ne pouvez pas remplacer une méthode sans exactement la même signature (equals(Object)), (3) au cours de l'exécution de tous les objets à l'intérieur de la Liste sont traitées comme des Objets et non comme des instances de Maclasse. Par conséquent, la méthode qui est appelée est equals(Object) puisque c'est celui qui est été remplacée par votre classe.
Vous êtes en supposant que le
contains()
méthode dansList
sait le type de l'objet au moment de l'exécution, ce qui est incorrect.En raison de l'effacement,
List<MyClass>
devient juste unList
au moment de l'exécution, de sorte que lecontains()
méthode voit son paramètre comme unObject
donc l'invocation de l'Objetequals()
à la place de celle que vous avez définie pourMyClass
dans son exécution.