– 메서드 재정의하기 (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를 가지고 있음
- 재정의된 경우는 재정의 된 메서드의 주소를 가리킴