I will leave a memorandum of what I learned while studying for the Java Silver 11 qualification.
It was difficult to understand the behavior when there was a field with the same name and a method with the same name in two classes that have an inheritance relationship, so I tried learning while verifying.
Create an instance of a subclass, set it in a superclass type variable, and verify the behavior when calling it.
Astudy class
class Astudy {
String val = "A";
void print() {
System.out.println("A study output->" + val);
}
}
Bstudy class
class Bstudy extends Astudy {
String val = "B";
void print() {
System.out.println("Bstudy output->" + val);
}
}
Execution class
public class Study {
public static void main(String[] args) {
Astudy a = new Astudy();
Astudy b = new Bstudy();
System.out.println("Output of variable a->" + a.val);
System.out.println("Output of variable b->" + b.val);
a.print();
b.print();
}
}
Result of verification 1
Output of variable a->A //Referencing a superclass
Output of variable b->A //Referencing the superclass ...(1)
A study output->A //Calling a superclass method
Bstudy output->B //Calling a subclass method ...(2)
** Explanation of (1) ** The Bstudy class was instantiated, but the output is the value of the Astudy class. This is because the object that created the instance is set to the Astudy class type. Since there is a rule that ** field reference uses the one declared by the variable type **, the value defined in the Astudy class is output according to this rule.
** Explanation of (2) ** Unlike the field, the method call ** calls the method of the instantiated class **, so the print () method of the Bstudy class is executed. Although it inherits the Astudy class, the reference destination of the field is the value of the field defined in the Bstudy class because the scope is not specified in the variable.
// Comment Scope = this or super. this or, if omitted, refer to its own class. In case of super, refer to the inheriting class.
This time, the class to be instantiated and the variable type are aligned and verified.
Astudy class
class Astudy {
String val = "A";
void print() {
System.out.println("A study output->" + val);
}
}
Bstudy class
class Bstudy extends Astudy {
String val = "B";
void print() {
System.out.println("Bstudy output->" + val);
}
}
Execution class
public class Study {
public static void main(String[] args) {
Astudy a = new Astudy();
Bstudy b = new Bstudy(); //Change type to Bstudy
System.out.println("Output of variable a->" + a.val);
System.out.println("Output of variable b->" + b.val);
a.print();
b.print();
}
}
Result of verification 1
Output of variable a->A //Referencing a superclass
Output of variable b->B //Referencing a subclass ...(1)
A study output->A //Calling a superclass method
Bstudy output->B //Calling a subclass method ...(2)
** Explanation of (1) ** By setting the instance to a variable of subclass type, the field reference destination is different from the verification 1.
** Explanation of (2) ** Same result as verification 1. Make sure it does not affect the type of the variable.
In verification 1 and verification 2, Bstudy overridden the print () method of the inherited Astudy class, but the behavior when this is not overridden is verified.
Astudy class
class Astudy {
String val = "A";
void print() {
System.out.println("A study output->" + val);
}
}
Bstudy class
class Bstudy extends Astudy {
String val = "B";
// print()Delete method
}
Execution class
public class Study {
public static void main(String[] args) {
Astudy a = new Astudy();
Astudy b = new Bstudy(); //Change type to Astudy
System.out.println("Output of variable a->" + a.val);
System.out.println("Output of variable b->" + b.val);
a.print();
b.print();
}
}
Result of verification 1
Output of variable a->A //Referencing a superclass
Output of variable b->A //Referencing the superclass ...(1)
A study output->A //Calling a superclass method
A study output->A //Calling a superclass method ...(2)
** Explanation of (1) ** The same result was obtained because the variable type was changed to the superclass as in the verification 1.
** Explanation of (2) ** Since there are no methods in the subclass, the inherited method was called. The behavior when creating an instance of a subclass is that the subclass and the superclass are combined into one instance. At this time, if methods with the same definition match each class, the subclass method is overriding (overriding). Since verification 1 is the above pattern, the method of Bstudy class was called. Since the verification of the extra edition was not overwritten, the method of the Astudy class was called.
There was no practical case where I had to be aware of this, so I was confused about my understanding. The reason why the method uses the instance-time class while the field is declared with the variable type seems to be due to the difference between compile-time and run-time, but this is still well understood. Not. This is a future issue.
Recommended Posts