https://changel.tistory.com/164
지난편에 이어 상속의 메서드 오버라이딩 개념에 대해 정리해보고자한다.
상위 클래스에 정의한 메서드가 하위 클래스에서 구현할 내용과 맞지 않는 경우 하위 클래스에서 이 메서드를 재정의 할 수 있다.
이를 메서드 오버라이딩이라고 한다.
걍 쉽게 말해서 상속 받은 상위 클래서의 메서드가 내가 구현할 클래스에서 필요 없거나 고쳐야돼서 재정의 하는 것을 말한다.
오버라이딩을 하려면 조건이 필요하다.
반환형, 메서드 이름, 매개변수의 개수 그리고 매개변수의 자료형이 반드시 같아야한다.
그렇지 않는다면 컴파일러는 재정의한 메서드를 기존의 메서드와 다른 메서드로 인식한다.
메서드 오버라이딩 방법
@override // <- 애노테이션이라고 함. 이 메서드는 재정의된 메서드라는 것을 컴파일러에게 명확하게 알려주는 역할을 한다.
+메서드 이름
// 이클립스같은 경우 기능을 활용할 수 있다. 마우스 오른쪽 버튼 클릭 > 소스에서 오버라이드를 택하면 기능을 사용할 수 있다.
여기서 애노테이션에대해 짚고 넘어가자. 애노테이션(Annotation)은 '주석'이라는 의미이다. 자바에서 제공하는 애노테이션은 컴파일러에게 특정한 정보를 제공해주는 역할을 한다. 예를들어 @overrride는 컴파일러에게 이 메서드가 재정의된 메서드임을 알려준다. 만약 메서드의 선언부가 다르다면 오류가 발생하게 된다 > 프로그래머의 실수를 줄여줌.
이렇게 미리 정의되어 있는 애노테이션을 표준 애노테이션이라고 한다. + 이에대해서는 구글링을 해보자.
묵시적 클래스 형 변환과 메서드 재정의
묵시적 형 변환을 통해 하위 클래스를 상위 클래스형으로 형 변환하고, 여기서 메서드가 하위 클래스에서 오버라이딩 되었다고 가정하자. (즉, 메서드가 상위/하위 클래스 둘 다 존재) 호출해보면 의아하게도 선언한 클래스 형인 사우이 클래스의 메서드가 아닌, 재정의 된 메서드를 가진 하위 클래스 형이 호출됨을 확인할 수 있다.
상속에서 상위 클래스와 하위 클래스에 같은 이름의 메서드가 존재할 때 호출되는 메서드는 인스턴스에 따라 결정된다.
즉, 선언한 클래스형이 라닌 생성된 인스턴스의 메서드를 호출하는 것이다. 그래서 하위 클래스에서 재정의된 메서드가 호출되는 것이다.
이렇듯 인스턴스 메서드가 호출되는 기술을 '가상메서드'라고 한다. 가상 메서드가 실행되는 원리를 제대로 이해하면 왜 위 경우에 상위 클래스의 메서드가 아닌 인스턴스의 메서드를 호출하는 것인지 알 수 있다.
가상 메서드
자바의 클래스는 멤버 변수와 메서드로 이루어져 있다. 클래스를 생성하여 인스턴스를 만들게 되면 힙 메모리에 멤버 변수가 위치하게 된다.
그렇다면 메서드는 어디에 위치하는가? -> 변수가 사용하는 메모리와 메서드가 사용하는 메모리는 다르다.
변수는 인스턴스가 생성될 때마다 새로 생성되지만 메서드는 실행해야하는 명령 집함이기에 인스턴스가 달라도 같은 로직을 수행한다.
즉, 같은 객체의 인스턴스를 여러 개 생성하더라고 메서드가 여러 개 생성되지 않는다는 의미이다.
메인함수가 실행되면 지역변수는 스택 메모리에 위차한다. 그리고 참조 변수를 가리키는 인스턴스가 힙 메모리에 생성된다. 메서드 명령 집함은 메서드 영역(코드 영역)에 위치한다. 메서드를 호출하여 실행하면 메서드 영역의 주소를 참조하여 명령이 실행된다.
가상 메서드의 원리
프로그램에서 메서드를 호출한다는 것은 그 메서드의 명령 집합이 있는 메모리 위치를 참조하여 명령을 실행하는 것이다. 그런데 가상 메서드의 경우 '가상 메서드 테이블'이 만들어진다. 가상 메서드 테이블은 각 메서드의 이름과 실제 메모리 주소가 짝을 이루고 있는 테이블이다.
가상 메서드 테이블에서 재정의된 메서드와 메서드 주소는 각각 어떻게 매칭될까?
상위 클래스와 하위 클래스의 같은 이름을 가진 메서드인 A 가 있다고 하자. 그리고 이 메서드는 하위 클래스에서 재정의 되었다.
가상 메서드 테이블에서 주소가 어떻게 매칭되었는지 보면, 이 둘은 서로 다른 주소를 가리킨다는 것을 알 수 있다.
또, 재정의 되지 않은 같은 메서드는 같은 주소를 가리키며 상위 클래스에는 존재하지 않는 하위 클래스에서 추가된 메서드는 아예 새로운 다른 주소를 가리킨다. (당연함 ㅇㅇㅇ)
총정리
상위 클래스에서 선언한 메서드를 하위 클래서에서 재정의한 상태에서 하위 클래스의 인스턴스가 상위 클래스로 형 변환을 하고, 이 메서드를 호출하면 이 변수를 선언할 때 사용한 상위 클래스의 메서드가 호출되는 것이 아니라 생성된 인스턴스의 메서드가 호출되고, 이것을 가상 메서드라고 한다!!!!
자바의 모든 메서드는 가상 메서드이다.
'공부 STUDY > JAVA' 카테고리의 다른 글
[JAVA] ArrayList 사용법 (0) | 2023.01.09 |
---|---|
[JAVA] 상속 | 다형성(Polymorphism) (0) | 2023.01.08 |
[JAVA] 상속 | 부모를 부르는 예약어, super (0) | 2023.01.08 |
[Java] 상속 inheritance, 클래스 생성과 형변환 | 예제를 통해 이해하기 (0) | 2023.01.08 |
[JAVA] 싱글톤 패턴(Singleton Pattern) - static 응용 (0) | 2023.01.07 |