[Java/자바] Super와 Super()

super

super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조변수입니다.

멤버변수와 지역변수의 이름이 같을 때 this를 붙여 구별했듯이 상속받은 멤버와 자신의 멤버와 이름이 같을 때는 super를 붙여 구분할 수 있습니다.

 

super와 this 비교
class SuperTest {
	public static void main(String args[]) {
		Child c = new Child();
		c.method();
	}
}

class Parent {
	int x=10;
}

class Child extends Parent {
	int x = 20;
	
	void method() {
		System.out.println("x=" + x);
		System.out.println("this.x=" + this.x);
		System.out.println("super.x="+ super.x);
	}
}

출력 결과

위 코드를 보면 x = 10의 값을 갖는 Parent 클래스가 있고, Parent클래스를 상속받고 x 값을 20으로 초기화한 Child 클래스가 있습니다.

this로 x의 값을 호출시 Child클래스의 x 값을 출력하게 되며, super로 x의 값을 호출시 Parent 클래스의 x 값을 출력하게 됩니다. 

 

 

super를 이용한 오버라이딩
class Point {
	int x;
	int y;
	
	String getLocation() {
		return "x :" + x + ", y :" + y;
	}
}

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

super를 이용해 getLocation() 메서드를 불러와 Point3Dtest의 getLocation()을 오버라이딩하였습니다.

super.getLocation()은 조상 클래스인 Point 클래스의 getLocation()의 반환 값 : "x :" + x + ", y :" + y 을 가져오게 됩니다.

즉, return "x :" + x + ", y :" + y + ", z :" + z; 와 똑같은 결과입니다.


super()

this()는 같은 클래스의 다른 생성자를 호출하는데 사용되지만, super()는 조상 클래스의 생성자를 호출하는데 사용됩니다.

super() 또한 this()와 마찬가지로 반드시 생성자의 첫 줄에서 호출해야 합니다.

 

만약 자식 클래스에서 생성자를 생성했는데 생성자의 첫 줄에 super() 가 없다면, 컴파일러는 여기에 자동으로 super();를 삽입하게 됩니다.

 

자세한 내용은 아래 코드를 참고하며 이해해봅시다.

super()의 사용
class PointTest {
	public static void main(String args[]) {
		Point3D p3 = new Point3D(1,2,3);
		System.out.println("p3.x=" + p3.x);
		System.out.println("p3.y="+ p3.y);
		System.out.println("p3.z=" + p3.z);
	}
}

class Point {
	int x;	
	int y;

	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

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

class Point3D extends Point {
	int z;

	Point3D(int x, int y, int z) {
    
    		this.x = x;
                this.y = y;
                this.z = z;
	}

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

 

위 코드를 실행 하면 조상 클래스의 생성자인 Point()를 찾을 수 없다는 에러가 발생합니다.

그 이유는 Point3D클래스의 생성자의 첫 줄이 생성자를 호출하는 문장이 아니기 때문에 컴파일러는 자동적으로 super();를 Point3D(int x, int y, int z) 아래에 추가합니다.

	Point3D(int x, int y, int z) {
    		super(); // 자동으로 추가됨
    		this.x = x;
                this.y = y;
                this.z = z;
	}

 

이게 왜 문제가 되냐 ?

 

자동으로 추가된 super()는 부모 클래스 Point의 Point() 생성자를 호출하는데 Point 클래스에 Point() 생성자가 없기 때문입니다.

 

  • 그렇기 때문에 에러를 해결하기 위해선 2가지 방법이 있습니다.
  1. Point 클래스에 매개변수가 없는 생성자 Point()를 생성한다.
  2. Point3D(int x, int y, int z) 아래에 매개변수를 가진 super(x, y)를 추가해 Point(int x, int y) 생성자를 호출한다.

(변경하면 다음과 같습니다.)

	Point3D(int x, int y, int z) {
		super(x, y); // 조상클래스의 생성자 Point(int x, int y)를 호출.
		this.z = z;
	}

 

 


참고자료 : 자바의 정석3