char ch = 'A'; // 문자

char ch = 'AB'; // 에러 발생

String s = "ABC"; // 문자열

 

String은 자료형이 아니라 클래스이다. 따라서, 원칙적으로는 new 연산자를 사용하여

String str = new String("AB"); 라고 작성해야하지만,  문자열은 워낙 자주 사용하다 보니 자바에서

String str = "AB"; 라고 작성할 수 있도록 허용되었다.

 

String s1 = "AB"에서

참조변수 s1에는 문자열 "AB"의 주소가 저장된다.

 

그런데, 어떤 것들을 "문자열"이라고 할까? 아래를 살펴보자.

 

String s= "ABC"; // 연속된 여러문자

String s = "A"; // 하나의 문자.

String s = ""; // 빈 문자열  

 

모두 문자열에 해당된다.(주의! char ch = '';와 같이 작은 따옴표로는 표현할 수 없다.)

 

String s = "A" + "B"; // 문자열을 이어붙인다. 따라서, 변수 s에 "AB"가 저된다.

이때, 숫자와 문자열의 결합을 살펴보면,

""(String) + 7(int) -> "" + "7" -> "7" // 숫자와 문자열의 결합시 숫자가 문자열로 변환된다.

 

숫자뿐만 아니라, 문자열과 어떤 type을 결합하면 그 type은 문자열이 되고, 결합 결과도 문자열이다.

(문자열 + 어떤 타입 = 문자열)

 

문자열의 결합시 순서가 존재한다. 즉, 왼쪽에서 오른쪽방향으로 결합이 되는 것.

1. "" + 7 + 7 -> "7" + 7 -> "7" + "7" -> "77"

2. 7 + 7 + "" -> 14+ "" -> "14" + "" -> "14"

 

 

 

 

 

'Java > 자바의 정석 정리' 카테고리의 다른 글

Data Type(값의 타입)  (0) 2023.01.17
변수, 상수, 리터럴  (2) 2023.01.04
변수(variable)  (0) 2023.01.03
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
package String;
 
public class String1 {
    public static void main(String[] args) {
        String s = "I like Java and Python and C.";
        System.out.println(s);
 
        // 문자열의 길이
        System.out.println(s.length()); // 29
 
        // 대소문자 변환
        System.out.println(s.toUpperCase()); // 대문자로
        System.out.println(s.toLowerCase()); // 소문자로
 
        // 포함 관계
        System.out.println(s.contains("Java")); // 포함된다면 true 포함되지 않는다면 false
        System.out.println(s.contains("C++"));
        // 위치 정보(맨 앞이 0부터 시작), Java 중 맨 앞 J는 7번째에 있다.
        System.out.println(s.indexOf("Java")); // 7
        System.out.println(s.indexOf("C#")); // 포함되지 않는 문자열이므로 -1 나온다.
        // 문자열의 마지막 글자의 위치 정보, and의 d의 위치
        System.out.println(s.lastIndexOf("and")); // 23
        // 특정한 문자열로 시작하는 지 확인
        System.out.println(s.startsWith("I like")); // 이 문자열로 시작하면 true
        System.out.println(s.endsWith(".")); // 이 문자열로 끝나면 true
 
    }
}
 
cs

 

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
package String;
 
public class String2 {
    public static void main(String[] args) {
        String s = "I like Java and Python and C.";
 
        // 문자열 변환
 
        // 위 문장을 "I like Java, Python, C."로 바꿔서 나타내고 싶다.
        System.out.println(s.replace(" and"", "));
        System.out.println(s); // 원래 문자열의 변화는 없음 // I like Java and Python and C.
 
        // 원래 문자열을 원하는 문자열로 바꿔놓으려면,
        s = s.replace(" and"", ");
        System.out.println(s); // I like Java,  Python,  C.
 
        s = "I like Java and Python and C."// 다시 원래대로
 
        // 문자열을 원하는 부분만 출력하고 싶을 때
        System.out.println(s.substring(7)); // 인덱스 7부터 시작해서 끝까지 출력(이전 내용은 제외)
        // 인덱스 번호를 모르는 경우가 많으므로
        System.out.println(s.substring(s.indexOf("Java")));
        // 결과: Java and Python and C.
        // 시작과 끝을 정해서 원하는 부분만 출력하고 싶을 때
        System.out.println(s.substring(s.indexOf("Java"), s.indexOf(".")));
        // 이때, substring(시작 인덱스, (끝+1) 인덱스) 임을 주의하자.
        // 즉, 끝 위치에 나타난 인덱스 바로 전의 인덱스에 해당하는 값이 출력된다.
        // 따라서, Java and Python and C 이 출력된다.
 
        System.out.println(s); // 원래 문자열의 변화는 없음 // I like Java and Python and C.
 
        // 원래 문자열을 원하는 문자열로 바꿔놓으려면,
        s = s.substring(7);
        System.out.println(s); // Java and Python and C.
 
        // 공백 제거
        s = "            I love Java.           ";
        System.out.println(s);
        System.out.println(s.trim()); // 앞뒤 공백 제거
 
        // 문자열 결합
        String s1 = "Java";
        String s2 = "Python";
        System.out.println(s1 + s2); // JavaPython
        System.out.println(s1 + "," + s2); // Java,Python
        System.out.println(s1.concat(",").concat(s2)); // Java,Python
 
 
    }
}
 
