조상 클래스와 자손 클래스의 멤버 변수와 메소드가 중복될 때의 차이를 알아보자.
public class BindingTest {
public static void main(String[] args) {
Parent p = new Child();
Child c = new Child();
System.out.println("p.x: "+p.x);
p.method();
System.out.println("c.x: "+c.x);
c.method();
}
}
class Parent{
int x = 10;
void method() {
System.out.println("Parent Method");
}
}
class Child extends Parent{
int x =20;
void method() {
System.out.println("Child Method");
}
}
코드 실행 결과는 다음과 같다.
p.x: 10
Child Method
c.x: 20
Child Method
이 결과로 조상클래스와 자손클래스의 멤버 변수가 중복될 때에는 참조 변수의 타입의 영향을 받지만, 메소드는 중복되더라도 참조 변수의 타입에 구애 받지 않고 자손 클래스의 메소드를 따른다는 것을 알 수 있다.
다음의 코드를 살펴보자
public class BindingTest2 {
public static void main(String[] args) {
Parent p = new Child();
Child c = new Child();
System.out.println("p.x: "+p.x);
p.method();
System.out.println("c.x: "+c.x);
c.method();
}
}
class Parent{
int x = 10;
void method() {
System.out.println("Parent Method");
}
}
class Child extends Parent{}
결과는 다음과 같다.
p.x: 10
Parent Method
c.x: 10
Parent Method
첫번째 코드와 달리 조상클래스와 자손 클래스의 멤버 변수, 메소드가 중복되지 않은 경우이다.
멤버 변수 및 메소드의 중복이 없으므로 자연히 조상 클래스에 명시된 멤버변수와 메소드가 사용된 것을 알 수 있다.
따라서, 조상클래스와 자손클래스의 멤버변수의 중복이 있을 경우에는 참조변수 타입에 따라 호출되는 멤버 변수가 달라진다는 것을 알 수 있다.
마지막으로 세번째 코드를 살펴보자.
public class BindingTest3 {
public static void main(String[] args) {
Parent p = new Child();
Child c = new Child();
System.out.println("p.x: "+p.x);
p.method();
System.out.println();
System.out.println("c.x: "+c.x);
c.method();
}
}
class Parent{
int x = 10;
void method() {
System.out.println("Parent Method");
}
}
class Child extends Parent{
int x = 20;
void method() {
System.out.println("x: "+x);
System.out.println("super.x: "+super.x);
System.out.println("this.x: "+this.x);
}
}
코드 실행 결과
p.x: 10
x: 20
super.x: 10
this.x: 20
c.x: 20
x: 20
super.x: 10
this.x: 20
앞서 살펴보았듯이 조상클래스와 자손클래스에 메소드 중복이 있더라도 참조변수 타입에 영향을 받지 않고 오로지 자손클래스의 메소드가 실행되는 것을 알 수 있다.
인스턴스 변수 x가 20으로 출력되는 이유는 메소드의 호출은 오로지 자손 클래스에서 일어나기 때문에 this.x의 값과 일치하는 것을 알 수 있다. 참조변수 super는 조상클래스를 의미한다.