Java Puzzlers Advent Calendar 2016 is in a regrettable situation that only one post is missing, so I will substitute the article for Day 5 I will.
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 = "Hello";
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");
}
}
The result of executing the above code is
-[] A. Hello world / hello world -[] B. Hello world / Hello world -[] C. hello world / hello world
The answer is
It may seem complicated at first glance, but in fact, if you can understand polymorphism properly, you should be able to solve it immediately. Let's take a look at the processing of the main
method.
--The first line of the main
method declares a variable b
of the ʻA type
Bimplementation. The upcast process called
(A)is written, but in fact it is a work that the compiler does automatically, so it is just annoying and meaningless (although it does not cause an error, of course). --When using a method of
b, the compiler first looks to see if the implementation has that method (second line). There was a method called
hello in class
B. The override isn't specified, but you can see that the parent class's
hellomethod has been overridden because the signatures are the same. The rules of polymorphism execute the
hello method of class
B. --The method called
hello calls the field of the consumer function called
hello, but unfortunately
hello exists only in the ʻA
class. Therefore, it is unavoidable to use the hello
function in the ʻAclass. (By the way, duplicate method names and field names are allowed, so no compilation error will occur.) --The function
hello uses the field
message. The
message of class ʻA
is hello
, so the output will be hello world
. There is also a field called message
in class B
, but it has nothing to do with the hello
function you are using now.
――Furthermore, on the 4th line of main
, it looks like you are using the hello
function of the b
object. But keep in mind that there are no field variable overrides. The hello
function, like the hello
method, defines the processing procedure, but is essentially a field variable like message
. Therefore, which field is used depends on the reference type at the time of declaration. Since it was declared as ʻA, the
hello function of class ʻA
is used and it looks the same as the output result on the second line.