Java - 생성자, 생성자 오버로딩

2020. 6. 13. 22:32Java

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
public class Ex {
 
    public static void main(String[] args) {
        /*
         * 생성자(Constructor)
         * - 클래스를 사용하여 인스턴스를 생성할 때 호출되는 메서드 형태
         * - 주로 인스턴스 변수를 초기화하는 용도 또는 인스턴스 생성 시 초기에 수행할 작업 기술
         * - 메서드와 차이점(생성자 작성 규칙)
         *   1) 선언부에 리턴타입이 없음(리턴값이 없는게 아니라 리턴타입을 기술하지 않음)
         *   2) 생성자 이름이 클래스명과 동일함
         * - 개발자가 생성자를 하나도 정의하지 않으면, 컴파일러에 의해 자동으로 기본 생성자 생성
         *   => 단, 생성자를 하나라도 정의할 경우 기본 생성자는 자동 생성되지 않는다!
         * - 파라미터가 없는 생성자와 파라미터가 있는 생성자 모두 정의 가능(= 메서드와 동일)
         * 
         * < 생성자 정의 기본 문법 >
         * [접근제한자] 클래스명([파라미터변수선언...]) {
         *         // 생성자 호출 시점(인스턴스 생성 시점)에 수행할 작업들(= 인스턴스 변수 초기화 등)
         * }
         */
        
        // Student 인스턴스 생성 후 id : 20201111, 이름 : 홍길동 으로 초기화
        Student s = new Student();
        // => new 뒤의 Student() 코드 부분이 생성자 Student() 를 호출하는 코드
//        s.id = 20201111;
//        s.name = "홍길동";
//        s.name = "이순신";
        System.out.println("아이디 : " + s.id + ", 이름 : " + s.name);
        
        System.out.println("-------------------");
        
        Student s2 = new Student();
        System.out.println("아이디 : " + s2.id + ", 이름 : " + s2.name);
        
    }
 
}
 
class Student {
    int id;
    String name;
    
    // 클래스 내에서 별도의 생성자를 정의하지 않으면
    // 자바 컴파일러에 의해 기본 생성자가 자동으로 생성됨
//    public Student() {} // 기본 생성자 형태
    
    // 직접 기본 생성자를 정의하여 인스턴스 변수를 초기화하는 경우
    public Student() {
        // 생성자 내에서 인스턴스 변수 초기화 가능함
        // => 인스턴스 생성 시 생성자가 호출되면 자동으로 초기화 수행되므로 
        //    모든 Student 클래스의 인스턴스는 시작 시 동일한 값을 갖는다.
        id = 20201111;
        name = "홍길동";
    }
    
}
 
ublic class Ex2 {
 
    public static void main(String[] args) {
        /*
         * 파라미터 생성자 정의
         * - 일반 메서드와 동일하게 선언부 소괄호() 안에 파라미터 변수를 선언하는 생성자
         * - 주의! 파라미터 생성자를 하나라도 정의하게 되면, 기본 생성자가 자동으로 생성되지 않음
         *   => 따라서, 인스턴스 생성 시 기본 생성자 호출 코드가 있으면 오류 발생하게 됨!
         *      (파라미터가 일치하지 않는 메서드를 호출하는 것과 동일한 상황)
         */
        
//        Student2 s = new Student2(); // 기본생성자 Student2() 호출 => 오류 발생!
        // => 파라미터 생성자가 정의되어 있으므로 기본생성자가 자동 생성되지 않음
        
        // 메서드와 동일하게 파라미터 갯수 및 타입이 일치하도록 데이터 전달 필수!
        Student2 s = new Student2(20201111"홍길동");
        System.out.println("아이디 : " + s.id + ", 이름 : " + s.name);
        
        
    }
 
}
 
class Student2 {
    int id;
    String name;
    
    // Student2() 기본 생성자 정의
//    public Student2() {
//        id = 20201111;
//        name = "홍길동";
//    }
    
    // Student2() 파라미터 생성자 정의
    // => 생성자를 직접 정의했기 때문에, 기본 생성자는 더이상 자동으로 생성되지 않는다!
    public Student2(int newId, String newName) {
        // 아이디(newId)와 이름(newName)을 전달받아 멤버변수를 초기화
        System.out.println("Student2(int, String) 생성자 호출됨!");
        id = newId;
        name = newName;
    }
    
    
}
 
public class Ex3 {
 
