상속과 다형성 - 동적 바인딩과 정적 바인딩
동적 바인딩과 정적 바인딩
정적 바인딩(Static Binding)
- 컴파일타임(Compile Time)에 선언된 객체의 타입에 따라 호출될 메서드를 인식
-
자바의 멤버 변수는 정적 바인딩이 적용되므로 다형성 특징을 이용하지 못함.
- 선언된 타입의 멤버 변수 접근
-
자바의 클래스 메서드(static method) 역시 정적 바인딩이 적용되므로 다형성 특징을 이용하지 못함.
- 오버라이딩된 자식의 메서드를 호출하는 것이 아니라 각각의 클래스에 별개의 메서드가 존재하는 것
동적 바인딩(Dynamic Binding)
- 런타임(Run Time)에 실제 생성된 객체 타입에 따라 호출될 메서드를 인식
-
자바의 인스턴스 메서드(non-static method)는 동적 바인딩이 적용되므로 다형성의 특징을 적극 이용
- 자식의 클래스에서 부모의 인스턴스 메서드를 오버라이딩(재정의)한 경우, 부모 타입의 참조 변수라고 할지라도 자식 타입의 객체를 생성했다면 자식의 메서드를 호출
메서드 Overridng과 Hiding
메서드 Overridng
- 동적 바인딩이 적용되는 상황
- 자식 클래스에서 부모 메서드를 재정의한 경우 동적 바인딩에 의해 자식의 메서드를 호출
Java
class Employee {
String skill = "Work Hard";
public void getSkill() {
System.out.println("직원 스킬 : " + skill);
}
}
class Engineer extends Employee {
String skill = "Play Hard";
public Engineer(String skill) {
this.skill = skill;
}
// 메서드 오버라이딩(동적 바인딩 적용)
@Override
public void getSkill() {
System.out.prinln("개발자 스킬 : " + skill);
}
}
public class SkillTest {
public static void main(String[] args) {
Employee emeg = new Engineer();
emeg.getSkill(); // 동적 바인딩(런타임 시 오버라이딩 된 자식 객체 메서드 호출)
System.out.println("emeg의 스킬 : " + emeg.skill); // 정적 바인딩(참조 변수 타입인 부모의 변수 접근)
}
}
개발자 스킬 : Play Hard // 인스턴스 메서드는 동적 바인딩
emeg의 스킬 : Work Hard // 멤버 변수는 정적 바인딩
Hiding
- 정적 바인딩이 적용되는 상황
- 자식 클래스에서 부모 클래스의 static 메서드와 똑같은 static 메서드를 정의한 경우
- static 메서드(클래스 메서드)가 오버라이딩이 된 것이 아니라 메서드가 2개 생긴 셈
- 따라서 자식 클래스에서 부모 클래스의 메서드를 숨긴 효과
Java
class Employee {
static String skill = "Work Hard";
public static void getSkill() {
System.out.println("직원 스킬 : " + skill);
}
}
class Engineer extends Employee {
static String skill = "Play Hard";
public Engineer(String skill) {
this.skill = skill;
}
// 메서드 Hiding(정적 바인딩 적용)
// @Override 오버라이딩 annotation 작성 불가
public static void getSkill() {
System.out.prinln("개발자 스킬 : " + skill);
}
// 컴파일 에러 : 부모의 static은 자식이 인스턴스 메서드로 오버라이딩 불가능
/*
public void getSkill() {
System.out.prinln("개발자 스킬 : " + skill);
}
*/
}
public class SkillTest {
public static void main(String[] args) {
Employee emeg = new Engineer();
emeg.getSkill(); // 정적 바인딩(컴파일 시 참조 변수의 타입인 부모의 메서드 호출)
System.out.println("emeg의 스킬 : " + emeg.skill); // 정적 바인딩(참조 변수 타입인 부모의 변수 접근)
}
}
직원 스킬 : Work Hard // 클래스 메서드(static method)는 정적 바인딩
emeg의 스킬 : Work Hard // 멤버 변수는 정적 바인딩