09009

[Java] 생성자, Super 주의할 점 본문

Back-End/JAVA
[Java] 생성자, Super 주의할 점
09009

하위 클래스에 의해 가려진 상위 클래스의 멤버 변수나 메소드에 접근할 때

  super.객체변수     

  super.메서드이름(매개변수)

상위 클래스의 생성자를 호출할 때

  super(매개변수)

 

!!!  super문장은 반드시 첫 번째 라인에 와야 한다 !!!

 

✍ Super1.java

package ch07;

class E1 {
	E1() {
		System.out.println("기본 생성자");
	}
	E1(int k) {
		System.out.println("매개변수가 1개인 생성자 : " + k);
	}
	void m1() {
		System.out.println("m1 메서드입니다");
	}
}

class E2 extends E1 {
	E2(int k) {
		System.out.println("안녕하세요");
	}
	void m2() {
		System.out.println("반가워요");
	}
}
public class Super1 {
	public static void main(String[] args) {
		E2 e = new E2(7);
		e.m1(); e.m2();
	}
}

💻 출력 결과

기본 생성자
안녕하세요
m1 메서드입니다
반가워요

!!! 주의할 점!!!

 기본 생성자는 생성자가 하나도 없으면 컴파일할 때 자동으로 만들어 준다. 다른 생성자가 하나라도 있으면 기본 생성자는 만들어지지 않는다.

• 위의 소스코드에서 E1 클래스의 기본생성자가 없고 매개변수를 받는 생성자 (E1(int k)) 만 있을 때와 동시에 E2 클래스의 매개변수 k가 있는 E2 생성자에 super(k);가 명시되어 있지 않으면 에러가 발생한다.

아래 스크린샷에 있는 소스코드를 보면 그 사실을 확인할 수 있다.

 

-----------------------------------------------------------------------------------------------------------------------------------------

에러 해결 방법

1)  E2 클래스에 super(k);를 작성 (E1 클래스에 기본생성자는 없고 매개변수를 받는 생성자만 있을 경우)

💻 출력 결과

매개변수가 1개인 생성자 : 7
안녕하세요
m1 메서드입니다
반가워요

 

2)  E1 클래스에 기본 생성자 만들기 (E2 클래스에 super(k);를 작성하지 않아도 에러가 발생하지 않는다.)

 

!!! 생성자는 자식 생성자를 호출하면 반드시 부모부터 호출된 후에 자식이 호출된다는 것을 잊지말자 !!!

그러므로 출력 결과에 "기본 생성자입니다"가 먼저 출력되는 것이다.

 

💻 출력 결과

기본 생성자입니다
안녕하세요
m1 메서드입니다
반가워요

수정한 코드

✍ Super1.java

package ch07;
class E1 {
	E1() {
		System.out.println("기본 생성자");
	}
	E1(int k) { 
		System.out.println("매개변수가 1개인 생성자 : " + k);
	}
	void m1() {
		System.out.println("m1 메서드입니다");
	}
}

class E2 extends E1 {
	E2 (int k) { 
		super(k); 
		System.out.println("안녕하세요");
	}
	void m2() {
		System.out.println("반가워요");
	}
}
public class Super1{
	public static void main(String[] args) {
		E2 e = new E2(7);
		e.m1(); e.m2();
	}
}

💻 출력 결과

매개변수가 1개인 생성자 : 7
안녕하세요
m1 메서드입니다
반가워요

 

 

 

 

다른 예제 소스코드

위의 소스코드를 그대로 컴파일하면 에러가 발생한다. Point3D 클래스의 생성자에서 조상 클래스의 생성자인 Point()를

찾을 수 없기 때문이다.

Point3D 클래스의 생성자의 첫 줄이 생성자를 호출하는 문장이 아니므로 컴파일러는 자동적으로 super();를 point3D 클래스의 생성자의 첫 줄에 넣어준다. (super()도 생성자이므로 자식의 생성자가 호출될 시, 부모의 생성자부터 먼저 호출되어야 하기 때문에)

그래서 Point3D 클래스의 인스턴스를 생성하면, 생성자 Point3D(int x, int y, int z)가 호출되어 첫 문장인 super();를 수행한다. 

super() = Point 클래스 [Point3D 클래스의 조상]의 기본 생성자인 Point() 

그러나, Point 클래스에서 기본 생성자 Point()가 정의되어 있지 않았기 때문에 에러가 발생한다.

위 에러를 수정하기 위해서는 Point 클래스에 기본 생성자 Point()를 추가하던지 아니면 생성자 Point3D(int x, int y, int z)의 첫 줄에서 Point(int x, int y)를 호출하도록 변경해야 한다.

 

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

 


에러 해결 방법

수정한 코드

1) Point 클래스에 기본 생성자 Point()를 추가

2) 생성자 Point3D(int x, int y, int z)의 첫 줄에서 Point(int x, int y)를 호출