    public static void main(String[] args) {
        /*
         * 생성자 오버로딩
         * - 클래스 내에서 생성자 여러개를 정의하는 것(=> 파라미터를 달리함)
         *   => 일반 메서드 오버로딩과 동일
         * - 생성자 내에서 다른 생성자를 이름으로 호출할 수 없다!
         */
        
        // 인스턴스 생성 시 Mydate() 생성자 호출
        MyDate d1 = new MyDate();
//        System.out.println(d1.year + "/" + d1.month + "/" + d1.day);
        
        // 인스턴스 d1 내의 printDate() 메서드 호출
//        d1.printDate();
        
        System.out.println("-------------------------------");
        
        // 인스턴스 생성 시 MyDate(int year) 생성자 호출
        MyDate d2 = new MyDate(2000);
//        System.out.println(d2.year + "/" + d2.month + "/" + d2.day);
        
        // 인스턴스 d2 내의 printDate() 메서드 호출
//        d2.printDate();
        
        System.out.println("-------------------------------");
        
        // 인스턴스 생성 시 MyDate(int year, int month) 생성자 호출
        MyDate d3 = new MyDate(20105);
//        System.out.println(d3.year + "/" + d3.month + "/" + d3.day);
        
        // 인스턴스 d3 내의 printDate() 메서드 호출
//        d3.printDate();
        
        System.out.println("-------------------------------");
        
        // 인스턴스 생성 시 MyDate(int year, int month, int day) 생성자 호출
        MyDate d4 = new MyDate(2020527);
//        System.out.println(d4.year + "/" + d4.month + "/" + d4.day);
        
        // 인스턴스 d4 내의 printDate() 메서드 호출
//        d4.printDate();
        
        System.out.println("-------------------------------");
        
    }
 
}
 
// 날짜를 관리하는 MyDate 클래스
class MyDate {
    // 연도(year), 월(month), 일(day) - 정수형 변수로 선언
    int year;
    int month;
    int day;
    
    // MyDate() 생성자 오버로딩
    // 1. 파라미터가 없는 생성자(기본 생성자) MyDate() 정의
    public MyDate() {
        System.out.println("MyDate() 생성자 호출됨!");
        // 1900년 1월 1일로 초기화
        year = 1900;
        month = 1;
        day = 1;
        
        // 멤버메서드 printDate() 호출하여 날짜 출력
        printDate();
        
        // 생성자 내에서 메서드 호출과 동일하게 다른 생성자를 호출할 수는 없다!
//        MyDate(1900, 1, 1); // 오류 발생! 생성자 이름을 사용하여 호출 불가능!
    }
    
    // 2. 파라미터 1개(연도)를 전달받아 초기화하는 생성자 MyDate(int) 추가 = 오버로딩
    // => 연도(newYear)를 전달받아 멤버변수 year 을 초기화하고, 나머지는 1월 1일로 초기화
    public MyDate(int newYear) {
        System.out.println("MyDate(int) 생성자 호출됨!");
        year = newYear; // 전달받은 연도를 사용하여 초기화
        month = 1;
        day = 1;
        
        // 멤버메서드 printDate() 호출하여 날짜 출력
        printDate();
    }
    
    // 3. 파라미터 2개(연도, 월)를 전달받아 초기화하는 생성자 MyDate(int, int) 추가
    // => 연도(newYear), 월(newMonth) 전달받아 멤버변수 초기화하고, day 는 1일로 초기화
    public MyDate(int newYear, int newMonth) {
        System.out.println("MyDate(int, int) 생성자 호출됨!");
        year = newYear; // 전달받은 연도를 사용하여 초기화
        month = newMonth; // 전달받은 월을 사용하여 초기화
        day = 1;
        
        // 멤버메서드 printDate() 호출하여 날짜 출력
        printDate();
        
    }
    
    // 4. 파라미터 3개(연도, 월, 일)를 전달받아 초기화하는 생성자 MyDate(int, int, int) 추가
    // => 연도(newYear), 월(newMonth), 일(newDay) 전달받아 멤버변수 초기화
//    public MyDate(int newYear, int newMonth, int newDay) {
//        System.out.println("MyDate(int, int, int) 생성자 호출됨!");
//        year = newYear; // 전달받은 연도를 사용하여 초기화
//        month = newMonth; // 전달받은 월을 사용하여 초기화
//        day = newDay;
//        
//        // 멤버메서드 printDate() 호출하여 날짜 출력
//        printDate();
//    }
 
    
    // 생성자 자동 생성 단축키 : Alt + Shift + S -> O
    // => 필요한 멤버변수 선택 후 Generate 클릭
    public MyDate(int year, int month, int day) {
        System.out.println("MyDate(int, int, int) 생성자 호출됨!");
        
        this.year = year;
        this.month = month;
        this.day = day;
        
        printDate();
    }
    
