package ex0224.superkeyword;
// 부모 클래스: Animal
class Animal {
int age = 5;
String bodyColor; // 기본값 null
public void sound() {
System.out.println("super sound call");
}
public void eat() {
System.out.println("super eat call");
}
}
// 자식 클래스: Cat
class Cat extends Animal {
int age = 2; // 부모 클래스와 동일한 변수 선언 (Shadowing)
int weight; // Cat 클래스만의 추가 필드
@Override
public void sound() {
System.out.println("야옹");
}
public void run() {
System.out.println("잘 달린다");
}
public void test() {
System.out.println("======= 필드 값 확인 =======");
System.out.println("age (Cat) : " + age);
System.out.println("this.age (Cat) : " + this.age);
System.out.println("super.age (Animal) : " + super.age);
System.out.println("---------------------------");
System.out.println("bodyColor (Animal) : " + bodyColor);
System.out.println("this.bodyColor (Animal) : " + this.bodyColor);
System.out.println("super.bodyColor (Animal) : " + super.bodyColor);
System.out.println("---------------------------");
System.out.println("weight (Cat) : " + weight);
System.out.println("this.weight (Cat) : " + this.weight);
// System.out.println(super.weight); // 부모 클래스에 존재하지 않음 (컴파일 오류)
System.out.println("======= 메서드 호출 =======");
System.out.println("[sound()]");
sound();
this.sound();
super.sound();
System.out.println("[eat()]");
eat();
this.eat();
super.eat();
System.out.println("[run()]");
run();
this.run();
// super.run(); // 부모 클래스에 없는 메서드 (컴파일 오류)
}
}
// 실행 클래스
public class SuperKeywordExam {
public static void main(String[] args) {
System.out.println("======= Cat 객체 생성 및 호출 =======");
Cat cat = new Cat();
System.out.println("cat.age : " + cat.age);
System.out.println("cat.bodyColor : " + cat.bodyColor);
System.out.println("cat.weight : " + cat.weight);
cat.sound();
cat.eat();
cat.run();
System.out.println("==============================");
System.out.println("======= 업캐스팅 후 호출 =======");
Animal animal = new Cat();
System.out.println("animal.age : " + animal.age);
System.out.println("animal.bodyColor : " + animal.bodyColor);
// System.out.println(animal.weight); // 부모 클래스에 없는 필드 (컴파일 오류)
animal.sound(); // Cat 클래스의 오버라이딩된 메서드 실행
animal.eat();
// animal.run(); // Animal 타입으로는 Cat의 메서드 호출 불가 (컴파일 오류)
System.out.println("animal 주소 = " + animal);
// 다운캐스팅: 부모 타입 → 자식 타입
if (animal instanceof Cat) { // 안전한 캐스팅 확인
Cat c = (Cat) animal;
System.out.println("c 주소 = " + c);
System.out.println("c.weight : " + c.weight);
c.run(); // Cat 클래스의 run() 호출 가능
}
}
}
가독성 개선
System.out.println()에 필드명과 클래스명을 명확히 표기.불필요한 코드 제거
super.weight는 부모 클래스에 없기 때문에 주석 처리.super.run()도 부모 클래스에 없어서 주석 처리.출력 가독성 향상
======= 구분선 =======을 추가하여 실행 흐름이 명확하게 보이도록 함.System.out.println("메서드 호출") 구분하여 출력.이제 코드가 깔끔하고 구조적으로 정리되어 가독성이 좋아졌어요! 🚀
super 키워드 정리Cat 클래스는 Animal 클래스를 상속받음 (extends Animal).Animal)의 속성과 메서드를 자식(Cat)이 물려받음.@Override) 할 수 있음.super 키워드 사용super 키워드는 부모 클래스(Animal)의 멤버(필드, 메서드)를 참조할 때 사용.super.age → 부모 클래스의 age 값 참조 (5)this.age → 자식 클래스의 age 값 참조 (2)super.sound() → 부모 클래스의 sound() 실행 (super sound call)this.sound() 또는 sound() → 자식 클래스의 sound() 실행 (야옹)super로 접근할 수 없음.super.weight는 부모 클래스(Animal)에 존재하지 않으므로 접근 불가.super 키워드 사용 예제 (출력 정리)System.out.println(age); // 2 (자식 클래스 Cat의 age)
System.out.println(this.age); // 2 (this는 현재 객체의 age)
System.out.println(super.age);// 5 (부모 클래스 Animal의 age)
System.out.println(bodyColor); // null (부모로부터 상속됨)
System.out.println(this.bodyColor); // null
System.out.println(super.bodyColor);// null
System.out.println(weight); // 0 (자식 클래스 Cat의 필드)
System.out.println(this.weight); // 0
// System.out.println(super.weight); // 오류! 부모에는 weight 필드 없음
System.out.println("=======메서드 호출==========");
sound(); // "야옹" (자식 클래스의 메서드)
this.sound(); // "야옹"
super.sound(); // "super sound call" (부모 클래스의 메서드)
System.out.println("=======메서드 호출==========");
eat(); // "super eat call" (부모의 메서드를 오버라이딩하지 않음)
this.eat(); // "super eat call"
super.eat(); // "super eat call"
System.out.println("=======메서드 호출==========");
run(); // "잘달린다" (자식 클래스의 메서드)
this.run(); // "잘달린다"
// super.run(); // 오류! 부모 클래스에 run() 없음
Animal animal = new Cat(); → 업캐스팅 (Upcasting)Animal) 참조 변수로 자식 객체(Cat)를 가리킴.age = 5).sound()는 "야옹").run() 같은 자식 클래스 전용 메서드는 호출 불가.Animal animal = new Cat();
System.out.println(animal.age); // 5 (부모 클래스의 필드)
System.out.println(animal.bodyColor); // null (부모 클래스에서 상속된 필드)
animal.sound(); // "야옹" (오버라이딩된 메서드 실행)
animal.eat(); // "super eat call"
// animal.run(); // 오류! Animal 타입으로는 Cat의 메서드 호출 불가
Cat)으로 변환.if (animal instanceof Cat)으로 안전성 확인 후 변환.if(animal instanceof Cat) {
Cat c = (Cat) animal; // 다운캐스팅
System.out.println(c.weight); // 0 (자식 클래스의 필드 접근 가능)
c.run(); // "잘달린다" (자식 클래스의 메서드 호출 가능)
}
instanceof를 사용하지 않으면 ClassCastException 발생할 가능성이 있음.✅ super 키워드
super.age → 부모 클래스 age 값.super.sound() → 부모 클래스의 sound() 실행.✅ 메서드 오버라이딩
✅ 업캐스팅 (Upcasting)
Animal animal = new Cat();✅ 다운캐스팅 (Downcasting)
if (animal instanceof Cat) { Cat c = (Cat) animal; }💡 상속을 통해 코드의 재사용성을 높이고, super와 업캐스팅/다운캐스팅을 활용하여 객체지향적인 설계를 할 수 있음! 🚀