오버라이딩
은 상위 클래스에 정의된 메서드 중, 하위 클래스와 기능이 맞지 않거나 추가 기능이 필요한 경우
같은 이름과 매개변수로 하위 클래스에서 재정의 하는 것입니다.
'오버로딩'과 '오버라이딩'의 차이는,
전자의 경우 하나의 클래스에 같은 이름의 여러 메서드를 매개변수를 달리하여 설정하는 것이고
후자의 경우 위에 설명한 것과 같이, 상위 클래스에 정의된 같은 이름의 메서드를 하위 클래스에서 재정의 하는 것입니다.
// Customer 에 정의된 메서드
public int calcPrice(int price) {
bonusPoint += price * saleRatio;
return price;
}
// VIPCutomer 에 재정의된 메서드(오버라이딩)
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price - (int)(price * saleRatio);
}
가상 함수
또는 가상 메서드
의 경우 타입(참조 자료형)과 상관없이 실제 생성된 인스턴스의 메서드가 호출됩니다.
하지만 참조 변수, 참조 메서드는 그 타입에 따라 이루어집니다.
// 가상 함수의 예시
Customer customerWho = new VIPCustomer(100010, "Who", 200);
int price = customerWho.calcPrice(10000);
System.out.println("지불금액은 " + price + "원 이고 " + customerWho.showCustomerInfo());
// 결과 : 지불금액은 9000원 이고 Who 님의 등급은 VIP이며, 보너스 포인트는 500점 입니다.
위 예시의 결과를 보면 분명 'customerWho'의 타입은 'Customer'이지만
생성된 인스턴스의 속성값(여기에서 VIP 등급)을 가지고 있고,
상위 클래스(Customer)에서 정의된 메서드와 같은 이름의 메서드(calcPrice)가
하위 클래스(VIPCustomer)에 재정의 되어 이 경우에 호출되는 것은 인스턴스의 것임을 알 수 있습니다.
반면 이 참조 변수를 통해 호출할 수 있는 데이터는 'Customer'의 것만 가능합니다.
다형성
이란 하나의 코드가 여러 자료형으로 구현되어 실행되는 것입니다.
객체지향 프로그래밍의 유연성, 재활용성, 유지보수성에 기본이 되는 가장 큰 특징 중의 하나입니다.
// 상위 클래스
class Animal {
public void move() {
System.out.println("동물이 움직입니다.");
}
}
// 하위 클래스
class Human extends Animal {
public void move() { // 각 클래스마다 같은 이름의 서로 다른 메서드를 재정의 함.
System.out.println("사람이 두 발로 걷습니다.");
}
}
class Tiger extends Animal {
public void move() {
System.out.println("호랑이가 네 발로 뜁니다.");
}
}
class Eagle extends Animal {
public void move() {
System.out.println("독수리가 하늘을 납니다.");
}
}
// main 메서드가 있는 클래스
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.moveAnimal(new Human());
test.moveAnimal(new Tiger());
test.moveAnimal(new Eagle());
// Animal animal = new Human();
}
// 인스턴스의 'move()' 메서드를 호출하는 메서드
// 매개변수로 인스턴스를 받는 것은 위의 주석과 동일한 방법입니다.
public void moveAnimal(Animal animal) { // 매개변수의 자료형이 상위 클래스
animal.move(); // 하위 클래스에서 재정의된 메서드들이 호출됨
}
}
이렇게 상위 클래스 타입으로 선언된 하나의 변수가 여러 객체에 대입되어
동일한 메서드를 호출하지만 다양한 구현이 실행될 수 있습니다.
이 부분에 '상속', '가상 함수', '오버라이딩'이 포함되어 있습니다.
상속
은 하나의 클래스에 공통적인 요소를 모으고 나머지 클래스는 이를 상속받아
각각 필요한 특성과 메서드를 구현하는 방법입니다. 👉 지난 글 [상속]
하나의 클래스에 여러 특성을 한 번에 구현하는 경우 많은 코드 내에 많은 if문이 생길 수 있습니다.
if (customerGrade == "VIP") {
// 할인 최고, 적립 최고
} else if (customerGrade == "GOLD") {
// 할인, 접립
} else if (customerGrade == "SILVER") {
// 할인 없음, 적립 조금
}
'상속'은 IS-A 관계 (is a relationship) : Inheritance
로
일반적인(general) 개념과 구체적인(specific) 개념과의 관계입니다.
상위 클래스는 일반적인 개념, 하위 클래스는 구체적인 개념이 됩니다.
반면 HAS-A 관계 (has a relationship) : Composition
는 '포함관계'이며
한 클래스가 다른 클래스를 소유한 관계입니다.