본문 바로가기

자바스프링웹공부(2024)/자바

2024.09.13. super

반응형

* 상속에서 생성자
 - 생성자는 상속되지 않음
 - 서브클래스의 객체(인스턴스) 생성시, 먼저 슈퍼클래스의 인스턴스를 생성한 후 서브클래스의 인스턴스가 생성됨
  => 이떄, 서브클래스의 생성자 내에서 먼저 자동으로 슈퍼클래스의 기본생성자 호출

       (생성자 super() 코드가 생략되어 있을 경우에도 암묵적으로 호출됨)
  => 슈퍼클래스의 생성자 내에서 작업이 모두 끝나면 다시 서브클래스의 생성자로 돌아와서 다음 코드들을 실행하게 됨
        즉, 슈퍼클래스의 생성자의 코드가 먼저 실행된 후 서브클래스 생성자 코드가 실행됨.
 - 슈퍼클래스에 기본생성자가 꼭 있어야함. 

   만약에 없으면 오버로딩된 형식대로 맞추든지 부모 클래스 기본 생성자를 만들어줘야한다.

* 이클립스에서 슈퍼클래스를 통해 간접적으로 초기화 하도록 생성자를 자동정의하는 단축키
1. Alt + Shift + S -> O
=> 슈퍼클래스의 멤버변수를 슈퍼클래스에서, 서브클래스의 멤버변수를 서브클래스에서 초기화하는 생성자가 자동으로 생성됨
2. Alt + Shift + S -> C (내가 추가한 멤버변수가 없을 때 사용)
=> 슈퍼클래스의 생성자와 동일한 형태의 생성자가 자동으로 생성됨.
   (주로, 서브클래스에서 추가한 멤버변수가 없을 때 생성자 정의시 사요함) 

* 생성자 super()
- 서브클래스의 생성자 내에서 슈퍼클래스의 생성자를 명시적으로 호출하는 코드
- 서브클래스의 생성자 내에서 생성자 super() 코드가 생략될 경우 컴파일러에 의해 슈퍼클래스의 기본생성자 호출하는 super()가 자동으로 추가됨.
- 생성자 super()도 생성자 this()와 마찬가지로 생성자 내에서 반드시 첫줄에 실행되어야 한다.
=> 따라서, 생성자 this()와 super()는 하나의 생성자에서 기술불가! 
=> 만약, 오버로딩 생성자 호출 this()와 슈퍼클래스 호출하는 super()가 함께 실행되어야 하는 경우 this() 생성자를 통해 
     다른 생성자를 먼저 호출한 후 해당 오버로딩 생성자 내에서 생성자 super()를 통해 슈퍼클래스에 접근해야함.
- 주로, 슈퍼클래스의 기본생성자가 없는 상태에서 파라미터 생성자만 정의했을 경우.
  서브 클래스에서 슈퍼클래스 기본생성자를 호출하게 되면 오류가 발생하므로 

  이때, 슈퍼클래스의 파라미터 생성자를 명시적으로 호출하는 용도로 사용 super(전달한 데이터...);

public class Ex1 {
	public static void main(String[] args) {
		Child c = new Child();
	}
}
class Parent {
	public Parent() {
		// super();// object 상속받음.
		System.out.println("Parent 생성자");
	}
	public Parent(String name) {
		System.out.println("Parent 생성자");
	}
}
class Child extends Parent {
	public Child() { 
		super("홍길동"); // 부모생성자처럼 파라미터 넣음.
		System.out.println("Child 생성자");
	}
}
class Person {
	String name;
	int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
}
class SpiderMan extends Person {
	boolean isSpider;

	public SpiderMan(String name, int age, boolean isSpider) {
		super(name, age);
		this.isSpider = isSpider;
	}
	public SpiderMan(String name, int age, boolean isSpider) { // 에러가 난다. 해결법은?? 
		// 슈퍼클래스의 생성자를 호출하여 간접적으로 상속받은 멤버변수에 대해 초기화를 수행하고,
		// 서브클래스에서 선언한 멤버변수만 직접 초기화하면 코드 중복제거 가능 
		super(name,age); //슈퍼클래스의 파라미터 생성자를 명시적으로 호출하는 용도로 super()사용됨.
        	this.isSpider = isSpider;
	}
}

 

* super.super가 안되는 이유
- 부모 클래스에서 확장된 클래스가 (자식클래스) 부모의 부모 클래스를 접근함으로써 캡슐화 위반을 막기위함
- 따라서, 부모 클래스의 메서드를 우회하여 부모의 부모클래스 메서드나, 멤버변수에 접근할 수 없다. 
  ex. Unit 

        AirUnit - GroundUnit

        Jet       - Tank

   - AirUnit 을 상속받는 공중 유닛 Jet는 날아가서 바로 목표지점에 도착해도 괜찮음.

   - GroundUnit 을 상속받는 지상 유닛 Tank가 super.super 해가지고 목표지점으로 바로 날아가는 오류가 생기게 됨. 

 

반응형