cs

 

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
package String;
 
public class StringCompare {
    public static void main(String[] args) {
 
        // 문자열 비교
        String s1 = "Java";
        String s2 = "Python";
 
        System.out.println(s1.equals(s2)); // 문자열 내용이 같으면 true, 다르면 false // false
        System.out.println(s1.equals("Java")); // true
 
        System.out.println(s2.equals("python")); // 대소문자 구분하므로 false
        // 대소문자 구분없이 내용이 같으면 true를 나타내게 하고 싶다면?
        System.out.println(s2.equalsIgnoreCase("python"));
 
        // 문자열 비교 심화
        s1 = "1234";
        s2 = "1234";
        // 문자열 변수 s1, s2 모두 한 메모리 공간에 존재하는 "1234"를 참조한다.
        System.out.println(s1.equals(s2)); // true // 참조하고 있는 메모리 공간의 내용을 비교
        System.out.println(s1 == s2); // true // 변수 각각이 참조하고 있는 것이 같은지를 비교
 
        s1 = new String("1234");
        s2 = new String("1234");
        // 문자열 변수 s1, s2 각각 다른 메모리 공간에 존재하는 "1234"를 참조한다.
        System.out.println(s1.equals(s2)); // true // 참조하고 있는 메모리 공간의 내용이 같으므로
        System.out.println(s1 == s2); // false // 변수 각각이 참조하고 있는 것이 다르므로
 
        // 따라서 Java에서 문자열의 내용을 비교하고 싶으면 equals를 써라!!
 
    }
}
 
cs
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
import java.util.Arrays;
 
public class Lotto {
    public static void main(String[] args) {
        //정수 6개를 저장할 배열 선언
        int[] num = new int[6];
        //1 ~ 45 사이의 중복되지 않은 6개의 정수 입력
        //Math.random()은 0이상 1미만의 double 출력
        //따라서 1 ~ 45 를 출력하기 위해 45를 곱한후 int로 형변환 후 +1
        //중복된 값이 있는지 비교할 때, 자기 자신을 제외하고 그 앞의 값들과 비교(이 부분이 j<i)
        //중복된 값이 존재한다면, i--를 통해 i를 하나 줄이고, 다시 난수를 받도록 한다.
        for (int i = 0; i < num.length; i++) {
            num[i] = (int)(Math.random()*45+ 1;
            for (int j = 0; j < i; j++) { 
                if(num[i] == num[j]) {
                    i--
                }
            }
        }
        System.out.println(Arrays.toString(num));
        
        //오름차순 정렬
        for (int i = 0; i < num.length - 1; i++) {
            for (int j = i+1; j < num.length; j++) {
                if(num[i] > num[j]) {
                    int tmp = num[j];
                    num[j] = num[i];
                    num[i] = tmp;
                }
            }
        }
        System.out.println(Arrays.toString(num));
        
    }
}
 
cs

Theme. 변수, 상수, 리터럴의 구분

변수(variable): 하나의 값을 저장하기 위한 공간

상수(constant): 한 번만 값을 저장할 수 있는 변수

리터럴(literal): 그 자체로 값을 의미하는 것

일반적으로 우리가 아는 상수가 자바에서는 리터럴을 의미하는데, 보다 확실한 구분을 위해 아래 예를 살펴보자.

색을 달리하여 구분해보자면, 변수 / 상수 / 리터럴 

 

int score = 100;

     score = 200;

final int MAX = 100;  //final을 붙여서 상수임을 나타냄

