<생성자의 개념과 목적>
- 생성자(constructor)는 객체가 생성될 때 객체의 초기화를 위해 실행되는 메소드이다.
예를 들어 얼굴 클래스로 얼굴을 만들어 냈을 때 생성자 없이 객체가 생성된다면 생성된 얼굴 객체는 맨 얼굴(기본 객체)일 것이다. 하지만 생성자(화장)를 실행하여 얼굴의 각 부위를 화장(초기화)하게 한다면 예쁘게 화장된 얼굴 객체(초기화된 객체)로 생성될 것이다.
<생성자 선언 및 활용>
- 생성자(constructor)는 객체가 생성되는 순간에 자동으로 호출되는 메소드로서, 객체에 필요한 초기화를 실행하는 코드를 담아야 한다.
1. 생성자의 이름은 클래스 이름과 동일하다.
- 생성자의 이름은 반드시 클래스 이름과 동일하게 작성해야 한다.
public class Circle {
public Circle(int r, String n) {...} // 생성자
}
2. 생성자는 여러 개 작성(오버로딩) 할 수 있다.
- 매개변수의 개수와 타입만 다르다면, 클래스 내에 생성자를 여러개 둘 수 있다.
public class Circle {
public Circle() {...} // 매개 변수 없는 생성자
public Circle(int r, String n){...} // 2개의 매개 변수를 가진 생성자
}
3. 생성자는 new를 통해 객체를 생성할 때 한 번만 호출된다.
- 객체 생성은 반드시 new를 통해서만 이루어지며, 생성자는 이때 자동으로 한번만 호출된다. 호출하고 싶을때 아무 때나 호출할 수 있는 메소드가 아니다.
Circle pizza = new Circle(10, "자바 피자"); // 생성자 Circle(int r, String n) 호출
Circle donut = new Circle(); // 생성자 Circle() 호출
4. 생성자에 리턴 타입을 지정할 수 없다.
- 생성자는 어떤 값도 리턴하지 않기 때문에 다음과 같이 리턴 타입을 선언해서는 안된다.
public Circle() {...} //리턴 타입 선언하지 않음
- 리턴 값이 없다고 해서, void를 리턴 타입으로 지정하면 안 된다.
public void Circle(){...} //오류, void를 리턴 타입으로 사용할 수 없음
5. 생성자의 목적은 객체가 생성될 때, 필요한 초기 작업을 위함이다.
Circle(int r, String n) 생성자를 호출하여 pizza 객체의 radius를 10으로 name을 "자바 피자"로 초기화한다.
Circle pizza = new Circle(10, "자바 피자"); //생성자 Circle(int r, String n) 호출
6. 생성자 선언 및 활용 연습
제목과 저자를 나타내는 title과 author 필드를 가진 Book 클래스를 작성하고, 생성자를 작성하여 필드를 초기화하라.
public class Book {
String title;
String author;
public Book(String t) { // 생성자
title = t;
author = "작자미상";
}
public Book(String t, String a) { // 생성자
title = t;
author = a;
}
public static void main(String[] args) {
Book littlePrince = new Book("어린왕자", "생텍쥐페리");
// 생성자 Book(String t, String a) 호출
Book loveStory = new Book("춘향전"); // 생성자 Book(String t) 호출
System.out.println(littlePrince.title+" " + littlePrince.author);
System.out.println(loveStory.title+" " + loveStory.author);
}
}
<기본 생성자>
- 기본 생성자(default constructor)란 매개변수와 실행 코드가 없어 아무일도 하지 않고 단순 리턴하는 생성자로 디폴트 생성자라고도 부른다.
class Circle {
public Circle(){ } //기본 생성자. 매개변수 없고 아무 일 없이 단순 리턴
}
1. 기본 생성자가 자동으로 생성되는 경우
- 객체가 생성될 때 반드시 생성자가 실행되기 때문에 생성자가 하나도 없는 경우, 컴파일러는 기본 생성자를 자동으로 생성한다.
2. 기본 생성자가 자동으로 생성되지 않은 경우
- 자바 컴파일러는 클래를 만든 개발자의 의도를 지켜주기(훼손하지 않기) 위하여 생성자가 하나라도 존재하는 클래스에는 컴파일러가 기본 생성자를 자동으로 삽입해주지 않는다.
<this 레퍼런스>
1. this의 기초 개념
- this는 현재 실행되고 있는 메소드가 속한 객체의 레퍼런스 즉, 현재 객체 자신에 대한 레퍼런스이다.
public class Circle{
int radius;
public Circle(int r){this.radius = r; }
public int getRadius(){return radius; }
}
ex) 위 코드에서 this는 현재 객체에 대한 레퍼런스이므로 this.radius는 현재 객체의 멤버 radius를 접근한다.
2. this의 필요성
-앞의 Circke 클래스에서 메소드 getRadius()는 this를 사용하지 않았다. 클래스 멤버 내에서 radius를 접근할 때는 굳이 this.radius로 할 필요가 없다.
return radius; // return this.radius; 와 동일
매개변수를 필요로 할 때 -> 매개변수의 이름은 그 자체로서 코드를 읽는 사람에게 그 용도를 나타내므로 circle(int r) 생성자의 매개변수를 r 대신 radius로 변경하는 것이 좋다.
public Circle(int radius) {radius = radius;}
하지만 이렇게 코드를 변경하면 여기서 2개의 radius는 모두 Circle(int radius)의 매개변수 radius를 접근하게 되므로 멤버 radius를 변경하지 못한다. 이때 this를 이용하면 된다.
또 메소드가 객체 자신의 레퍼런스를 리턴해야 하는 경우, this를 리턴하면 된다.
public Circle getMe(){return this;} //getMe() 메소드는 객체 자신의 레퍼런스를 리턴
3. this의 상세 설명
이 코드에서 main()은 3개의 Circle 객체(ob1, ob2, ob3)를 생성한다. ( 객체가 있어야 this를 사용할 수 있다.)
이 객체에서 this는 각각 자기가 속한 객체에 대한 레퍼런스( ob1.set(4)가 실행될때 this는 ob1 객체에, ob2.set(5)이 실행될때 this는 ob2객체, ob3.set(6)이 실행될때 this는 ob3객체에 대한 레퍼런스)이다.
<this()로 다른 생성자 호출>
public class Book {
String title;
String author;
void show(){ System.out.println(title + " " + author); }
public Book() {
this(" " , " ");
System.out.println("생성자 호출됨");
}
public Book(String title) {
this(title, "작자미상");
}
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public static void main(String[] args) {
Book littlePrince = new Book("어린왕자", "생텍쥐페리");
Book loveStory = new Book("춘향전");
Book empty = new Book();
loveStory.show();
}
}
위 코드 main()에서 객체 생성문을 보면
new가 실행될 때 Book(String title) 생성자가 호출되며 title에는 "춘향전"이 전달된다.
그리고 생성자는 바로 다음 this() 문을 실행한다.
public Book(String title) {
// Book loveStory = new Book("춘향전"); 이 실행될때 Book(String title) 생성자가 호출되고
// title에 "춘향전"이 전달됨.
this(title, "작자미상");
}
Book loveStory = new Book("춘향전");
이 this() 문은 2개의 매개변수를 가진 다음 생성자를 다시 호출한다.
이 생성자에 의해 멤버 title과 author는 각각 "춘향전", "작자미상"으로 초기화된다.
public Book(String title, String author) {
this.title = title;
this.author = author;
}
1. this 사용 시 주의할 점
- this()는 반드시 생성자 코드에서만 호출할 수 있다.
- this()는 반드시 같은 클래스 내 다른 생성자를 호출할 때 사용된다.
- this()는 반드시 생성자의 첫번째 문장이 되어야 한다.
<객체 치환 시 주의할 점>
- 연산자로 객체를 치환하면 객체를 복사하는 것이 아니라 같은 객체를 함께 가리키게 된다.
main()메소드에서 다음과 같이 Circle 객체를 두개 생성한 후
Circle ob1 = new Circle(1);
Circle ob2 = new Circle(2);
다음 라인을 실행하면 , ob2의 래퍼런스가 레퍼런스 s에 치환(대입)되어 s는 ob2가 가리키는 객체를 함께 가리키게 된다.
s = ob2;
다음 객체 치환 문장을 실행해보면
ob1 = ob2 ;
역시 ob1의 레퍼런스가 ob2의 레퍼런스와 동일하게 되어 ob2의 객체를 함께 가리키게 된다.
그러고 나면 원래 ob1이 가리키던 객체는 아무도 가리키지 않게 되어 프로그램에서 접근할 수 없는 상태가 되는데 이 객체를 가비지(garbage)라고 부른다.
'프로그래밍 공부 > java' 카테고리의 다른 글
[Java] 이것이 자바다 6장 확인 문제 1 : this()를 활용해서 중복 코드 제거하기 (1) | 2022.12.30 |
---|---|
[JAVA] 클래스와 객체 - 객체 배열, 메소드, 접근지정자, static, final클래스 (0) | 2022.12.30 |
[JAVA] 클래스와 객체 - 객체지향과 자바 , 자바 클래스 만들기 (0) | 2022.12.20 |
[Java] 이중 for문을 사용하여 별 찍기 (0) | 2022.12.07 |
[JAVA] JAVA Programming 3장 실습문제 2번 (0) | 2022.12.06 |