Java Puzzlers Advent Calendar 2016 est dans une situation regrettable car il ne manque qu'un seul article, je vais donc remplacer l'article par Day 5 Je vais.
class MyTest
{
private static class A {
String message = "hello";
Consumer<String> hello = s -> System.out.print(message + s);
void hello(String s) { this.hello.accept(s); }
}
private static class B extends A {
String message = "Bonjour";
void hello(String s) { this.hello.accept(s); }
}
public static void main(String[] args) {
A b = (A) new B();
b.hello(" world");
System.out.print("/");
b.hello.accept(" world");
}
}
Le résultat de l'exécution du code ci-dessus est
La réponse est
Cela peut sembler compliqué à première vue, mais en fait, si vous pouvez bien comprendre le polymorphisme, vous devriez être en mesure de le résoudre immédiatement. Jetons un œil au traitement de la méthode main
.
--Dans la première ligne de la méthode main
, nous avons déclaré une variable b
de l'implémentation ʻA type
B. Le processus upcast appelé
(A)` est écrit, mais en fait c'est un travail que le compilateur fait automatiquement, donc c'est juste ennuyeux et sans signification (bien que cela ne provoque pas d'erreur, bien sûr).
b
, le compilateur regarde d'abord si l'implémentation a cette méthode (deuxième ligne). Il y avait une méthode appelée «bonjour» dans la classe «B». Le remplacement n'est pas spécifié, mais comme il n'y a pas de différence dans la signature, nous pouvons voir que la méthode hello
de la classe parente a été remplacée. Les règles du polymorphisme exécutent la méthode «hello» de la classe «B».message
de la classe ʻA est
bonjour, donc le résultat sera
bonjour le monde`. Il y a aussi un champ appelé «message» dans la classe «B», mais il n'a rien à voir avec la fonction «bonjour» que vous utilisez maintenant.main
, il semble que vous utilisiez la fonction bonjour
de l'objet b
. Mais gardez à l'esprit qu'il n'y a pas de remplacement de variable de champ. La fonction hello
définit la procédure de traitement comme la méthode hello
, mais il s'agit essentiellement d'une variable de champ comme message
. Par conséquent, le champ utilisé dépend du type de référence au moment de la déclaration. Puisqu'elle a été déclarée comme ʻA, la fonction
bonjour de la classe ʻA
est utilisée et elle est identique au résultat de sortie sur la deuxième ligne.