오버라이딩 시 슈퍼클래스의 멤버변수와 메서드는 은닉되어 보이지 않음
=> super
는 그런 슈퍼클래스의 멤버에 접근하기 위한 키워드
레퍼런스 this와 마찬가지로 서브클래스 인스턴스 생성 시 생성됨
자동으로 생성되는 슈퍼클래스의 인스턴스 주소 저장
주로 오버라이딩에 의해 은닉된 멤버변수 또는 메서드 접근 시 사용
< 기본 문법 >
super.부모의 멤버변수
super.부모의 메서드()
class Parent {
String tv = "부모님이 구입한 tv";
public void watchTV() {
System.out.println("부모님 집에서 " + tv + " 보기!");
}
}
class Child extends Parent {
String tv = "내가 구입한 tv";
public void watchTV() { // 오버라이딩
System.out.println("독립한 나의 집에서 " + tv + " 보기!");
// 슈퍼클래스의 메서드는 은닉되어 보이지 않음
}
public void watchParentTV() {
System.out.println("부모님 집 tv : " + super.tv);
// 슈퍼클래스의 멤버변수는 super를 통해서 표시함
System.out.println("우리집 tv : " + this.tv);
// 서브클래스의 멤버변수는 this로 표시
}
서브클래스 메서드 내 동일한 이름의 변수 존재 시 탐색 과정
(메서드 내 접근할 변수 : 로컬변수, 서브클래스의 멤버변수, 슈퍼클래스의 멤버변수)
- 로컬변수
- 서브클래스 멤버변수
- 슈퍼클래스 멤버변수
public static void main(String[] args) {
}
class Parent {
String x = "parent";
}
class Child extends Parent {
String x = "child"; // 멤버변수
public void method() {
String x = "method"; // 로컬변수
System.out.println("로컬변수 x : " + x);
// 로컬변수 선언 안 했으면 서브클래스 멤버변수 값 출력됨
System.out.println("서브클래스 멤버변수 x : " + this.x);
// 멤버변수 선언하지 않았을 경우(=오버라이딩 안했으면)
// 슈퍼클래스의 멤버변수 값이 출력됨
System.out.println("부모클래스 멤버변수 x : " + super.x);
// 슈퍼클래스에서 멤버변수 선언하지 않았을 경우 오류 발생
// 로컬변수 -> 서브클래스 멤버변수 -> 슈퍼클래스 멤버변수 순서로
// 차례대로 접근하면서 값이 존재하는지 확인함
}
}
슈퍼클래스 생성자 명시적 호출 시 사용
-> 생성자 this()와 사용 방법 및 목적 동일
반드시 생성자의 첫 문장에서 실행되어야 함
=> 생성자 super()와 생성자 this()는 동시 사용X
< 기본 문법 >
super([데이터...]);
목적 1) 슈퍼클래스 생성자 중 특정 생성자를 명식적으로 호출한 경우
class Person {
String name;
int age;
public Person() {
// 기본 생성자
}
public Person(String name, int age) {
// 파라미터 생성자
super(); // 슈퍼클래스의 부모클래스는 Object
this.name = name;
this.age = age;
}
}
class Student extends Person {
boolean isStudyMode;
public Student() {
super();
// 지금은 super() 생성자 사용 가능
// 근데 Person() 클래스에서 기본 생성자 정의 안했으면
// 컴파일 오류 나서 사용 못함
// 슈퍼클래스에서 기본생성자 정의 안했는데
// super() 생성자 쓰고 싶으면
super("홍길동", 20);
// 파라미터 생성자로 호출하면 사용 가능!
}
}
목적 2) 슈퍼클래스 생성자에 멤버변수 초기화 코드가 존재할 경우
서브클래스 생성자에서 슈퍼클래스의 멤버까지 초기화하게 되면 초기화 코드의 중복이 발생함
이 때, 슈퍼클래스의 멤버는 슈퍼클래스의 생성자에서, 서브클래스의 멤버는 서브클래스의 생성자에서 초기화해서 코드 중복을 제거함
class Person {
String name;
int age;
public Person() {}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
class Student extends Person {
boolean isStudyMode;
public Student() {
// name = "홍길동";
// age = 20;
// isStudyMode = true;
// 여기서 초기화를 진행하는 게 아니라
this("홍길동", 20, true);
// 해당 생성자 내에서 다시 생성자를 호출해서 초기화 코드의 중복을 제거함
// super(); // !!!!오류 발생!!!!
// super() 생성자는 가장 첫 줄에서 호출해야함
// this()로 서브클래스의 생성자 먼저 호출하고
// super() 생성자를 호출할 경우 오류 발생!!
}
public Student(String name, int age, boolean isStudyMode) {
super(name, age);
// super() 기본 생성자를 호출하지 않는 이유는
// 슈퍼클래스의 멤버변수는 슈퍼클래스에서 초기하고
this.isStudyMode = isStudyMode;
// 서브클래스의 멤버변수는 서브클래스에서 초기화하기 위해서임
// 중복 초기화 제거!!
}
}