– 메서드 재정의하기 (Overriding)
자바에서 메서드 재정의(Overriding)는 객체 지향 프로그래밍의 핵심 개념 중 하나로, 상속받은 메서드를 하위 클래스에서 새롭게 정의하는 것을 말합니다. 메서드 재정의를 통해 상위 클래스의 기능을 하위 클래스에 맞게 변경할 수 있습니다.
- 오버라이딩(overriding) : 상위 클래스에 정의된 메서드의 구현 내용이 하위 클래스에서 구현할 내용과 맞지 않는 경우
- VIPCustomer 클래스의 calcPrice()는 할인율이 적용되지 않음
- 재정의 하여 구현해야 함
– @overriding 어노테이션(annotation)
- 어노테이션은 원래 주석이라는 의미
- 컴파일러에게 특별한 정보를 제공해주는 역활
| 어노테이션 | 설명 |
| @Overriding | 재정의된 메서드라는 정보 제공 |
| @FuctionnalInterface | 함수형 인터페이스라는 정보 제공 |
| @Deprecated | 이후 버전에서 사용되지 않을 수 있는 변수, 메서드에 사용됨 |
| @SuperessWarning | 특정 경고가 나타나지 않도록 함 (예) @SuperessWarning(“deprecation”)는 @Deprecated 가 나타나지 않도록 함 |
public class Customer {
protected int customerId;
protected String customerName;
protected String customerGrade;
int bonusPoint;
double bonusRatio;
public Customer(){
customerGrade = "SILVER";
bonusRatio = 0.01;
}
public int calcPrice(int price){
bonusPoint += price * bonusRatio;
return price;
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerGrade() {
return customerGrade;
}
public void setCustomerGrade(String customerGrade) {
this.customerGrade = customerGrade;
}
public String showCustomerInfo(){
return customerName + "님의 등급은" + customerGrade + "이며, 보너스 포인트는"
+ bonusPoint + "입니다.";
}
}
public class VIPcustomer extends Customer {
protected int agentID;
double salesRatio;
public VIPcustomer(){
customerGrade = "VIP";
salesRatio = 0.1;
bonusRatio = 0.05;
System.out.println("VIPCustomer()");
}
@Override
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price - (int)(price * salesRatio);
}
public int getAgentID(){
return agentID;
}
@Override
public String showCustomerInfo() {
return super.showCustomerInfo() + "상담원 아이디는 " + agentID;
}
}
public class CustomerTest {
public static void main(String[] args) {
int price = 10000;
Customer customerLee = new Customer();
customerLee.setCustomerName("이순신");
customerLee.setCustomerId(10010);
customerLee.bonusPoint = 10000;
int cost = customerLee.calcPrice(price);
System.out.println(customerLee.showCustomerInfo() + "지불 금액은 " + cost + "입니다.");
VIPcustomer vipCustomerKim = new VIPcustomer();
vipCustomerKim.setCustomerName("김유신");
vipCustomerKim.setCustomerId(10020);
vipCustomerKim.bonusPoint = 10000;
cost = vipCustomerKim.calcPrice(price);
System.out.println(vipCustomerKim.showCustomerInfo() + "지불 금액은 " + cost + "입니다.");
Customer customerPark = new VIPcustomer();
customerPark.setCustomerName("Park");
cost = customerPark.calcPrice(price);
System.out.println(customerPark.showCustomerInfo() + "지불 금액은 " + cost + "입니다.");
}
}
– 가상메서드 원리
자바에서 가상 메서드(Virtual Method)는 런타임 다형성(Polymorphism)을 구현하는 중요한 개념입니다. 이는 객체 지향 프로그래밍의 핵심 원리 중 하나로, 상위 클래스의 메서드 호출이 런타임에 실제 객체의 타입에 따라 적절한 하위 클래스의 메서드가 호출되도록 하는 메커니즘입니다.
- 메서드(함수)의 이름은 주소값을 나타냄
- 메서드는 명령어의 set 이고 프로그램이 로드되면 메서드 영역(코드영역)에 명령어 set이 위치
- 해당 메서드가 호출 되면 명령어 set 이 있는 주소를 찾아 명령어가 실행됨
- 이때 메서드에서 사용하는 변수들은 스택 메모리에 위치 하게 됨
- 따라서 다른 인스턴스라도 같은 메서드의 코드는 같으므로 같은 메서드가 호출됨
- 인스턴스가 생성되면 변수는 힙 메모리에 따로 생성되지만, 메서드 명령어 set은 처음 한번만 로드 됨
- 가상 메서드 테이블(virtual method table)에서 해당 메서드에 대한 address를 가지고 있음
- 재정의된 경우는 재정의 된 메서드의 주소를 가리킴