클래스는 인스턴스를 생성할 때 클래스의 이름과 같은 이름인 생성자(constructor)로 인스턴스를 만든다.
클래스는 따로 만들어 주지 않아도 기본 생성자를 포함하고 있다. 아무것도 지정하지 않는 생성자를 기본 생성자라고 한다. 기본적으로 public 권한으로 설정되어 있어서 따로 명시하지 않아도 클래스를 만들게 되면 새로운 인스턴스를 생성할 수 있도록 만든다.
만약 처음에 인스턴스를 생성할 때부터 필드를 초기화하고 싶다면, 필드를 초기화할 수 있게 만드는 생성자를 구성할 수 있다.
생성자는 접근 권한을 설정할 수 있고, 리턴 타입은 명시하지 않으며, 초기화할 필드에 따라 파라미터를 설정한다.
import java.io.FileWriter;
import java.io.IOException;
public class OthersOOP {
public static void main(String[] args) throws IOException {
FileWriter f1 = new FileWriter("data.txt");
f1.write("Hello Java");
f1.close();
}
}
위 코드에서
FileWriter 클래스를 호출할 때 'data.txt'라는 값을 입력했다. 파일을 수정한다는 행위를 나타내는 FileWriter 클래스는 수정하고자 하는 대상인 파일이 반드시 지정되어 있어야 한다.
이 파일을 지정하는 행위를 까먹거나, 나중에 하거나 하게 되면 문제가 생길 수 있기 때문에, 이 인스턴스를 생성하는 시점에 파일을 지정할 수 있다면 사용자들이 안전하게 사용할 수 있을 것이다. 또, 인스턴스가 생성될 때 반드시 처리해야 하는 어떠한 작업이 있을 수도 있다.
바로 그러한 초기값, 또는 인스턴스가 생성될 때 최초로 반드시 실행되어야 하는 어떠한 작업들을 우리가 하고 싶을 때 바로 생성자(constructor)이라는 것을 이용해서 이런 문제들을 해결할 수 있다.
public class MyOOP {
public static void main(String[] args) {
Print p1 = new Print();
p1.delimiter = "----";
p1.A();
p1.B();
Print p2 = new Print();
p2.delimiter = "****";
p2.A();
p2.B();
}
}
class Print {
public String delimiter;
public void A() {
System.out.println(delimiter);
System.out.println("A");
}
public void B() {
System.out.println(delimiter);
System.out.println("B");
}
}
위와 같은 코드들이 있다고 할 때,
만약 main 메소드에서 delimiter 값을 지정하지 않을 경우 우리가 만든 클래스가 인스턴스화 되지 못하도록 한다면, 사용자가 실수할 수 있는 가능성을 원천적으로 차단할 수 있다.
이것을 하기 위해서는 생성자(constructor)을 정의해줘야 한다. 클래스와 똑같은 이름의 메소드를 정의해주면 그것이 바로 생성자이다.
생성자를 정의해준 코드는 다음과 같다.
public class MyOOP {
public static void main(String[] args) {
Print p1 = new Print("----"); // 인스턴스 생성할 때 delimiter 값 설정 강제
// p1.delimiter = "----";
p1.A();
p1.B();
Print p2 = new Print("****");
// p2.delimiter = "****";
p2.A();
p2.B();
}
}
class Print {
public String delimiter;
// 생성자 (constructor)
public Print(String _delimiter) {
delimiter = _delimiter;
}
public void A() {
System.out.println(delimiter);
System.out.println("A");
}
public void B() {
System.out.println(delimiter);
System.out.println("B");
}
}
위 코드에서처럼 이제 main 메서드에서 인스턴스를 생성할 때 delimiter 값을 무조건 지정하도록 하는 것이다.
이때 생성자 메소드에 this 키워드를 사용할 수 있다.
생성자도 클래스 내부의 메소드이고, 보통 초기화할 필드를 파라미터로 넣기 때문에 생성자 내부에서 필드에 접근할 때 파라미터의 이름과 같게 되어 접근하기 어렵게 된다.
이때 사용하는 예약어가 this인데, this는 인스턴스를 가리키는 예약어이다. this를 통해 필드를 손쉽게 사용할 수 있다.
class Print {
public String delimiter;
// 생성자
public Print(String delimiter) {
this.delimiter = delimiter; // this 예약어
}
public void A() {
System.out.println(this.delimiter);
System.out.println("A");
}
public void B() {
System.out.println(this.delimiter);
System.out.println("B");
}
}
이렇게 깔끔하게 정리할 수 있는 것이다.
결론적으로, 생성자는 초기에 주입할 필요가 있는 값을 전달하거나, 초기에 작업을 수행하도록 할 때 사용한다. 그리고 this 라는 예약어는 그 클래스가 인스턴스화 되었을 때 그 인스턴스를 가리키는 특수한 이름이다.
[참고자료]
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
Using the this Keyword (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated
docs.oracle.com
https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
Providing Constructors for Your Classes (The Java™ Tutorials > Learning the Java Language > Classes and Ob
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated
docs.oracle.com
'Language > Java' 카테고리의 다른 글
this, super (0) | 2022.11.14 |
---|---|
Overriding, Overloading (0) | 2022.11.14 |
static (0) | 2022.11.13 |
접근 제어자 (access level modifiers) (0) | 2022.11.10 |
main 메소드 (0) | 2022.11.10 |