Programing Language/Java

[Java] 부모 클래스 생성자 호출(Inheriting Constructor)

vinedpillar 2022. 9. 5. 21:52

부모 클래스 생성자의 호출

  • 모든 클래스는 컨스트럭터를 통해서 인스턴스를 생성해야만 활용할 수 있습니다.

  • 상속을 통해 자식 클래스에서 부모 클래스의 특성이나 기능을 사용할 수 있는 것은 자식 클래스의 인스턴스를 생성할 때 부모 클래스의 컨스트럭터도 같이 호출되기 때문입니다.

  • 하지만 컨스트럭터 자동 생성 규칙에 맞지 않는다면 프로그래머가 직접 이를 설정해주어야 합니다.
  • 이 때 super 예약어가 사용됩니다.

 

 

 

 

super 예약어

  • super는 부모(상위) 클래스를 지칭하는 예약어로 this와 유사한 용도로 사용됩니다.

  • super는 아래와 같이 두 가지 방법으로 활용할 수 있습니다.

  • suepr: 자식 클래스에서 부모 클래스의 필드나 메서드를 지칭하고자 경우
    • 원래 부모 클래스의 필드나 메서드는 모두 super.을 붙여야 하지만 프로그램 컴파일 시 컴파일러가 자동으로 추가해주기 때문에 생략이 가능합니다.
    • 다만 필요한 경우 this와 같이 이름이 같은 변수를 구분하기 위해 사용됩니다.
super의 활용 방법

// 필드 호출
super.필드변수

// 메서드 호출
super.메서드

 

super 사용 예시

// 동물 클래스 생성
public class Animal {
    int legs;
    int arms;
    
    public Animal() {
    
    }
    
    public void move() {
    	System.out.println("움직입니다.");
    }
}


// 고양이 클래스 생성
public class Cat extends Animal {
    int tails;
    
    public void grooming() {
    	// super를 이용해 부모 클래스의 메서드 실행 
        super.move();
        System.out.println("고양이가 털을 햝습니다.");
    }
}

 

  • super(): 부모 클래스의 컨스트럭터를 호출하는 경우
    • 부모 클래스가 매개변수가 없는 기본 컨스트럭터를 사용할 경우 별도의 선언 없이도 자식 클래스의 생성과 동시에 부모 클래스도 생성이 됩니다. 
    • 이는 프로그램이 컴파일될 때 컴파일러가 자식 클래스의 첫 줄에 super();를 자동으로 추가해주기 때문입니다.
      (컨스트럭터를 별도로 선언하지 않아도 컴파일러가 기본 컨스트럭터를 자동으로 생성해주는 것과 같음)
    • 반면 부모 클래스의 컨스트럭터가 별도의 매개변수를 가지는 컨스트럭터로 선언되었고 기본 컨스트럭터가 없을 경우라면, 프로그래머가 별도로 부모 클래스의 컨스트럭터를 선언해주어야 합니다.
    • 만약 부모 클래스의 컨스트럭터가 선언되지 않는다면 컴파일 에러가 발생합니다.
자식 클래스의 생성자 부분 

public 자식클래스이름() {
	// 기본 컨스트럭터일 경우 자동 생성
    super();
}

 

super() 사용 예시

// 동물 클래스 생성
public class Animal {
    int legs;
    int arms;
    
    // 매개변수가 있는 컨스트럭터
    public Animal(int legs, int arms) {
    	this.legs = legs;
        this.arms = arms;
    }
    
    public void move() {
    	System.out.println("움직입니다.");
    }
}


// 고양이 클래스 생성
public class Cat extends Animal {
    int tails;
    
    // 고양이 클래스의 컨스트럭러 선언
    public Cat(int legs, int arms, int tails) {
    	// super() 키워드를 통해 부모 클래스의 컨스트럭터 선언
        super(4, 0);
        // 추가로 필요한 매개변수 처리
        this.tails = tails;
    }
    
    public void grooming() {
        System.out.println("고양이가 털을 햝습니다.");
    }
}

 

 

 

 

Protected 접근제어자

  • protected는 상속과 관련이 있는 접근제어자로 같은 패키지이거나 자식 클래스일 때 접근을 허용해주는 기능을 가지고 있습니다.

  • protected로 설정이 된 멤버를 다른 패키지에서 사용하기 위해서는 해당 클래스를 상속을 해야만 합니다.

  • 위 경우, 부모 클래스의 컨스트럭터를 바로 사용할 수는 없고, super()를 활용하여 호출해야합니다.
    (new 연산자를 활용하여 직접 생성은 불가)
다른 패키지에서의 protected 접근 제어자 활용

// 부모 패키지 및 클래스 선언
package package1;

public class Parent {
    protected String parentField;
    
    protected Parent() {
    
    }
    
    protected void parentMethod() {
    
    }
}


// 부모 패키지와 다른 패키지
package package2;

// 부모 패키지 삽입
import package1.Parent;

public class Child extends Parent {
    public Child() {
    	// 부모 생성자 호출 가능
        super();
    }

	public void childMethod1() {
    	// 부모 필드와 메서드 호출 가능
        this.parentField = "Parent";
        this.parentMethod();
    }
    
    public void childMethod2() {
    	// 아래 코드들은 직접 객체를 생성하여 사용하려 하기 때문에 모두 실행 불가
        // Parent p1 = new Parent();
        // p1.parentField = "Parent";
        // p1.parentMethod();
    }
}