본문 바로가기
Java

[JAVA] 생성자, this, super

by 코코형아 2024. 1. 24.

6. 생성자, this, super

 

 

 

생성자


 

  • 객체를 생성할 때 호출하는 것 (like 메서드)
    • new 키워드와 함께 호출하는 것
    • 일반 멤버 변수의 초기화나 객체 생성 시 실행되어야 하는 작업 정리
Person p1 = new Person();

 

  • 작성 규칙
    • 메서드와 비슷하나 리턴 타입이 없고 이름은 클래스 이름과 동일

 

  • 기본생성자(default constructor)
    • 기본 생성자의 형태는 파라미터가 없고 구현부가 비어있는 형태
    • 생성자 코드가 없으면 컴파일러가 기본 생성자 제공
public class Movie {
	public int id;
	public String title;
	public String director;
	public String genre;
	public int runningTime;
	
	//public Movie() {
	//
	//} -> 컴파일러가 기본 생성자가 제공 
}

 

  • 파라미터가 있는 생성자
    • 생성자의 목적이 일반 멤버 변수의 초기화 → 생성자 호출 시 값을 넘겨줘서 초기화
💡 파라미터가 있는 생성자를 만들면 기본 생성자는 추가되지 않는다.

 

 

public class Movie {
	public int id;
	public String title;
	public String director;
	public String genre;
	public int runningTime;
	
	//public Movie() {
	//	
	//} -> 컴파일러가 자동으로 생성해주지 않는다!
	
	public Movie(int id, String title, String director, String genre, int runningTime) {
		this.id = id;
		this.title = title;
		this.director = director;
		this.genre = genre;
		this.runningTime = runningTime;
	}

	
}

 

 

 

 

this


  • 참조 변수로써 객체 자신을 가리킴
    • 참조 변수를 통해 객체의 멤버에 접근했던 것처럼 this를 이용해 자신의 멤버에 접근 가능
  • 용도
    • 로컬 변수와 멤버 변수의 이름이 동일할 경우 멤버 변수임을 명시적으로 나타냄
    • 명시적으로 멤버임을 나타낼 경우 사용
public class Movie {
	public int id; // 1
	public String title;
	public String director;
	public String genre;
	public int runningTime;
	
	public Movie(int id /* 2 */, String title, String director, String genre, int runningTime) {
		this.id = id; //this.id -> 멤버 변수(1), id -> 로컬 변수(2)
		this.title = title;
		this.director = director;
		this.genre = genre;
		this.runningTime = runningTime;
	}
}

 

  • this는 객체에 대한 참조
    • 따라서 static영역에서 this 사용 불가
  • 메서드와 마찬가지로 생성자도 오버로딩 가능
    • 객체 생성 시 필요한 멤버변수만 초기화 진행 → 생성자 별 코드의 중복 발생
    • 한 생성자에서 다른 생성자를 호출할 때 사용 - this()

 

this()

  • this()는 같은 클래스의 다른 생성자를 호출할 때 사용
  • 생성자의 첫줄에서만 사용 가능
public class Book {

    String title;
    int price;
    
    public Book() {
 	this("타이틀 미 입력", -1);
    }
    
    public Book(String title) {
    	this(title, 0);
    }
    
    public Book(String title, int price) {
    	this.title = title;
        this.price = price;
    }

 

 

  • this는 객체 자신에 대한 레퍼런스 변수로, this.title은 멤버변수 title을 나타냄
  • this()는 생성자 안에서 다른 생성자를 호출하므로, this(title, 0); 은 매개변수 2개를 가진 생성자를 호출

 

 

 

Super


  • this를 통해 멤버에 접근했듯이 super를 통해 조상 클래스 멤버를 접근할 수 있음
    • super.을 이용해 조상의 메서드 호출로 조상의 코드 재사용 가능
  • 변수의 scope
    • 사용된 위치에서 점점 확장해나가며 처음 만난 선언부에 연결됨
    • method 내부 → 해당 클래스 멤버 변수 → 조상 클래스 멤버 변수로 확장해나감
class Parent {
	String s = "parent";
}

class Child extends Parent {
	String s = "child";

	void method() {
		String s = "method";
		System.out.println("s : " + s);
		System.out.println("this.s : " + this.s);
		System.out.println("super.s : " + super.s);
	}
}

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

//출력 결과 : 
//method
//child
//parent

 

super()

  • this() 가 해당 클래스의 다른 생성자를 호출하듯 super()는 조상 클래스의 생성자 호출
    • 조상 클래스에 선언된 멤버들은 조상 클래스의 생성자에서 초기화가 이뤄지므로 이를 재활용
    • 자식 클래스에 선언된 멤버들만 자식 클래스 생성자에서 초기화
  • super()는 자식 클래스 생성자의 맨 첫 줄에서만 호출 가능
    • 즉 생성자의 첫 줄에서만 this() 또는 super()가 올 수 있다.
  • 명시적으로 this() 또는 super()를 호출하지 않는 경우 컴파일러가 super() 삽입
    • 결론적으로 맨 상위의 Object까지 객체가 다 만들어지는 구조
class Parent {
	String name;

	Parent(String name) {
		// -> Object의 기본 생성자 호출
		// super();
		this.name = name;
	}
}