반응형

<생성자의 개념과 목적>

- 생성자(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)라고 부른다.

반응형

+ Recent posts