             MAX = 200; // 에러 발생

char ch = 'A';

String str = "abc";

 

Theme. 리터럴의 접두사와 접미사

종류 리터럴 접미사
논리형 false, true 없음
정수형 123, 0b0101, 077, 0xFF, 100L L(long을 의미)
실수형 3.14, 3.0e8, 1.4f, 0x1.0p-1 f(float), d(double, 생략가능)
문자형 작은 따옴표 안, 'A', '1', '\n' 없음
문자열 큰 따옴표 안 "ABC", "123", "A" 없음

추가적인 설명을 하자면, 

변수에 값을 저장하기 위해서 변수의 타입과 리터럴의 타입을 일치시켜야 하고,

 

byte b = 127;

byte b = 128; //에러

왜냐하면, byte는 -127 ~ 128의 리터럴만 변수에 저장할 수 있다.

 

0b0101에서 앞의 "0b"는 2진 접두사로 이진수를 나타낼 때 사용한다.

같은 논의로

0100에서 맨앞 '0'은 8진수를,

0x100에서 앞의 "0x"는 16진수를 나타낼 때 사용한다.

 

long l = 10_000_000_000L; // 100억은 long 타입의 리터럴로 반드시 뒤에 L을 붙여줘야 한다.

int는 20억까지 가능하므로 int l = 10_000_000_000은 불가능하다.

float f = 3.14f; // f 생략 불가능

double d = 3.14d; // d 생략 가능

즉, 리터럴이 실수형인데 f가 안붙으면 double로 간주하게 된다.

아래 리터럴들의 타입에 대해 알아보자

10. - > 10.0

.10 - > 0.10

둘다 double

10f - > 10.0f로 float

1e3 - > e는 10^n을 의미하고, 즉 1 * 10^3이므로 1000.0을 의미(double타입)

 

Theme. 변수와 리터럴의 타입 불일치

변수는 그릇, 리터럴은 물건처럼 생각해보자

 

1. 범위가 "변수  >  리터럴"인 경우, 가능!

int i = 'A'; // 변수(int) > 리터럴(char), ASCII 코드와 관련있는데, A의 ASCII 코드 값은 65다.

long l = 123; // 변수(long) > 리터럴(int)

double d = 3.14f; // 변수(double) 리터럴(float)

 

2. 범위가 "변수  <  리터럴"인 경우, 에러 발생

int i = 30_0000_0000; // int의 범위 (-20억 ~ 20억) 벗어남

long l = 3.14f; // long이 8byte이고, float가 4byte이지만, 실수형이 정수형보다 저장범위가 커서 에러 발생

float f = 3.14; // 3.14는 double이므로 float < double이어서 에러 발생

'Java > 자바의 정석 정리' 카테고리의 다른 글

Data Type(값의 타입)  (0) 2023.01.17
문자와 문자열  (0) 2023.01.16
변수(variable)  (0) 2023.01.03

Theme. 변수란?

하나의 값을 저장할 수 있는 메모리 공간(메모리 공간은 RAM을 의미한다)

 

전체 메모리 공간을 1byte 단위로 나누고, 각각의 저장공간에 0,1,2,3,4.. 처럼 연속된 번호를 붙여준다. 이를 메모리 주소라고 한다.

원래는 메모리에 값을 저장할 때 메모리 주소를 이용해야 하지만, 메모리 주소가 복잡하여 사람이 이용하기 불편하다.

따라서, 특정 메모리 영역에 이름을 붙이고 주소 대신에 이름을 통해 메모리에 값을 저장하고, 읽을 수 있게 하는 것이 변수다.

변수는 하나의 값만 저장할 수 있기 때문에 변수에 새로운 값을 저장하면 기존의 값은 지워지고 새로 저장한 값만 남게 된다.

 

Theme. 변수의 선언

메모리에 값을 저장하려면 먼저 변수를 선언해야 한다.

즉, 값(data)를 저장할 공간을 마련하기 위해 변수를 선언하는 것이다.

변수를 선언하는 방법: 변수타입 변수이름;

예) int age; // 정수(int)타입의 변수 age를 선언

그 결과 아래와 같은 age라는 이름의 저장공간이 생기게 된다.

 

Theme. 변수에 값 저장하기

1. 변수에 값 저장하기

int age; //정수(int)타입의 변수 age를 선언

age = 25; //변수 age에 25를 저장

혹은 int age = 25;

이때, '='는 등호가 아니라 '=' 오른쪽 값을 왼쪽 변수에 대입하는 대입연산자이다.

2. 변수의 초기화

변수에 처음으로 값을 저장하는 것을 말한다.

int x = 0; // 변수 x를 선언 후, 0으로 초기화

int y = 5; // 변수 y를 선언 후, 0으로 초기화

혹은 int x = 0, y = 0;

변수의 종류로 클래스 변수, 인스턴스 변수, 지역변수가 있는데, 

클래스변수, 인스턴스 변수는 자동으로 초기화되지만, 지역변수는 그렇지 않으므로

지역 변수는 읽기 전에 반드시 초기화를 해줘야 한다.

 

Theme. 변수의 타입

변수의 타입은 저장할 값의 타입에 의해 결정된다.

저장할 값의 타입과 알치하는 타입으로 변수를 선언해야 한다.

char ch = '가';

double pi = 3.14;

 

데이터의 기본형(기본 타입)

값을 크게 문자, 숫자, 논리형(true/false)으로 나누었을 때, 

문자 - char

숫자 - 정수( byte, short, int, long), 실수(float, double)

논리 - boolean

변수를 선언할 때 이중 적합한 타입을 선택하여 선언한다.

 

 

 

 

'Java > 자바의 정석 정리' 카테고리의 다른 글

