Language/Java

[Java]super

Hoplin 2021. 12. 28. 18:52
반응형

super은 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수이다. this가 자신이 속한 인스턴스를 가리키는 것처럼 super는 자신의 부모 클래스에 대한 참조를 하는 변수이다. super또한 static으로 선언된 클래스 변수 / 메소드에 대해서는 사용할 수 없으며 인스턴스 변수 / 메소드에 대해서만 사용이 가능하다.

 

   
class Parent1{
    int x = 20;
    int y = 30;
}
class Child1 extends Parent1{
    int y = 10;
    void method(){
        System.out.println("x = " + x);
        System.out.println("this.x = " + this.x);
        System.out.println("super.x = " + super.x);

        System.out.println();
        System.out.println("y = " + y); // Child1.y
        System.out.println("this.y = " + this.y); // Child1.y
        System.out.println("super.y = " + super.y); // Parent1.y
    }
}

public class super1 {
    public static void main(String[] args){
        Child1 aa = new Child1();
        aa.method();
    }
}

위 코드를 보면 알겠지만 자식 클래스인 Child1과 상속받은 Parent1 클래스 모두 y라는 변수가저장되어있다. this를 통해 y에 접근하면 Child1에 대해서만 접근하는것을 알 수 있으며, super를 통해서만 부모 클래스의 y멤버에 접근할 수 있다. 반대로 x같은 경우 부모클래스에만 선언이 되어있는 상태이다. 이 경우, this혹은 super를 통해서 모두 부모클래스에 있는 멤버만 접근한다.

class Point3{
    int x;
    int y;
    Point3(int x, int y){
        this.x = x;
        this.y = y;
    }
    Point3(){
        this(10,10);
    }
    String getLocation2(){
        return "X : " + this.x + " Y : " + this.y;
    }
}

class Point3D1 extends Point3{
    int z;
    Point3D1(int x, int y, int z){
        super(x,y);
        this.z = z;
    }
    Point3D1(){
        super();
        this.z = 20;
    }
    String getLocation2(){
        return super.getLocation2() + " Z : " + this.z;
    }
}

public class super2 {
    public static void main(String[] args){
        Point3D1 td = new Point3D1();
        Point3D1 tdd = new Point3D1(10,20,30);

        System.out.println(td.getLocation2());
        System.out.println(tdd.getLocation2());
    }
}

그리고 위 코드와 같이 부모 클래스 메소드 내용에 추가적인 작업을 덧붙이는 경우에는(오버라이딩 시) 이처럼 super를  사용해 부모클래스 메소드 실행 후 자식클래스의 메소드를 실행시키는 것이다 좋다

 

super()는 this()와 동일하게 생성자이다. 다만 이 super()는 부모 클래스의 생성자이다. 자손 클래스 인스턴스 생성시 부모 클래스 멤버가 모두 합쳐진 인스턴스가 생성되게 된다. 이때 부모 클래스 멤버의 초기화 작업이 진행되어야 하므로 자손 클래스 인스턴스에서도 정상적으로 부모클래스의 메소드를 사용할 수 있는것이다. 그리고 당연히, 부모 클래스의 생성자도 자식 클래스 생성자 맨 첫줄에 선언을 해주어야 한다.

 

class Point3{
    int x;
    int y;
    Point3(int x, int y){
        this.x = x;
        this.y = y;
    }
    Point3(){
        this(10,10);
    }
    String getLocation2(){
        return "X : " + this.x + " Y : " + this.y;
    }
}

class Point3D1 extends Point3{
    int z;
    Point3D1(int x, int y, int z){
        super(x,y);
        this.z = z;
    }
    Point3D1(){
        super();
        this.z = 20;
    }
    String getLocation2(){
        return super.getLocation2() + " Z : " + this.z;
    }
}

public class super2 {
    public static void main(String[] args){
        Point3D1 td = new Point3D1();
        Point3D1 tdd = new Point3D1(10,20,30);

        System.out.println(td.getLocation2());
        System.out.println(tdd.getLocation2());
    }
}

중요한 것은 부모 클래스의 멤버변수는 물론 자식 클래스의 this를 통해 부모클래스 멤버에 접근하여 초기화를 시켜줄 수 있지만, 부모 클래스의 생성자에 의해 초기화 하도록 해야하는 것이 좋다.

반응형