인프런 커뮤니티 질문&답변

인프린님의 프로필 이미지

작성한 질문수

김영한의 실전 자바 - 기본편

다형성과 메서드 오버라이딩

오버라이딩 질문

작성

·

248

0

안녕하세요.

아래 작성해주신 메서드 오버라이딩 관련한 설명 확인했습니다. 한 가지 궁금한 건 답변에서처럼 실제 런타임시에는 변수의 타입이 아닌 인스턴스의 타입을 우선적으로 본다고 한다면, method 오버라이딩은 자식 타입의 method(오버라이딩된)을 보는 게 맞는데 필드값은요 ?

 

위에 작성해주신 내용이 필드에는 해당이 안 되고 메서드에만 해당이 되는 내용인가요 ?

답변 2

3

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 인프린님

 

메서드 호출

메서드는 동적 바인딩(dynamic binding)을 따릅니다. 이는 런타임에 결정됩니다. 즉, 객체의 실제 타입에 따라 메서드가 호출됩니다. 이는 다형성(polymorphism)을 구현하는 핵심 메커니즘입니다.

예를 들어, 다음 코드를 봅시다:

class Parent {
    void printName() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    @Override
    void printName() {
        System.out.println("Child");
    }
}

public class Test {
    public static void main(String[] args) {
        Parent obj = new Child();
        obj.printName();  // "Child" 출력
    }
}

여기서 obj.printName()Parent 타입으로 선언된 obj 변수에 대해 호출됩니다. 하지만 obj의 실제 인스턴스 타입은 Child이므로, Child 클래스의 printName 메서드가 호출됩니다. 이것이 동적 바인딩의 예입니다.

 

이유

왜 필드와 메서드가 이렇게 다르게 동작할까요? 이는 주로 자바의 설계 철학과 성능 최적화 때문입니다. 메서드의 경우, 동적 바인딩을 통해 다형성을 제공하여 객체 지향 프로그래밍의 강력한 기능을 제공합니다. 반면 필드의 경우, 정적 바인딩을 통해 성능 최적화를 도모합니다.

  • 필드: 컴파일 타임에 결정되므로 더 빠른 접근이 가능합니다.

  • 메서드: 런타임에 결정되므로 다형성을 지원하고, 객체 지향 설계의 유연성을 제공합니다.

결론적으로, 자바에서 필드 접근은 변수의 선언된 타입에 따라 정적 바인딩을 따르지만, 메서드 호출은 객체의 실제 타입에 따라 동적 바인딩을 따릅니다. 이 차이점은 자바의 성능 최적화 및 객체 지향 프로그래밍 기능을 모두 제공하기 위한 설계 선택입니다.

참고로 필드도 동적 바인딩을 지원하는 언어들도 있습니다.

자바의 동적 바인딩, 즉 메서드 오버라이딩을 왜 사용하는지는 강의를 끝까지 들어보시면 이해가 되실거에요 🙂

감사합니다.

0

질문이해를 잘 못하겠는데 이 설명이 맞을까ㅛ?

class Parent {
    String name = "Parent";
}

class Child extends Parent {
    String name = "Child";
}

public class Test {
    public static void main(String[] args) {
        Parent obj = new Child();
        System.out.println(obj.name);  
    }
}

메서드오버라이딩은 자식타입의 함수를 먼저 보는게 맞지만 데이터타입은 부모타입으로 필드명을 호출하면 부모클래스의 필드가 호출이됩니다

인프린님의 프로필 이미지
인프린
질문자

네, 저게 저렇게 된다는 아는데 설명한 내용이 좀 앞뒤가 안 맞는 거 같아서요.

위의 코드에서 obj 변수는 Parent 타입이기 때문에 실제 메모리에 올라간 객체에서도 Parent 클래스의 내용을 먼저 확인한다. 그래서 name 필드도 Parent 클래스에 있는 name을 본다.

이 논리대로라면 method에서도 같은 논리가 적용되어야 하는데 method는 오버라이딩이 되면 자식 클래스의 오버라이딩된 메서드를 호출하는 부분에서 아래 어떤 분이 실제 변수를 getClass()로 확인해보면 생성한 객체의 타입으로 클래스가 나오므로 자식 클래스의 메서드가 호출이 된다고 테스트코드를 보여주셔서요.

그렇다면 필드도 같은 논리가 적용이 되어야 하는데 필드에 적용되는 것과 메서드에 적용되는 논리가 각각 달라서 여쭙습니다.

 

단순하게는 부모 클래스에서 자식 클래스를 확인할 방법이 없는데 어떻게 자식 클래스의 메서드를 확인할 수 있는지가 궁금합니다.

저도 햇갈려서 구글링하고 전공책도 찾아봤는데 "메서드는 런타임 시점에 실제 객체의 타입을 기준으로 동적 바인딩을 통해 호출되고, 필드는 컴파일 시점에 레퍼런스 타입을 기준으로 정적 바인딩을 통해 접근된다."라고 나와있더라구요 그냥 이렇게 외워야할것같아요