[JAVA] 객체 지향 핵심 – 메서드 재정의하기(overriding) 와 가상 메서드 원리

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

Leave a Comment