Java learning_Behavior when there is a method with the same name as a field with the same name in two classes that have an inheritance relationship

Preface

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.

Content of learning

Verification 1: Instantiation = subclass, variable type = superclass

Create an instance of a subclass, set it in a superclass type variable, and verify the behavior when calling it.

Validation source

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();
	}
}

inspection result

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.

Verification 2: Instantiation = subclass, variable type = subclass

This time, the class to be instantiated and the variable type are aligned and verified.

Validation source

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();
	}
}

inspection result

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.

Extra: Behavior when the method overridden from the subclass is lost

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.

Validation source

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();
	}
}

inspection result

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.

Impressions

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

Java learning_Behavior when there is a method with the same name as a field with the same name in two classes that have an inheritance relationship
Isn't there a name collision when enum has the same name in the switch statement?
wsimport error handling (A class / interface with the same name "xxx" is already in use)
[Head panic] Priority when variables / methods with the same name are used in inherited classes
[Java] How to search for a value in an array (or list) with the contains method
How to output the value when there is an array in the array
When calling sshpass from Java with shell etc., it seems that it is necessary to have a path.
A nice workaround when "having an instance of either of the two classes"
Declare a method that has a Java return value with the return value data type
Invoke the character string passed as an argument as a method with send
How to reference a column when overriding the column name method in ActiveRecord
When reassigning to an argument in a Ruby method and then calling `super` → The reassigned one is used
What is the main method in Java?
Cause of is not visible when calling a method of another class in java
Even in Java, I want to output true with a == 1 && a == 2 && a == 3 (gray magic that is not so much as black magic)
Let's create a TODO application in Java 12 Processing when a request comes in with an unused HttpMethod ・ Processing when an error occurs in the server
An embarrassing story that was treated as the same day when trying to compare dates on 3/31 and 4/1 [Java / Calendar]
Processing when an ID that does not exist in the database is entered in the URL
[Java] The problem that true was returned as a result of comparing Integer with ==
Getting started with JavaFX with an app that can calculate the alcohol content when strong zero is divided by a bite