Data Type(값의 타입)  (0) 2023.01.17
문자와 문자열  (0) 2023.01.16
변수, 상수, 리터럴  (2) 2023.01.04

CRUD 기능이 포함된 주소록을 List를 이용하여 만들어보자.

먼저, 간단한 용어 정리를 하자면,

 

CRUD: 기본적인 데이터 처리 기능인 Create(생성, 추가), Read((읽기, 검색), Update(갱신, 수정) Delete(삭제)를 말한다.

DAO: DAO(Data Access Object) 는 데이터베이스의 data에 접근하기 위한 객체이다. DataBase에 접근 하기 위한 로직 & 비지니스 로직을 분리하기 위해 사용한다.

DTO: DTO(Data Transfer Object) 는 계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체(getter & setter 만 가진 클래스)이다.

 

본 프로그램은 4개의 클래스를 통해 구성하였다.

1. MainClass

2. AddressDao

3. HumanDto

4. FileProc

 

전체적인 프로그램 실행 과정은 마지막에 설명하도록 하고,

먼저 각각의 클래스에 대한 설명과 코드를 나타내보자.

 

Theme. 각 클래스에 대한 설명 및 작성된 코드

 

1. MainClass

주소록의 menu 역할을 하는 클래스로 AddressDAO 클래스의 인스턴스를 통해 메서드를 호출하여 사용자가 원하는 메뉴를 선택하면 그에 따른 실행, 결과 출력 등을 하도록 한다.

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
package main;
 
import java.util.Scanner;
 
import dao.AddressDao;
 
public class MainClass {
 
    public static void main(String[] args)  {
        
        Scanner sc = new Scanner(System.in);
        
        AddressDao dao = new AddressDao();
        
        boolean end = false;
        
        // menu
        out:while(true) {
            
            System.out.println(" << 주소록 >> ");
            System.out.println("1. 지인추가");
            System.out.println("2. 지인삭제");
            System.out.println("3. 지인검색");
            System.out.println("4. 지인수정");
            System.out.println("5. 모두출력");
            System.out.println("6. 데이터저장");
            System.out.println("7. 종료");
            
            System.out.print(">> ");
            int choice = sc.nextInt();
            
            switch(choice) {
                case 1:
                    dao.insert();
                    break;
                case 2:
                    dao.delete();
                    break;
                case 3:
                    dao.select();
                    break;
                case 4:
                    dao.update();
                    break;
                case 5:
                    dao.allDataPrint();
                    break;
                case 6:    
                    dao.filesave();
                    break;
                case 7:        
                    end = true;                    
                    //System.exit(0);        // 강제종료
                    break out;
                default:
                    
            }
                    
            /*
            if(end) {
                System.out.println("프로그램을 종료합니다");
                break;
            }
            */
                        
        }
 
    }
 
}
 
 
 
 
 
cs

 

2. AddressDAO

CRUD 기능을 나타낼 메서드를 정의하는 것을 중심으로 FileProc 클래스와의 데이터 저장, 불러오기 기능을 나타낸다.

HumanDto 클래스로부터 각 사람에 대한 데이터를 가져와 실행한다.

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
package dao;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
 
import data.FileProc;
import dto.HumanDto;
 
public class AddressDao {
    
    Scanner sc = new Scanner(System.in);
 
    private List<HumanDto> list = new ArrayList<HumanDto>();
    
    private int count;
    
    private FileProc fileProc = null;  // composition(합성)
    
    public AddressDao() {
    
        fileProc = new FileProc("address");
        
        fileload();
    
    }
        
    public void insert() {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("지인을 추가합니다");
        
        System.out.print("이름 = ");
        String name = sc.next();
        
        System.out.print("나이 = ");
        int age = sc.nextInt();
        
        System.out.print("전화번호 = ");
        String phone = sc.next();
        
        System.out.print("주소 = ");
        String address = "";
        try {
            address = br.readLine(); 
        } catch (IOException e) {            
            e.printStackTrace();
        }
        
        System.out.print("메모 = ");
        String memo = sc.next();
            
        HumanDto dto = new HumanDto(name, age, phone, address, memo);
        list.add(dto);
    }
    
    public void delete() {
                
        System.out.print("삭제할 지인의 이름 = ");
        String name = sc.next();
        
        // 검색
        int index = search(name);
        
        if(index == -1) {
            System.out.println("지인의 정보를 찾을 수 없습니다");
        }
        else {            
            // 삭제
        
            list.remove(index);
            
            System.out.println("지정한 지인을 삭제하였습니다");
        }
    }
    
    public void select() { // 동명이인을 찾는다
        // 검색
        System.out.print("검색할 지인의 이름 = ");
        String name = sc.next();
    
        
        for (HumanDto h : list) {
            if(name.equals(h.getName())) {
                System.out.println(h.toString());
            }
        }        
    }
    
    public void update() {
        System.out.print("수정할 지인의 이름 = ");
        String name = sc.next();
        // 검색
        int index = search(name);        
        if(index == -1) {
            System.out.println("지인의 정보를 찾을 수 없습니다");
            return;
        }
        
        // 수정
        // phone
        // address
        System.out.println("데이터를 찾았습니다");
        System.out.print("전화번호 = ");
        String phone = sc.next();
        
        System.out.print("주소 = ");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String address = "";
        try {
            address = br.readLine(); 
        } catch (IOException e) {            
            e.printStackTrace();
        }
        
        list.get(index).setPhone(phone);
        list.get(index).setAddress(address);
        
        System.out.println("정상적으로 수정되었습니다");
    }
    
    
    public int search(String name) {
        int index = -1;
        for (int i = 0; i < list.size(); i++) {
            HumanDto h = list.get(i);
            if(name.equals(h.getName())) {
                index = i;
                break;
            }
        }
        return index;
    }
        
    public void allDataPrint() {
        
        for (HumanDto humanDto : list) {
            System.out.println(humanDto.toString());
        }
        
    }    
    
    
    public void filesave() {
        String dataArr[] = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            dataArr[i] = list.get(i).toString();
        }        
        
        fileProc.write(dataArr);
        
    }
    
    public void fileload() {
        
        String datas[] = fileProc.read();
    
        for (int i = 0; i < datas.length; i++) {
        
            String split[] = datas[i].split(":");
            
            HumanDto h = new HumanDto(    split[0], 
                                        Integer.parseInt(split[1]), 
                                        split[2],         
                                        split[3], 
                                        split[4] );            
            list.add(h);
        }
    }
}
 
 
 
 
 
 
 
 
 
 
 
 
 
