자바[JAVA] : super 키워드

2021. 1. 28. 02:46Java

반응형

● super 키워드

super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다. 멤버변수와 지역변수의 이름이 같을 때 this를 붙여서 구별했듯이 상속받은 멤버와 자신의 멤버와 이름이 같을 때는 super를 붙여서 구별할 수 있다.

조상 클래스로부터 상속받은 멤버도 자손클래스 자신의 멤버이므로 super대신 this를 사용할 수 있다. 그래도 조상 클래스의 멤버와 자손클래스의 멤버가 중복 정의되어 서로 구별해야하는 경우에만 super를 사용하는 것이 좋다.

조상의 멤버와 자신의 멤버를 구별하는데 사용된다는 점을 제외하고는 super와 this는 근본적으로 같다. 모든 인스턴스메서드에는 자신이 속한 인스턴스의 주소가 지역변수로 저장되는데, 이것이 참조변수인 this와 super의 값이 된다.

static메서드(클래스메서드)는 인스턴스와 관련이 없다. 그래서 this와 마찬가지로 super역시 static메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.

위 사진을 보면, 같은 이름의 멤버변수(--> x)가 조상 클래스인 parent에도 있고 자손 클래스인 Child클래스에도 있을 때는 super.x와 this.x는 서로 다른 값을 참조하게 된다. super.x는 조상 클래스로부터 상속받은 멤버변수 x를 뜻하며, this.x는 자손 클래스에 선언된 멤버변수를 뜻한다.

변수만이 아니라 메서드 역시 super를 써서 호출할 수 있다. 특히 조상 클래스의 메서드를 자손 클래스에서 오버라이딩한 경우에 super를 사용한다.

class Point {
    int x;
    int y;

    String getLocation() {
        return "x : " + x + ", y : " + y;
    }
}

class Point3D extends Point {
    int z;

    String getLocation() {  //오버라이딩
        return super.getLocation() + ", z : " + z; //조상의 메서드 호출.
    }
}

이처럼 조상클래스의 메서드가 변경되더라도 변경된 내용이 자솥클래스의 메서드에 자동적으로 반영시키길 원한다면 super를 사용해서 조상클래스의 메서드를 포함시키는 것이 좋다.

 super() - 조상 클래스의 생성자 

this()와 마찬가지로 super() 역시 생성자이다. this()는 같은 클래스의 다른 생성자를 호출하는 데 사용되지만, super()는 조상 클래스의 생성자를 호출하는데 사용된다.

자손 클래스의 인스턴스를 생성하면, 자손의 멤버와 조상의 멤버가 모두 합쳐진 하나의 인스턴스가 생성된다. 그래서 자손 클래스의 인스턴스가 조상 클래스의 멤버들을 사용할 수 있는 것이다. 이 때 조상 클래스 멤버의 초기화 작업이 수행되어야 하기 때문에 자손 클래스의 생성자에서 조상 클래스의 생성자가 호출 되어야한다.

생성자의 첫 줄에서 조상클래스의 생성자를 호출해야하는 이유는 자손 클래스의 멤버가 조상 클래스의 멤버를 사용할 수도 있으므로 조상의 멤버들이 먼저 초기화되어 있어야 하기 때문이다.

이와같은 조상 클래스 생성자의 호출은 클래스의 상속관계를 거슬러 올라가면서 계속 반복된다. 마지막으로 모든 클래스의 최고 조상인 Object클래스의 (링크)의 생성자인 Object()까지 가서야 끝이난다. 그래서 Object클래스를 제외한 모든 클래스의 생성자는 첫 줄에 반드시 자신의 다른 생성자 또는 조상의 생성자를 호출해야한다. 그렇지 않으면 컴파일러는 생성자의 첫줄에 'super();'를 자동적으로 추가할 것이다.

인스턴스 초기화의 순서 코드.

조상 클래스의 멤버 변수는 이처럼 조상의 생성자에 의해 초기화 되도록 해야하는 것이다.

'Point3D p3 = new Point3D();'와 같이 인스턴스를 생성하면, 아래와 같은 순서로 생성자가 호출된다.

Point3D() -> Point3D(int x, int y, int z) -> Point(int x, int y) -> Object()

단, 생성자가 정의되어 있는 클래스에는 컴파일러가 기본 생성자를 자동적으로 추가하지 않는다.

출처 : 자바의 정석

반응형