느리더라도 꾸준히

[Java기본]가상 함수(메서드)란? 본문

Java

[Java기본]가상 함수(메서드)란?

테디규 2022. 11. 15. 22:06

목표

문제

일반적으로 상위 클래스 타입에 하위 클래스의 인스턴스타입이 할당되면 하위 클래스에만 존재하는 메서드들은 사용할 수가 없다.

그런데 다형성(참조변환)으로 인해 상위 클래스 타입에 하위클래스의 인스턴스가 들어있고 같은 이름의 메서드가 존재할때는, 오버라이딩 된 메서드가 호출이 된다.

어떻게 이런 구조가 가능한 것일까? 가상메서드를 이해하며 오버라이딩에 대해 더 알아보자.

정리

가상함수란

Java에서 상속하는 클래스 내에서 같은 시그니처(메서드명, 매개변수, 리턴형)의 함수로 오버라이딩 될 수 있는 함수 또는 메소드를 말한다.

어떻게 오버라이딩을 동작 시키는 것일까?

일반적으로 static이 아닌 메서드는 객체가 생성될 때 메서드 영역에 생성된다. 그리고 가상 함수는 가상함수 테이블(virtual function table) 이라는 구조로 함수의 주소를 저장하고 있다.

객체가 생성 되는 시점은 Runtime 시점으로 인스턴스의 타입을 결정지을 수 있다. 이때 재정의 된 메서드가 있을 경우, JVM이 가상 함수 테이블에서 메서드 주소를 이용하여 상위 클래스의 메서드가 아닌 인스턴스의 타입인 하위 클래스의 메서스(재정의 된 메서드)를 가져온다.

본문

Java 에서는 상위클래스와 하위클래스의 메서드 이름이 같을 때 오버라이딩 기능을 제공합니다. 아래 예시를 통해 확인해 봅시다.

상위클래스 Customer

class Customer {
    void calPrice(){
        System.out.println("상위클래스에서 계산한 가격입니다.");
    }

    void showCustomerInfo(){
        System.out.println("상위클래스에서 실행된 고객 정보 입니다.");
    }
}

하위 클래스 VipCustomer

public class VipCustomer extends Customer {
    private String VipId = "1324";
    void calPrice(){
        System.out.println("하위클래스에서 계산한 가격입니다.");
    }

    String getVipId(){
        return VipId;
    }
}

실행 파일

public class Main {
    public static void main(String[] args) {
        Customer customer = new VipCustomer();
        customer.calPrice();
        customer.showCustomerInfo();
//        customer.getVipid(); // 컴파일 에러
    }
}
/* 출력 결과
하위클래스에서 계산한 가격입니다.
상위클래스에서 실행된 고객 정보 입니다.
*/

하위 클래스의 인스턴스를 가진 상위 클래스 타입의 참조변수는 하위 클래스의 메서드(getVipid())를 사용하지 못한다.

하지만 같은 이름으로 하위클래스에서 재정의된(오버라이딩 된) calPrice() 는 하위 클래스 인스턴스 객체 타입에 존재하는 메서드를 호출한다.

객체지향 프로그래밍에서는 위에서 말한 오버라이딩 활용하여 하나의 클래스를 여러 클래스가 상속을 받았을 경우, 각각의 상속된 하위클래스의 인스턴스의 함수가 호출되도록 하여 다형성(polymorphism)을 구현할 수 있다.

그런데 어떻게 이런 일이 가능한 것일까?

가상 함수

정의

객체 지향 프로그래밍에서 가상 함수(virtual function 또는 virtual method)는 상속하는 클래스 내에서 같은 시그니처(메서드명, 매개변수, 리턴형)의 함수로 오버라이딩 될 수 있는 함수 또는 메소드를 말한다.

그리고 Java에서는 항상 상속 관계에서는 가상 함수가 생성되고 동작하도록 규정하고 있다.

어떻게 동작할까?

일반적으로 static이 아닌 메서드는 객체가 생성될 때 메서드 영역에 생성된다. 가상 함수는 가상함수 테이블(virtual function table) 이라는 구조로 함수의 주소를 저장하고 있다.

객체가 생성 되는 시점은 Runtime 시점으로 인스턴스의 타입을 결정지을 수 있다. 이때 재정의 된 메서드가 있을 경우, JVM이 가상 함수 테이블에서 메서드 주소를 이용하여 상위 클래스의 메서드가 아닌 인스턴스의 타입인 하위 클래스의 메서스(재정의 된 메서드)를 가져온다.

관련 자료 & 참고

정적바인딩과 동적바인딩

https://42place.innovationacademy.kr/archives/8728

Comments