cs

3. HumanDto

주소록에서 한 사람에 대한 데이터를 담는 클래스로 이름, 나이, 전화번호, 주소, 메모 등에 대한 항목이 존재한다.

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
package dto;
 
public class HumanDto {
 
    // 이름, 나이, 전화번호, 주소, 메모
    private String name;
    private int age;
    private String phone;
    private String address;
    private String memo;
    
    public HumanDto() {
    }
 
    public HumanDto(String name, int age, String phone, String address, String memo) {
        this.name = name;
        this.age = age;
        this.phone = phone;
        this.address = address;
        this.memo = memo;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public String getPhone() {
        return phone;
    }
 
    public void setPhone(String phone) {
        this.phone = phone;
    }
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        this.address = address;
    }
 
    public String getMemo() {
        return memo;
    }
 
    public void setMemo(String memo) {
        this.memo = memo;
    }
 
    @Override
    public String toString() {
        return name + ":" + age + ":" + phone + ":" + address + ":" + memo;
    }
    
}
 
 
 
 
 
 
cs

4. FileProc

컴퓨터 C드라이브에 파일을 생성하고, 이에 데이터를 저장하고 읽어오는 기능을 AddressDao 클래스와 함께 수행한다.

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
package data;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Stack;
 
public class FileProc {
 
    // 파일 쓰기, 읽기
    private File file = null;
    
    public FileProc(String filename) {
        file = new File("c:\\tmp\\" + filename + ".txt");
        
        // 실제 파일이 생성되는 부분
        try {
            if(file.createNewFile()) {
                System.out.println("파일 생성 성공!");
            }else {
                System.out.println("기존의 파일이 있습니다");
            }
        } catch (IOException e) {            
            e.printStackTrace();
        }
    }
    
    public String[] read() {    
        
        String datas[] = null;
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            
            // 데이터의 총 개수를 구한다
            int count = 0;
            String str = "";
            while((str = br.readLine()) != null) {
                count++;
            }
            br.close();
            
            // 배열 할당
            datas = new String[count];            
            
            // 파일로부터 배열에 저장
            br = new BufferedReader(new FileReader(file));
            
            int w = 0;
            while((str = br.readLine()) != null) {
                datas[w] = str;
                w++;
            }
            br.close();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {            
            e.printStackTrace();
        }
        
        return datas;
    }
    
    public void write(String datas[]) {
        
        try {
            PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            
            for (int i = 0; i < datas.length; i++) {
                pw.println(datas[i]);
            }
            
            pw.close();
            
        } catch (IOException e) {            
            e.printStackTrace();
        }    
        
        System.out.println("파일에 저장되었습니다");
    }
    
    
}
 
cs

 

 

Theme. 작성된 프로그램의 실행

1. 지인추가(Create)

주소록에 4명이 지인을 추가해보도록 한다.

처음 프로그램을 실행하면 나타나는 콘솔모습

지인 추가한 결과를 보면,

이를 파일에 저장하고, 저장이 올바르게 되었는지 확인해보자.

파일에도 올바르게 저장된 모습

 

2. 지인 검색(Read)

3. 지인 수정(Update)

