728x90
1. 하위 클래스에서 메서드 재정의하기
- 오버라이딩(overriding): 상위 클래스에 정의된 메서드의 구현 내용이 하위 클래스에서 구현할 내용과 맞지 않는 경우 하위 클래스에서 동일한 이름의 메서드를 정의하여 사용하는 것.
- VIPCustomer 클래스의 calcPrice()는 할인율이 적용되지 않기 때문에 재정의하여 구현해야 함.
- VIPCustomer.java
@Override public int calcPrice(int price) { bonusPoint += price * bonusRatio; return price - (int)(price * salesRatio); } |
> 하위 클래스에서 calcPrice라는 메서드를 재정의한다. *가격에 대한 할인율이 들어간다.
> VIPCustomer.java 에서 화면에서 우클릭 > Source > Override/Implement method.. 선택 후 오버라이드 가능한 메서드를 선택한다.
2. overriding 어노테이션(annotation)
- 어노테이션은 원래 주석이라는 의미.
- 컴파일러에게 특별한 정보를 제공해주는 역할
- @overriding 어노테이션은 재정의된 메서드라는 의미로 선언부가 기존의 메서드와 다른 경우 에러가 난다.
3. 형 변환과 오버라이딩 메서드 호출
- Customer vc = new VIPCustomer();
- vc 변수의 타입은 Customer이지만 인스턴스 타입은 VIPCustomer이다.
- 자바에서는 항상 인스턴스의 메서드가 호출되기 때문에 자바의 모든 메서드는 가상 메서드이다.
- CustomerTest.java
package ch04; public class CustomerTest { public static void main(String[] args) { int price = 0; Customer customerLee = new Customer(10010, "이순신"); customerLee.bonusPoint = 1000; price = customerLee.calcPrice(1000); System.out.println(customerLee.showCustomerInfo() + "\n 1000원짜리 제품의 가격은 " + price + "원 입니다"); System.out.println(); VIPCustomer customerKim = new VIPCustomer(10020, "김유신"); customerKim.bonusPoint = 10000; price = customerKim.calcPrice(1000); System.out.println(customerKim.showCustomerInfo() + "\n 1000원짜리 제품의 가격은 " + price + "원 입니다."); // 그렇다면 VIPCustomer로 생성했는데 Customer형으로 변환한 vc의 경우에는? Customer vc = new VIPCustomer(12345, "noname"); price = vc.calcPrice(1000); System.out.println(price); // 900이 출력됨. 이게 가상함수 방식이다. (이것이 가상 메서드..) // VIPCustomer의 실제 인스턴스의 메서드가 호출이 된다. } } |
출력값 ..
이순신님의 등급은 SILVER이며, 보너스 포인트는 1010입니다. 1000원짜리 제품의 가격은 1000원 입니다 김유신님의 등급은 VIP이며, 보너스 포인트는 10050입니다. 1000원짜리 제품의 가격은 900원 입니다. vc 값 출력 : 900 |
4. 메서드(함수)는 어떻게 호출되고 실행 되는가?
- 메서드(함수)의 이름은 주소값을 나타낸다.
- 메서드는 명령어의 set이고 프로그램이 로드되면 메서드 영역(코드 영역)에 명령어 set이 위치한다.
- 해당 메서드가 호출되면 명령어 set이 있는 주소를 찾아 명령어가 실행된다.
- 이때 메서드에서 사용하는 변수들은 스택 메모리에 위치하게 된다.
- 따라서 다른 인스턴스라도 같은 메서드의 코드는 같으므로 같은 메서드가 호출된다.
- 인스턴스가 생성되면 변수는 힙 메모리에 따로 생성되지만, 메서드 명령어 set은 처음 한번만 로드 된다.
public class TestMethod { int num; void aaa() { System.out.println("aaa() 호출"); } public static void main(String[] args) { TestMethod a1 = new TestMethod(); a1.aaa(); TestMethod a2 = new TestMethod(); a2.aaa(); } } |
- aaa라는 메서드는 출력문을 실행하는 것
- main 함수의 a1, a2, args는 지역변수이고
- 객체(인스턴스)가 생성된 a1, a2는 힙 메모리에 올라간다.
- aaa() 메서드에서 사용하는 지역변수는 다시 스택 메모리에 올라간다. (예제에선 지역변수가 없지만..)
5. 가상 메서드의 원리
- 가상 메서드 테이블에서 해당 메서드에 대한 주소를 가지고 있다.
- 재정의된 경우는 재정의된 메서드의 주소를 가리킨다.
- showCustomerInfo의 경우 재정의되지 않았기 때문에 동일한 메서드 주소 값을 갖고,
- override된 calcPrice 메서드의 경우에는 각각의 메서드 주소를 갖는다.
1. 상속
2. 형 변환 (상위 클래스로 형이 대입된다.)
3. 재정의(Override - 상위 클래스에 있는 메서드를 재정의해서 입맛 대로 바꿈)
4. 인스턴스에서 재정의된 메서드가 호출된다.
728x90
'개발공부 > Java' 카테고리의 다른 글
[Java] 17. 다형성(polymorphism) 예제 (0) | 2022.01.26 |
---|---|
[Java] 17. 다형성의 의미와 다형성을 사용하는 이유 (0) | 2022.01.26 |
[Java] 15. 상속에서 클래스 생성과 형 변환 (0) | 2022.01.24 |
[JVM GC] GC 종류와 동작 방식과 G1GC 튜닝 포인트 (0) | 2022.01.05 |
[JVM GC] Garbage Collector에 대하여 (0) | 2022.01.04 |