    // 일반 메서드 printDate() 정의
    // => 파라미터 : 없음, 리턴값 : 없음
    // => "연도/월/일" 형태로 날짜 출력
    public void printDate() {
        System.out.println(year + "/" + month + "/" + day);
        
        // 메서드 내에서도 생성자 호출은 불가능하다!
//        MyDate(1900, 1, 1); // 오류 발생!
    }
 
    
}
public class Test {
 
    public static void main(String[] args) {
        Account acc = new Account(); // 인스턴스 생성 시점에서 Account() 생성자가 호출됨
        
        // 멤버변수 초기화 시 private 접근제한자로 인해 직접 접근이 불가능하므로
        // Setter 를 통해 간접적으로 초기화 필요
//        acc.setAccountNo("111-1111-111");
//        acc.setOwnerName("홍길동");
//        acc.setBalance(100000);
        // => 생성자를 통해 초기화를 수행해도 동일함
        
        
        // Getter 를 통해 간접적으로 멤버변수 값 가져와야함
        System.out.println("계좌번호 : " + acc.getAccountNo());
        System.out.println("예금주명 : " + acc.getOwnerName());
        System.out.println("현재잔고 : " + acc.getBalance() + "원");
        
    }
 
}
 
/*
 * Account 클래스 정의
 * - 멤버변수 => 모든 멤버변수의 접근제한자를 private 으로 지정
 *   1) 계좌번호(accountNo, 문자열)
 *   2) 예금주명(ownerName, 문자열)
 *   3) 현재잔고(balance, 정수)
 *   
 * - 기본 생성자 정의 
 *   => 계좌번호, 예금주명, 현재잔고를 초기화
 *    
 * - Getter/Setter 정의
 */
class Account {
    // 멤버변수 선언
    private String accountNo;
    private String ownerName;
    private int balance;
    
    // 생성자 정의
    public Account() {
        System.out.println("생성자 Account() 호출됨!");
        // 멤버변수의 값을 초기화
        // 멤버변수(인스턴스변수)는 인스턴스 내에서 모두 접근 가능하므로 이름만으로 접근 가능
        accountNo = "111-1111-111";
        ownerName = "홍길동";
        balance = 100000;
    }
    
    // Getter/Setter 정의
    public String getAccountNo() {
        return accountNo;
    }
    public void setAccountNo(String accountNo) {
        this.accountNo = accountNo;
    }
    public String getOwnerName() {
        return ownerName;
    }
    public void setOwnerName(String ownerName) {
        this.ownerName = ownerName;
    }
    public int getBalance() {
        return balance;
    }
    public void setBalance(int balance) {
        this.balance = balance;
    }
    
    
}
public class Test3 {
 
    public static void main(String[] args) {
        Account2 acc1 = new Account2();
//        System.out.println("계좌번호 : " + acc1.getAccountNo());
//        System.out.println("예금주명 : " + acc1.getOwnerName());
//        System.out.println("현재잔고 : " + acc1.getBalance());
        acc1.showAccountInfo();
        
        System.out.println("-----------------");
        
        // 계좌번호를 전달받는 생성자 Account3(String) 호출
        Account2 acc2 = new Account2("555-5555-555");
        acc2.showAccountInfo();
        
        System.out.println("-----------------");
        
        // 계좌번호, 예금주명을 전달받는 생성자 Account3(String, String) 호출
        Account2 acc3 = new Account2("777-7777-777""이순신");
        acc3.showAccountInfo();
 
        System.out.println("-----------------");
        
        // 계좌번호, 예금주명, 현재잔고를 전달받는 생성자 Account3(String, String, int) 호출
        Account2 acc4 = new Account2("777-7777-777""이순신"99999);
        acc4.showAccountInfo();
        
    }
 
}
 