진도준의 주소가 수정되었다.

 

4. 지인 삭제(Delete)

 

진양철이 삭제되었다.

 

5. 데이터를 저장하고 txt 파일을 확인해보자.

수정된 내용이 잘 저장되었다.

Theme. 참조변수 super

 

객체 자신을 가리키는 참조변수.

인스턴스 메서드나 생성자 내에만 존재 ( static 메서드 내에서 사용불가 )

조상의 멤버를 자신의 멤버와 구별할 때 사용

 

cf) 참조변수 super vs this

super: 조상멤버, 자신멤버 구별

this: lv와 iv 구별

 

아래 코드를 살펴보자

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
package test;
 
class Parent {
    int x = 10;
    // super.x 지만 super.이 생략된 것
}
 
class Child extends Parent {
    int x = 20;
    // this.x 지만 this.이 생략된 것
    
    void method() {
        System.out.println("x = " + x); //가장 가까운 x는 this.x이므로 20이 출력됨
        System.out.println("this.x = " + this.x);
        System.out.println("super.x = " + super.x);
    }
    
}
 
public class MainClass {
 
    public static void main(String[] args) {
        Child c  = new Child();
        c.method();
        
    }
 
}
 
cs

 

Theme. 생성자 super()

 

super()는 조상의 생성자이다.

즉, 조상의 생성자를 호출할 때 사용한다.

조상의 멤버를 조상의 생성자를 호출해서 초기화할 수 있다.

( 상속 시 조상의 생성자, 초기화 블럭은 상속되지 않는다.)

 

아래 코드를 살펴보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//2차원 좌표를 나타내는 Point 클래스
class Point {
    int x;
    int y;
    //생성자
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
//Point 클래스를 부모 클래스로 상속 받는 자녀 클래스 Point3D
//3차원 좌표를 나타내는 Point3D 클래스
class Point3D extends Point {
    int z;
    //생성자
    Point3D (int x, int y, int z) {
        //this.x = x; --- X
        //this.y = y; --- X
        super(x, y); // 조상클래스의 생성자 Point(int x, int y)를 호출
        this.z = z; //자신의 멤버는 this로 초기화
    }
}
cs

 

 

'Java' 카테고리의 다른 글

BufferedReader vs Scanner, BufferedWriter vs System.out.println() (백준 15552번: 빠른 A+B)  (0) 2023.01.18
String - Java  (0) 2023.01.15
오버라이딩(overriding)  (2) 2022.12.30
생성자(constructor)  (0) 2022.12.30
파일(File)  (0) 2022.12.27

오버라이딩이란, 상속받은 조상의 메서드를 자신에 맞게 변경하는 것이다.

엄밀히 말하면, (메서드) 오버라이딩이라고 할 수 있다.

아래 예시를 통해 먼저 살펴보자

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 test;
 
//2차원 좌표를 나타내는 Point 클래스
class Point {
    int x;
    int y;
    
    //메서드
    String getLocation() {
        return "x: " + x + ", y: " + "y";
    }
    
}
 
//Point 클래스를 부모 클래스로 상속 받는 자녀 클래스 Point3D
//3차원 좌표를 나타내는 Point3D 클래스
 
class Point3D extends Point {
    int z;
    
    //메서드(오버라이딩) - 메서드의 선언부는 변경 불가, 구현부(내용)만 변경가능
    String getLocation() { //선언부는 변경되지 않음(getLocation)
        return "x: " + x + ", y: " + "y" + ", z: " + "z";
    }
    
}
 
public class MainClass {
 
    public static void main(String[] args) {
        
        Point p = new Point();
        p.x = 1;
        p.y = 2;
        System.out.println(p.getLocation());
        
        Point3D p3 = new Point3D();
        p3.z = 3;
        System.out.println(p3.getLocation());
    }
 
}
 
 
 
 
 
 
cs

결과는

x: 1, y: y
x: 0, y: y, z: z 이다.

 

Theme. 오버라이딩의 조건

 

1. 선언부가 조상 클래스의 메서드와 일치해야 한다.

 

2. 접근 제어자(public, private, protected)를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다. 

 

3. 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다. 

 

cf) 오버로딩 vs 오버라이딩

오버로딩: 기존에 없는 새로운 메서드(메서드 이름은 같은)를 정의하는 것(new)

오버라이딩: 상속받은 메서드의 내용을 변경하는 것(change, modify)

'Java' 카테고리의 다른 글

String - Java  (0) 2023.01.15
참조변수 super, 생성자 super()  (0) 2022.12.31
생성자(constructor)  (0) 2022.12.30
파일(File)  (0) 2022.12.27
날짜와 시간(Calendar class)  (2) 2022.12.26

Theme. 생성자(constructor)

 

1. 생성자란?

 

생성자는 인스턴스가 생성될 때마다 호출되는 '인스턴스(객체) 초기화 메서드'이다.

