ksouth9

객체지향언어(11) - super 본문

Java

객체지향언어(11) - super

ksouth9 2022. 3. 8. 14:23

super


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

 

  • 상속받은 멤버와 자신의 멤버가 이름이 같을 때는 super를 붙여서 구별할 수 있다.
  • 모든 인스턴스메서드에는 자신이 속한 인스턴스의 주소가 지역변수로 저장되는데, 이것이 참조변수인 this와 super의 값이 된다.
  • super는 static메서드에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.
class Parent {
	int x = 10;
}

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

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

}//실행결과
x=10
this.x=10
super.x=10

x, this.x, super.x 모두 같은 변수를 의미하므로 모두 같은 값이 출력된다.

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);
	}
}

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

}//실행결과
x=20
this.x=20
super.x=10

super.x는 조상 클래스로부터 상속받은 멤버변수 x

this.x는 자손 클래스에 선언된 멤버변수

 

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


super()는 조상 클래스의 생성자를 호출하는데 사용된다.

 

사용방법

super();

 

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

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

 

Object클래스를 제외한 모든 클래스의 생성자 첫 줄에 생성자, this() 또는 super()를 호출해야 한다. 그렇지 않으면 컴파일러가 자동적으로 'super();'를 생성자의 첫 줄에 삽입한다.

 

인스턴스를 생성할 때는 클래스를 선택하는 것만큼 생성자를 선택하는 것도 중요하다.

 

1. 클래스

 - 어떤 클래스의 인스턴스를 생성할 것인가?

2. 생성자

 - 선택한 클래스의 어떤 생성자를 이용해서 인스턴스를 생성할 것인가?

 

class Point {
	int x;
	int y;
	
	Point (int x, int y){
		this.x = x;
		this.y = y;
	}
	//Point(){
	//	
	//}
	String getLocation() {
		return "x : "+x+"y : "+y;
	}
}
class Point3D extends Point{
	int z;
	
	Point3D(int x,int y,int z){
    	super(x,y);	//조상클래스의 생성자 Point(int x, int y)를 호출한다.
		this.x = x;
		this.y = y;
		this.z = z;
	}
	String getLocation() {	//오버라이딩
		return "x : "+x+" y : "+y+" z : "+z;
	}
}

public class PointTest {

	public static void main(String[] args) {
		Point3D p3 = new Point3D(1,2,3);
	}

}

Point클래스에 생성자 Point()가 정의되어 있지 않기 때문에 컴파일 에러가 발생한다. 이 에러를 수정하려면, Point클래스에 생성자 Point()를 추가하거나, 생성자 Point3D(int x,int y,int z)의 첫 줄에서 Point(int x,int y)를 호출하도록 변경하면된다.

 

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

 

조상 생성자는 자손 생성자의 맨 첫 줄에서 호출된다. 

 

조상 생성자가 명시적으로 호출되지 않으면 컴파일러는 자손 생성자의 첫 줄에 super()라는 메소드를 추가한다. 

super() 메소드는 부모의 기본 생성자를 호출한다. 

(기본생성자: 프로그래머가 정의한 생성자가 없는, 자동적으로 컴파일러에 의해 생성되는 생성자)

 

주의사항

 

조상 클래스에 기본 생성자가 없고, 매개 변수가 있는 생성자만 있다면 자손 생성자만 있다면 자손 생성자의 첫 줄에 반드시 조상 생성자 호출을 위해 super(매개값,...)를 명시적으로 호출해야 한다. 또는 조상클래스에 '조상생성자(){}'를 정의하고 자손클래스에서 'super()'를 호출해야 한다. 그렇지 않으면 컴파일 에러가 발생한다.