회고록 블로그
[공부 필기] Java 기본 공부하기 (16) 본문
공부 중인 강의 : 윤성우 선생님, 윤성우의 열혈 Java 프로그래밍 강의.
링크 : https://cafe.naver.com/cstudyjava
1. 메소드 오버라이딩 (이어서)
1) 오버라이딩 이해부터 하기
- 부모 클래스와 자식 클래스에 동일한 반환형+동일한 이름+동일한 파라미터인 메소드가 있다면?
→ 부모 객체의 메소드는 가려짐
→ 이렇게 자식 객체의 메소드가 부모 객체의 메소드를 가려버리는 것을 '오버라이딩'이라고 함
public class Coffee {
...
void printRecipe() {
System.out.println("샷 :"+shotCount+"만큼 첨가");
}
...
public class CaramelMacchiato extends Coffee {
...
void printRecipe() {
System.out.println("우유 : "+milk+"만큼 첨가");
System.out.println("카라멜시럽 : "+syrupCount+"만큼 첨가");
}
...
→ CaramelMacchiato의 printRecipe 메소드가 Coffee의 printRecipe 메소드를 오버라이딩 한 것
→ 두 인스턴스는 '오버라이딩 관계'라고 볼 수 있음
2) 그림1과 같은 상황이 나오는 이유
public class MainMethod {
public static void main(String args[]) {
Coffee order1 = new CaramelMacchiato(1, "오곡", 2);
CaramelMacchiato order2 = new CaramelMacchiato(2, "무지방", 2);
order1.printRecipe();
System.out.println("------------------------------");
order2.printRecipe();
}
}
- order1은 참조타입이 Coffee(부모)이지만, 가리키는 대상은 CaramelMacchiato(자식)
- order2는 참조타입도, 실제 가리키는 대상도 모두 CaramelMacchiato(자식)
- 일반적으로 아래의 코드는 "부모 객체의 printRecipe 메소드가 출력"되어야 하지만, 자식 객체의 메소드가 출력되어버림
order1.printRecipe();
// 보통은 부모 객체(Coffee)의 printRecipe 메소드가 출력되어야 함
// 하지만, 출력되는 결과는 자식 객체(CaramelMacchiato)의 printRecipe 메소드임
→ 그 이유는 자식 인스턴스의 printRecipe 메소드가 부모 인스턴스의 printRecipe 메소드를 가려버려서(= 오버라이딩)
자식 인스턴스의 printRecipe 메소드가 대신 호출됐기 때문
→ 이 경우가 바로 '메소드 오버라이딩'임
3) 주의사항
- 참조타입도 Coffee, 실제 가리키고 있는 인스턴스도 Coffee인 경우는 메소드 오버라이딩이 아님
→ 이 경우는 애초에 자식 객체(CaramelMacchiato)가 메모리에 올라가지도 않았음
Coffee order3 = new Coffee(2);
- 예전에 사용했던 StringBuilder 클래스에도 toString 메소드가 존재했는데 사실 이것도 '메소드 오버라이딩'이라고 볼 수 있을 듯
→ StringBuilder의 toString 메소드가 Object 클래스에 toString 메소드를 가려버린 경우
- 인스턴스 변수는 오버라이딩이 되지 않음
→ 부모 클래스와 자식 클래스에 같은 이름의 변수가 있다고 해도 오버라이딩 되지 않음
→ 인스턴스 메소드만 오버라이딩이 가능함
→ 그리고, 부모 클래스와 자식 클래스에 "동일한 이름의 변수"를 선언하는게 좋은 코드는 아님
4) 부모 클래스의 메소드를 호출하려면?
- 자식 클래스의 내부에서 super 키워드를 이용해서 멤버 메소드에 접근하면 됨
- 하지만, 외부에서 부모 클래스의 메소드에 접근할 수는 없음(오버라이딩 되었기 때문)
2. instanceof 연산자
- instanceof 연산자의 반환값은 true/false
- "참조변수"가 "클래스이름"의 인스턴스를 참조하면 true를 반환하고,
"참조변수"가 "클래스이름"을 상속하는 클래스의 인스턴스이면 true를 반환
- instanceof 연산자의 오른쪽에는 참조타입이나 패턴이 올 수 있음
- 이해를 위한 예시
→ 아래와 같이 상황을 가정
→ 메인 메소드에는 이러한 코드가 존재한다고 가정
public class MainMethod {
public static void main(String args[]) {
Product fridge = new Refrigerator();
if(fridge instanceof Refrigerator) {
System.out.println("true");
}
}
}
→ 실행 결과는 "true"가 됨
→ 여기에서 instanceof 연산자는 "fridge 참조변수가 참조타입으로 Refrigerator를 가질 수 있는지"를 묻는 것임
→ fridge가 가리키는 인스턴스가 Refrigerator이기 때문에 참조타입으로 모두(Product, HomeAppliance, Refrigerator) 올 수 있음
- 사실 instanceof 연산자를 많이 사용하지는 않는다고 함
# 번외
public class MainMethod {
public static void main(String args[]) {
HomeAppliance fridge = new Refrigerator();
if(fridge instanceof Refrigerator) {
System.out.println("Refrigerator true");
}
if(fridge instanceof HomeAppliance) {
System.out.println("HomeAppliance true");
}
if(fridge instanceof Product) {
System.out.println("Product true");
}
}
}
- 위의 코드의 결과는? 모두 true
→ 참조변수 fridge가 가리키는 인스턴스가 Refrigerator 이기 때문
public class MainMethod {
public static void main(String args[]) {
Product fridge = new HomeAppliance();
if(fridge instanceof Refrigerator) {
System.out.println("Refrigerator true");
}
if(fridge instanceof HomeAppliance) {
System.out.println("HomeAppliance true");
}
if(fridge instanceof Product) {
System.out.println("Product true");
}
}
}
- 위의 코드의 결과는? 두번째 if문과 세번째 if문만 true
→ 참조변수 fridge가 가리키는 인스턴스가 HomeAppliance 이기 때문에 fridge의 참조타입은 Product이거나 HomeAppliance 밖에 안됨
'2. 프로그래밍 언어 공부 > Java' 카테고리의 다른 글
[공부 필기] Java 기본 공부하기 (18) (0) | 2021.11.17 |
---|---|
[공부 필기] Java 기본 공부하기 (17) (0) | 2021.11.16 |
[공부 필기] Java 기본 공부하기 (15) (0) | 2021.11.10 |
[공부 필기] Java 기본 공부하기 (14) (0) | 2021.11.09 |
[공부 필기] Java 기본 공부하기 (13) (0) | 2021.11.08 |