생성자가 필요할이유?
- 평소에 우리가 사용하는 방식은
- 인스턴스 객체를 만들고
- 그후 객체.변수명을 사용하면 값을 설정할수있었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Cars
{
int price;
String color;
int km;
}
public class TEST {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cars a = new Cars();
a.price = 2000;
a.color = "red";
a.km = 10;
System.out.println("a.price , a.color, a.kr"+ " " + a.price+ " " + a.color + " " + a.km);
}
}
이때는 인스턴스의 초기화 작업이 필요하지않았기때문에
즉, Cars() 안에 매개변수의 초기화가 설정되있지않기때문에
자동으로 기본 생성자가 생겼었었다.
하지만 매개변수 초기화 작업이 필요하다?
이럴때 생성자라는 개념이 필요하다.
생성자
- 인스턴스가 생성될때 호출되는 인스턴스초기화 메서드
- 인스턴스 변수의 초기화 작업에 주로 사용
- 메서드처럼 클래스 내에 선언되며, 리턴값이 없음
- 생성자의 이름은 클래스의 이름과 같아야 함
이규칙을 가지고 생성자는 시작된다.
표현형식
1
2
3
4
5
6
7
8
9
10
class Card{
Card() //매개변수 없는 생성자
{
...
}
Card(String k, int num) //매개변수 있는 생성자
{
...
}
}
매개변수 있는 생성자의 선언방식
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Data1
{
int value;
}
class Data2
{
int value;
Data2(int x) //생성자를 만들었다면, 빈껍대기의 생성자를 만들지 않는다.
{
value = x;
}
}
public class DataTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Data1 d1 = new Data1(); // 빈껍데기생성자 자동생성
Data2 d2 = new Data2(10); // 생성자에 매개변수가 있으므로 꼭, 인스턴스 생성시 매개변수 맞춰줘야한다.
}
}
이것을 보면 생성자는 인스턴스 호출할때 자동 생성되는 매소드라고 생각하면된다.
만약 생성자를 위에서 선언해줬다면 그에 맞게끔 새인스턴스를 생성할때 매개변수를 맞춰줘야한다.
생성자 (호출 순서)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package sample;
class Car
{
String color;
String gearType; //auto(자동), manual(수동)
int door;
Car()
{
System.out.println("생성자 없음."); //1. 생성자없음이 호출된다. 그후 c1에 주소대입
}
Car(String c, String g, int d)
{
System.out.println("생성자 있음.");
color = c;
gearType = g;
door = d;
}
}
public class CarTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Car c1 = new Car(); //car메모리를 할당한후, 생성자를 호출하고, 그다음 그시작주소를 c1에 대입한다.
c1.color = "white";
c1.gearType = "auto";
c1.door = 4;
Car c2 = new Car("white", "auto", 4); //car메로리를 할당한후, 생성자에호출하고, 그다음 시작주소를 c2에 대입한
System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType + ", door=" + c1.door );
System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType + ", door=" + c2.door );
}
}
1
2
3
4
생성자 없음.
생성자 있음.
c1의 color=white, gearType=auto, door=4
c2의 color=white, gearType=auto, door=4
순서가 중요하다.
this를 사용.생성자끼리 호출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package sample;
class Car
{
String color;
String gearType;
int door;
Car()
{
this("white", "auto", 4); //생성자에서 다른생성자를 호출할때는 반드시 첫번째로 와야한다.
System.out.println("Car() 호출....");
}
Car(String color)
{
this("color", "auto", 4);
System.out.println("Car(String color) 호출....");
}
Car(String color, String gearType, int door)
{
this.color = color; // 인스턴스변수 = 지역변수 ,this.~ 는 인스턴스변수 , this() 다른생성자 호출
this.gearType = gearType;
this.door = door;
System.out.println("Car(String color, String gearType, int door) 호출....");
}
}
public class Sample1 {
public static void main(String[] args) {
Car c1 = new Car();
Car c2 = new Car("blue");
System.out.println("c1의 color = " + c1.color + ", gearType =" + c1.gearType + ", door=" + c1.door );
System.out.println("c2의 color = " + c2.color + ", gearType =" + c2.gearType + ", door=" + c2.door );
}
}
생성자이용한 인스턴스 복사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package sample;
class Car
{
String color;
String gearType;
int door;
Car()
{
this("white", "auto", 4); //생성자에서 다른생성자를 호출할때는 반드시 첫번째로 와야한다.
System.out.println("Car() 호출....");
}
Car(Car c)
{
color = c.color; //생성자를 이용한 인스턴스 복사
gearType = c.gearType;
door = c.door;
}
Car(String color)
{
this("color", "auto", 4);
System.out.println("Car(String color) 호출....");
}
Car(String color, String gearType, int door)
{
this.color = color; // 인스턴스변수 = 지역변수 ,this.~ 는 인스턴스변수 , this() 다른생성자 호출
this.gearType = gearType;
this.door = door;
System.out.println("Car(String color, String gearType, int door) 호출....");
}
}
public class Sample1 {
public static void main(String[] args) {
Car c1 = new Car();
Car c2 = new Car("blue");
System.out.println("c1의 color = " + c1.color + ", gearType =" + c1.gearType + ", door=" + c1.door );
System.out.println("c2의 color = " + c2.color + ", gearType =" + c2.gearType + ", door=" + c2.door );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package sample;
public class Sample2 {
public static void main(String[] args) {
// 생성자를 이용한 인스턴스 복사
Car c1 = new Car();
Car c2 = new Car(c1); //c1의주소를 가지고있다
System.out.println("c1의 color = " + c1.color + ", gearType =" + c1.gearType + ", door=" + c1.door );
System.out.println("c2의 color = " + c2.color + ", gearType =" + c2.gearType + ", door=" + c2.door );
// 두개다 동일한 값이 나온다.
c1.door = 100;
System.out.println("c1.door = 100; 수행후");
System.out.println("c1의 color = " + c1.color + ", gearType =" + c1.gearType + ", door=" + c1.door );
System.out.println("c2의 color = " + c2.color + ", gearType =" + c2.gearType + ", door=" + c2.door );
}
}
1
2
3
4
5
6
7
8
Car(String color, String gearType, int door) 호출....
Car() 호출....
c1의 color = white, gearType =auto, door=4
c2의 color = white, gearType =auto, door=4
c1.door = 100; 수행후
c1의 color = white, gearType =auto, door=100
c2의 color = white, gearType =auto, door=4
- 크게 이소스를 보면 Car c2 = new Car(c1);
- color = c.color; //생성자를 이용한 인스턴스 복사
- gearType = c.gearType;
- door = c.door;
이방식으로 c1의 주소를 넘겨주어서 c2에도 c1의 값을 줄수가있었다.
# 인스턴스 초기화 블럭
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package sample;
public class Sample3 {
// 클래스 초기화 블럭
static
{
System.out.println("static{}...."); // 첫번째로 실행된다.
}
//인스턴스 초기화 블럭
{
System.out.println("{ }...");
}
Sample3()
{
System.out.println("생성자....");
}
public static void main(String[] args) {
//초기화블럭
System.out.println("Sample3 sp = new Sample3();");
Sample3 sp = new Sample3();
System.out.println("Sample3 sp2 = new Sample3();");
Sample3 sp2 = new Sample3();
}
}
1
2
3
4
5
6
7
static{}....
Sample3 sp = new Sample3();
{ }...
생성자....
Sample3 sp2 = new Sample3();
{ }...
생성자....
- 인스턴스 초기화블럭을 추가로 보면 될거같다
- 생성자가 생기기전 호출되는것을 알면된다.
## 예제2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package sample;
class Product
{
static int count = 0; //공유할 수 있는 클래스변수
int serialNo;
{
++count;
serialNo = count; // 인스턴스 초기화 블럭
}
Product(){}
}
public class Sample1 {
public static void main(String[] args) {
/*
* 실행결과) p1의 제품번호(serial no )는1
* p2의 제품번호는(serial no)는 2
* p3의 제품번호는(serial no)는 2
* 생산된 제품의 수는 모두 3개입니다.
*/
Product p1 = new Product();
Product p2 = new Product();
Product p3 = new Product();
System.out.println("p1의 제품번호(serial no)는" + p1.serialNo); //1출력
System.out.println("p2의 제품번호(serial no)는" + p2.serialNo); //2출력
System.out.println("p3의 제품번호(serial no)는" + p3.serialNo);
System.out.println("생산된 제품의 수는 모두" + Product.count + "개 입니다.");
}
}
1
2
3
4
p1의 제품번호(serial no)는 1
p2의 제품번호(serial no)는 2
p3의 제품번호(serial no)는 3
생산된 제품의 수는 모두3개 입니다.
static변수는 세 인스턴스가 공유하는것을알수있고 초기화블럭이 세 인스턴스가 생성될때마다 출력되서 숫자가 증가하는것을 알 수 있다.