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.