앞서 공부한 오버로딩은 서로 다른 시그니처를 갖는 여러 메소드를 하나의 이름으로 정의하는 것
오버라이딩은 상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니처를 갖는 메소드로 다시 정의하는 것
class Parent {
void display() { System.out.println("부모 클래스의 display() 메소드입니다."); }
}
class Child extends Parent {
void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
}
public class Inheritance05 {
public static void main(String[] args) {
Parent pa = new Parent();
pa.display();
Child ch = new Child();
ch.display();
Parent pc = new Child();
pc.display(); // Child cp = new Parent();
}
}
>> 실행 결과
부모 클래스의 display() 메소드입니다.
자식 클래스의 display() 메소드입니다.
자식 클래스의 display() 메소드입니다.
// Child cp = new Parent();
예제에서 세 번째와 같은 인스턴스의 참조가 허용되는 이유는 자바에서의 다형성(polymorphism)때문
오버로딩 - 새로운 메소드 정의
오버라이딩 - 상속받은 기존의 메소드 재정의
밑의 예제는 오버로딩과 오버라이딩 둘 다 수행하는 예제
class Parent {
void display() { System.out.println("부모 클래스의 display() 메소드입니다."); }
}
class Child extends Parent {
// 오버라이딩된 display() 메소드
void display() { System.out.println("자식 클래스의 display() 메소드입니다."); }
void display(String str) { System.out.println(str); } // 오버로딩된 display() 메소드
}
public class Inheritance06 {
public static void main(String[] args) {
Child ch = new Child();
ch.display();
ch.display("오버로딩된 display() 메소드입니다.");
}
}
>> 실행 결과
자식 클래스의 display() 메소드입니다.
오버로딩된 display() 메소드입니다.
서로 다른 자료형을 연산 혹은 대입하는 경우 자바 컴파일러가 자료형을 통일
→ 표현 범위가 좁은 데이터 타입에서 넓은 데이터 타입으로의 변환만 허용 (데이터 손실이 되기 때문)
데이터 손실을 감수하더라도 강제로 형변환 시키는 형태
→ 자료형 b = (변화할 자료형) a;
(실수형에서 정수형으로 변환하는 경우 소수점 이하 자리는 버려짐)
public class Main01 {
public static void main(String[] args) {
double a = 3.14d;
int b = (int) a;
System.out.println(a);
System.out.println(b);
}
}
>> 실행 결과
3.14
3
함수 혹은 메서드는 이름이 그 자체로 주소 역할을 하기 때문에 같은 이름을 가진 다른 메서드가 존재할 수 없지만 오버라이드를 하는 경우 같은 이름의 다른 주소값을 가진 메서드가 재정의 되기 때문에 같은 이름의 다른 기능을 하는 메서드를 가질 수 있다
오버라이드를 할 수 있는 메서드 = 가상 메서
calcPrice는 이름이 같지만 재정의된 다름함수가 존재하고 그 주소값이 다르다. 이럴 때 실제적으로 호출되는 calPrice는 자료형(타입)기준이 아닌 생성된 인스턴스를 기준으로 호출이 되는 것을 가상 메서드 기법이라고 한다
정리해보면 Customer vd = new VIPCustomer(); 일 때 재정의가 안됬을 경우 Customer의 calPrice가 호출되지만 재정의가 됬을 경우 VIPCustoemr의 calPrice가 호출