객체는 iv(instance variable)의 묶음이므로 , 생성자는 결국 iv 초기화의 역할을 한다.

(물론, 생성자도 매서드이므로 { }안에 수행할 작업을 나타내는 코드를 작성할 수 있다.)

"iv 초기화"란 뭘까?

아래 코드를 보자.

1
2
3
4
5
6
7
8
 
Time t = new Time(); //t라는 인스턴스를 생성
 
//iv 초기화 -> 12시 34분 56
t.hour = 12;
t.minute = 34;
t.second = 56;
 
cs

즉, 만들어진 객체의 변수들에 원하는 값을 넣어놓은 것을 말한다.

 

위 코드는 생성자를 통해 

Time t = new Time(12, 34, 56); 와 같이 나타낼 수 있는데,

이때 "Time()"과 "Time(12, 34, 56)" 부분이 생성자가 호출된 부분이다.

 

생성자를 호출(사용)하기 위해서는 생성자를 추가해놔야 한다.

 

2. 생성자의 조건

 1) 생성자의 이름은 클래스의 이름과 같아야 한다.

 2) 생성자는 리턴 값이 없다.

 3) 모든 클래스는 반드시 한 개 이상의 생성자를 가져야 한다.

 

추가 조건!

모든 생성자는 첫 줄에 다른 생성자를 호출해야 한다.

예를 들어, super(); 을 통해 Object 생성자를 호출하는 방법이 있다.

 

 

 1) 생성자의 이름은 클래스의 이름과 같아야 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Card {
 
    //기본 생성자(매개변수 없는 생성자)
    Card() {
 
    //인스턴스 초기화 작업
 
    }
 
    //매개변수 있는 생성자
    Card(String str, int number) {
 
    //인스턴스 초기화 작업
 
    }
 
}
cs

클래스이름: Card

이때, 두 생성자는 오버로딩이다.

생성자의 형식은 다음과 같다.

 

1
2
3
4
5
6
7
8
// 생성자 형식
 
클래스 이름(타입 변수명, 타입 변수명, ...) {
 
    인스턴스 생성시 수행될 코드,
    인스턴스 변수의 초기화 
 
}
cs

2) 생성자는 리턴 값이 없다.

 따라서, void를 안 붙인다.

 

3. 생성자의 종류

 1) 기본 생성자(매개변수가 없는 생성자)

  형식: 클래스이름() { }

  기본 생성자 또한 직접 코드를 작성하여 추가해줘야 하지만, 클래스에 생성자가 하나도 없을 때에는 컴파일러가 자동으로 추가해준다.

 따라서, 클래스를 만들면 반드시 기본 생성자를 넣어주는 것을 습관화해야 한다!

 

 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
38
39
40
41
42
43
44
45
46
package test;
 
class Car {
    
    //iv(instance variable = 멤버변수)
    String color;    // 색상
    String gearType; // 변속기 종류(auto, manual)
    int door;        // 문의 개수
    
    //기본 생성자
    Car() {}
 
    //매개변수가 있는 생성자
    Car(String c, String g, int d) {
        //iv
        color = c;
        gearType = g;
        door = d;
    }
    
}
 
public class MainClass {
 
    public static void main(String[] args) {
        // 매개변수가 있는 생성자를 이용한 객체 생성 및 초기화
        Car c = new Car("white""auto"4);
        // 기본 생성자를 이용한 객체 생성 및 초기화
        Car c = new Car(); //객체 생성
        //iv 초기화
        c.color = "white";
        c.gearType = "auto";
        c.door = 4;
        
    }
 
}
 
 
 
 
 
 
 
 
 
cs
실행되는 순서를 설명하면, 다음과 같다.

Car c: 참조변수 c를 생성

new: new 연산자가 객체 생성

Car("white", "auto", 4): 생성자를 호출하여, 객체 초기화

=: 객체가 참조변수 c에 저장

 

 3) 생성자 this()

  생성자에서 같은 클래스에 있는 다른 생성자를 호출할 때 사용

  이때, 다른 생성자 호출 시 첫 줄에서만 사용 가능

  코드의 중복을 제거하기 위해 사용

  아래 코드를 보면 모두 Car 클래스(같은 클래스)에 있고, 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
class Car {
    
    //iv(instance variable = 멤버변수)
    String color;    // 색상
    String gearType; // 변속기 종류(auto, manual)
    int door;        // 문의 개수
    
    //기본 생성자
    Car() {
        this("white""auto"4); //Car(String c, String g, int d)를 호출
    }
    //매개변수가 있는 생성자
    Car(String c) {
        this(c, "auto"4); //Car(String c, String g, int d)를 호출
    }
    //매개변수가 있는 생성자
    Car(String c, String g, int d) {
        //iv
        this.color = c;
        this.gearType = g;
        this.door = d;
    }
    
}
cs
ㅇㅇ

