
변수는 오버라이딩X, 메서드는 오버라이딩O
class Parent {
String name = "Parent";
void printNames() {
System.out.println(name);
}
}
class Child extends Parent {
String name = "Child";
void printNames() {
System.out.println(name);
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
c.printNames(); // (1)
Parent p = new Child();
p.printNames(); // (2)
}
}실행결과
Child
Child메서드는 실제타입 기준으로 실행된다. printNames()는 오버라이딩된 메서드이기 때문에 참조 타입(Parent든 Child든)과 무관하게 객체의 실제 타입(new Child())을 따라간다. 그래서 둘 다 Child의 printNames()가 호출된다.
- 참조 타입 (Reference Type) : 변수를 선언할 때 사용한 클래스 타입
- 실제 타입 (Runtime Type) : new 키워드 뒤에 오는 실제 생성된 객체 타입
Foo obj = new Bar()
// 참조 타입 : Foo
// 객체 타입 : Bar출력은 왜 "Child"가 됐을까?
Child 클래스 안에 String name = "Child"라는 멤버 변수가 선언되어 있고, 이 때 오버라이딩 된 메서드 안에서 name을 참조하면 현재 클래스의 멤버 변수를 참조한다. 그래서 출력이 Child가 된 것이다. 이런 현상을 변수 은닉(variable hiding) 이라고 한다.
반면, 변수는 동적 바인딩이 안 된다.
변수는 메서드처럼 오버라이딩되지 않는다.
변수는 컴파일 타임의 타입(참조형)을 기준으로 동작한다.
하지만 printNames() 안에서는 자기 자신의 name을 쓰므로 Child 클래스의 name이 출력된다.
변수의 접근 방식
Child c = new Child();
System.out.println(c.name); // Child
Parent p = new Child();
System.out.println(p.name); // Parent ← 변수는 참조 타입 따라감1. Child c = new Child();
- Child 타입 참조변수 c가 Child 객체를 가리킴
- Child 클래스의 모든 필드, 메서드에 접근 가능 (단, 접근 제한자 고려)
- 동적 바인딩 적용됨
2. Parent p = new Child();
- Parent 타입 참조변수 p가 Child 객체를 가리킴
- 참조 변수 p는 Parent 클래스에 정의된 멤버만 접근 가능
- 단, 오버라이딩된 메서드는 실제 객체 타입(Child)에 따라 실행됨
고유 메서드 접근 가능 여부
class Parent {
String name = "Parent";
void whoAmI() {
System.out.println("I'm Parent");
}
}
class Child extends Parent {
String name = "Child";
void whoAmI() {
System.out.println("I'm Child");
}
void onlyChild() {
System.out.println("Only in Child");
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
Parent p = new Child();
c.whoAmI(); // ✅ "I'm Child"
c.onlyChild(); // ✅ Child의 고유 메서드 접근 가능
System.out.println(c.name); // ✅ "Child"
p.whoAmI(); // ✅ "I'm Child" (동적 바인딩)
// p.onlyChild(); // ❌ 컴파일 오류
System.out.println(p.name); // ✅ "Parent" (변수는 정적 바인딩)
}
}- c와 p 모두 Child 객체를 참조하고 있지만, p는 Parent 타입이므로 Parent에 선언된 것만 사용 가능하다.
- 참조타입이 Parent인데 Child 클래스에만 있는 onlyChild()라는 메서드는 실행할 수 없다.
- 메서드는 동적 바인딩으로 c.whoAmI()와 p.whoAmI() 모두 Child 버전을 실행한다.(오버라이딩)
- 변수는 정적 바인딩이라 p.name은 "Parent", c.name은 "Child" 출력
'Java' 카테고리의 다른 글
| [Java] Main.java unchecked or unsafe operations 에러 해결법 (2) | 2025.09.04 |
|---|---|
| [Java] local variables referenced from a lambda expression must be final or effectively final 에러 해결법 (6) | 2025.08.18 |
| [Java] (상속)변수는 메서드처럼 오버라이딩 되지 않는다. (3) | 2025.06.24 |
| [Java] 자바에서 this, 생성자 호출시 this() (3) | 2025.06.22 |
| [Java] JVM의 작동 원리 (5) | 2025.05.13 |