[자바] super

Gammi·2022년 10월 25일
0

JAVA

목록 보기
17/35
post-thumbnail

⭐ 레퍼런스 super


  • 오버라이딩 시 슈퍼클래스의 멤버변수와 메서드는 은닉되어 보이지 않음

    => 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로 표시
}

서브클래스 메서드 내 동일한 이름의 변수 존재 시 탐색 과정
(메서드 내 접근할 변수 : 로컬변수, 서브클래스의 멤버변수, 슈퍼클래스의 멤버변수)

  1. 로컬변수
  2. 서브클래스 멤버변수
  3. 슈퍼클래스 멤버변수

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);
    // 슈퍼클래스에서 멤버변수 선언하지 않았을 경우 오류 발생
    // 로컬변수 -> 서브클래스 멤버변수 -> 슈퍼클래스 멤버변수 순서로
    // 차례대로 접근하면서 값이 존재하는지 확인함
  }
}





⭐ 생성자 super()


  • 슈퍼클래스 생성자 명시적 호출 시 사용

    -> 생성자 this()와 사용 방법 및 목적 동일

  • 반드시 생성자의 첫 문장에서 실행되어야 함

    => 생성자 super()와 생성자 this()는 동시 사용X


< 기본 문법 >

super([데이터...]);


✔ 생성자 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;
    // 서브클래스의 멤버변수는 서브클래스에서 초기화하기 위해서임
    // 중복 초기화 제거!!
  }
}
profile
개발자가 되었어요⭐️

0개의 댓글