/*
 * 은행계좌(Account3) 클래스 정의
 * 
 * 인스턴스변수 선언
 * 계좌번호(accountNo, 문자열), 예금주명(ownerName, 문자열), 현재잔고(balance, 정수)
 * => 접근제한자를 private 으로 선언
 * 
 * 생성자 정의
 * 1) 파라미터가 없는 기본 생성자 정의
 *    계좌번호 : 111-1111-111, 예금주명 : 홍길동, 현재잔고 : 0 으로 초기화
 * 2) 파라미터 1개 => 계좌번호를 전달받은 데이터로 초기화
 *                    예금주명 : 홍길동, 현재잔고 : 0 으로 초기화
 * 3) 파라미터 2개
 *    => 계좌번호, 예금주명을 전달받은 데이터로 초기화, 현재잔고 : 0 으로 초기화                                        
 * 4) 파라미터 3개
 *    => 계좌번호, 예금주명, 현재잔고를 전달받은 데이터로 초기화
 * 
 * Getter/Setter 정의
 */
class Account2 {
    // 인스턴스 변수
    private String accountNo;
    private String ownerName;
    private int balance;
    
    // 생성자
    public Account2() {
        System.out.println("Account3() 생성자 호출됨!");
        this.accountNo = "111-1111-111";
        this.ownerName = "홍길동";
        this.balance = 0;
    }
    
    public Account2(String accountNo) {
        System.out.println("Account3(String) 생성자 호출됨!");
        this.accountNo = accountNo;
        this.ownerName = "홍길동";
        this.balance = 0;
    }
    
    public Account2(String accountNo, String ownerName) {
        System.out.println("Account3(String, String) 생성자 호출됨!");
        this.accountNo = accountNo;
        this.ownerName = ownerName;
        this.balance = 0;
    }
    
    public Account2(String accountNo, String ownerName, int balance) {
        System.out.println("Account3(String, String, int) 생성자 호출됨!");
        this.accountNo = accountNo;
        this.ownerName = ownerName;
        this.balance = balance;
    }
    
    
    // Getter/Setter
    public String getAccountNo() {
        return accountNo;
    }
    public void setAccountNo(String accountNo) {
        this.accountNo = accountNo;
    }
    public String getOwnerName() {
        return ownerName;
    }
    public void setOwnerName(String ownerName) {
        this.ownerName = ownerName;
    }
    public int getBalance() {
        return balance;
    }
    public void setBalance(int balance) {
        this.balance = balance;
    }
    
    // 계좌정보를 출력하는 showAccountInfo() 메서드 정의
    public void showAccountInfo() {
        System.out.println("계좌번호 : " + accountNo);
        System.out.println("예금주명 : " + ownerName);
        System.out.println("현재잔고 : " + balance);
    }
    
}
cs

생성자의 개념에 대해 배웠고 생성자를 활용한 오버 로딩을 이용하는 방법에 대해서 배우게 되었다. 리턴 값을 적지 않고 public 클래스명{} 형식으로 적어주는 생성자. 기본 생성자를 선언하게 되어 버리면 이제 프로그램이 자동으로 생성자를 생성하지 않는다는 것도 알게 되었고 생성자를 활용하여 오버 로딩하는 방법도 알게 되었다. 생성자는 메서드와 달리 인스턴스화 시키는 그 시점에서만 사용되고 그 후엔 적용이 안된다는 것도 알게 되었고 , 생각보다 간단한 개념이었다. 오버 로딩을 시켜주는 단축키도 알게 되었는데 Alt + Shift + S = O , 이것으로 간편하게 생성자를 오버 로딩시킬 수 있었고 역시나 Getter/Setter과 같이 자동화로 하게 되면 편하지만 혹시나 모를 경우를 대비해서 내가 직접 써보며 좀 더 익숙해지며 개념을 확실히 이해하고 체득하는 기간이 필요할 것 같다. 저번에 배웠던 은행계좌 형식의 클래스를 활용하여 생성자와 private가 선언된 변수를 활용하여 Getter/Setter를 설정하여 테스트도 해보았고 여러모로 많은 걸 배울 수 있는 시간이었다.

'Java' 카테고리의 다른 글

Java - static 키워드, 싱글톤디자인패턴  (0) 2020.06.14
Java - this. 문법  (0) 2020.06.14
Java - 가변인자, 접근제한자,Getter/Setter  (0) 2020.06.13
Java - 메서드 오버로딩  (0) 2020.06.13
Java - 메서드를 활용하기.  (0) 2020.06.13