주의!!

생성자 this()와 참조변수 this는 전혀 연관이 없고, 다른 것이다!!

그렇다면, 참조변수 this란 무엇일까?

 

cf) 참조변수 this

 

인스턴스 자신을 가리키는 참조변수

인스턴스 매서드(생성자 포함)에서 사용가능

지역변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//매개변수가 있는 생성자
Car(String c, String g, int d) {
    //color는 iv, c는 lv
    color = c;
    gearType = g;
    door = d;
}
 
//this를 통해 지역변수와 인스턴스 변수 구별
Car(String color, String gearType, int door) {
    //this.iv = lv; 형태
    this.color = color;
    this.gearType = gearType;
    this.door = door;
}
cs

'Java' 카테고리의 다른 글

참조변수 super, 생성자 super()  (0) 2022.12.31
오버라이딩(overriding)  (2) 2022.12.30
파일(File)  (0) 2022.12.27
날짜와 시간(Calendar class)  (2) 2022.12.26
정렬(Sorting) - 오름차순, 내림차순  (0) 2022.12.26
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
package test;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;    
 
public class Practice {
 
    public static void main(String[] args) {
    
    /*    
    file: 저장매체 ==> 기능
          Database
          기록(쓰기), 불러오기(읽기) 
          기록(쓰기) - 추가
          불러오기(읽기) - 검색
            
        *.txt: 모든 파일들의 원초적인 확장자
        
        // 확장자명의 변화: *.txt -> dll, lib, jar
            dll(dynamic link library) -> 동적 파일
            lib(library) -> 정적 파일
            
            동적 파일은 메모리 절약 효과가 있다.
            정적 파일은 보안의 장점이 있다.
                
     */    
        
    File file = new File("c:\\");    
    
    //파일을 조사
    String[] filelist = file.list();
    for (int i = 0; i < filelist.length; i++) {
        System.out.println(filelist[i]);
    }    
        
    }
 
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
// 파일과 폴더를 구분해서 조사
    File[] filelist = file.listFiles();
    for (int i = 0; i < filelist.length; i++) {
        if(filelist[i].isFile()) {
            System.out.println("[파일] " + filelist[i].getName());
        } else if(filelist[i].isDirectory()) {
            System.out.println("[폴더] " + filelist[i].getName());
        } else {
            System.out.println("[?] " + filelist[i].getName());
        }
    }
cs
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
package test;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;    
 
public class Practice {
 
    public static void main(String[] args) {
    
    
    File file = new File("c:\\");    
    
    // 파일을 생성
        File newfile = new File("c:\\tmp\\newfile.txt"); //파일을 생성할 준비
        
        
            
        try {
            if(newfile.createNewFile()) {
                System.out.println("파일 생성 성공!");
            } else {
                System.out.println("파일 생성 실패!");
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
        
    // 파일의 존재 여부
        if(newfile.exists()) {
            System.out.println("파일이 존재합니다");
        } else {
            System.out.println("파일이 존재하지 않습니다");
        }    
 
    // 읽기전용
        newfile.setReadOnly();
    
    // 삭제
        newfile.delete();
        
    
    
    }
 
}
 
cs

 

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
package test;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;    
 
public class Practice {
 
    public static void main(String[] args) {
    
    // (문자열)쓰기
    File f = new File("c:\\tmp\\iofile.txt");
    
    
    
    try {
        
    /*    
    //쓰기
    FileWriter fwriter = new FileWriter(f);
    fwriter.write("안녕하세요");
    fwriter.write(" Hello");
    fwriter.close();
    */
 
    /*
    // 추가쓰기    
    FileWriter fwriter = new FileWriter(f, true);
    fwriter.write("반갑습니다");            
    fwriter.close();
    */    
        
    /*
    PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(f)));
    pw.println("hi");
    pw.print("헬로우");
    pw.println("world");
    pw.close();
    */
        
    // (문자열)읽기
    // 한글자씩 읽기
    /*
    FileReader fr = new FileReader(f);
    int ch = fr.read();
    while(ch != -1) {
        System.out.print((char)ch);
        ch = fr.read();
    }
    */
 
    // 문장으로 읽기
    
    BufferedReader br = new BufferedReader(new FileReader(f));
    
    String str = "";
    while((str = br.readLine()) != null) {
        System.out.println(str);
    }
    
    br.close();    
    
    } catch (IOException e) {            
        e.printStackTrace();
    }
    
    
    
    }
 
}
 
cs

'Java' 카테고리의 다른 글

오버라이딩(overriding)  (2) 2022.12.30
생성자(constructor)  (0) 2022.12.30
날짜와 시간(Calendar class)  (2) 2022.12.26
정렬(Sorting) - 오름차순, 내림차순  (0) 2022.12.26
예외(Exception) 처리  (0) 2022.12.26

+ Recent posts