클래스의 필요성
- 예를들어, 전화번호부에서 한 사람의 "이름"과 "전화번호"는 항상 같이 붙어다녀야 하는 데이터이다.
- 이 두 가지 데이터를 각각 별개의 변수에 저장하면 데이터가 변경될 때 각각 수정해줘야하는 번거로움이 있다.
- 서로 관련있는 데이터들을 하나의 단위로 묶어두면 편할 듯하다.
- 이것이 클래스라는 개념이 필요한 이유이다.
클래스 개념 및 사용법
- "사람(Person1)"이라는 클래스를 만들어 그 클래스 내에서 "이름"과 "전화번호" 변수(field, data member라고도 불림)를 저장할 수 있다.
- 클래스의 이름은 항상 대문자로 시작하는 것이 관습이다.
- 자바에서 각각의 클래스는 별개의 파일로 저장되어야 하고 파일의 이름은 클래스의 이름과 일치해야 한다. 즉 클래스 Person1은 Person1.java라는 이름의 파일로 저장해야한다.
public class Person1 {
public String name;
public String number;
}
- 클래스는 결국 하나의 "타입"이다. ex) int, double 등 처럼
- 클래스는 객체를 찍어내기 위한 하나의 설계도와 같다. 4
- 실제로 프로그램 내에서 사용되는 실체는 객체이다.
- 다만 int, double 처럼 java에서 미리 정해놓은 타입(Primitive)이 아니라 사용자가 정의한 새로운 타입이라는 의미에서 사용자 정의 타입이라고 부르기도 한다.
- int 혹은 dobule 형 변수를 선언하고 사용하는 것처럼 Person1형 변수를 선언하고 이용한다.
int [] example = new int[100];
//마치 int형 배열을 선언 및 생성하는 것처럼
Person1 first = new Person1();
아래와 위는 동일. 변수를 선언 후 생성해줘야 한다.
int [] example;
example = new int[100];
//int형 배열을 선언 및 생성하는 것처럼
Person1 first;
first = new Person1(); //first 라는 객체(object) 생성
- 위 코드처럼 Person1이라는 클래스와 new를 통해 first라는 객체를 만든다.
public class Code01 {
public static void main(String[] args) {
Person1 first;
first = new Person1();
first.name = "John";
first.number = "0511233456";
System.out.println("First is " + first.name + " with number " + first.number);
}
}
- Person1이라는 클래스 내의 name과 number는 생성한 객체이름.name과 생성한 객체이름.number로 접근한다.
*프리미티브(Primitive) 타입의 종류- 기본 타입이라고도 말한다.
C vs Java
클래스 객체 배열
public class Code01 {
public static void main(String[] args) {
Person1 first;
first = new Person1();
first.name = "John";
first.number = "0511233456";
System.out.println("First is " + first.name + " with number " + first.number);
Person1 [] members = new Person1 [100];
members[0] = first;
members[1] = new Person1();
members[1].name = "David";
members[1].number = "024343432";
System.out.println("Second is " + members[1].name + " with number " + members[1].number);
}
}
- 위 코드와 같이 클래스를 이용해서 객체 배열을 만들 수도 있다.
프리미티브 타입과 클래스(사용자 정의 타입)의 차이점
int count = 0;
Person1 first = new Person1();
- count라는 이름의 변수가 만들어지고 그 안에 정수값 0이 저장 됨.
- 반면, first라는 이름의 변수는 만들어지지만, 그 안에 사람 이름과 전화번호가 저장되는 것은 아니다.
- new 명령어로 객체를 생성한다.
- first에는 new 명렁어로 생성한 Person1 클래스(타입)의 새로운 객체의 주소가 저장되는 것이다.
- first를 참조 변수라 한다.
모든 프리미티브 타입의 변수는 보통변수이다. 즉 변수 자체에 값이 저장된다.
반면, 프리미티브 탕비이 아닌 모든 변수는 참조 변수이다.
즉 실제 데이터가 저장될 "객체"는 new 명렁으로 따로 만들어야 하고, 참조변수에는 그 객체의 주소를 저장한다.
객체의 주소 개념
public class Code01_2 {
public static void main(String[] args) {
Person1 first = new Person1();
first.name = "John";
first.number = "0511233456";
Person1 second = first;
second.name = “Tom”;
System.out.println(first.name + “, " + first.number);
}
}
- 위 코드에서 생성된 객체는 하나이다. new 명령을 한번만 사용했기 때문이다.
- Person1 클래스 타입의 second 변수에 first 값(객체 주소)를 저장 했다.
- 그러므로 second와 first는 같은 주소를 참조한다.
public class Code01_2 {
public static void main(String[] args) {
Person1 first = new Person1();
first.name = "John";
first.number = "0511233456";
Person1 second = first;
second.name = “Tom”;
System.out.println(first.name + “, " + first.number);
// 아래가 추가 설명할 부분
Person1 [] members = new Person1 [100];
members[0] = first;
members[1] = second;
System.out.println(members[0].name + “, ” + members[0].number);
System.out.println(members[1].name + “, ” + members[1].number);
}
}
- Person1 타입의 member라는 객체 배열을 만들었다.
- 각 배열의 칸에는 객체 주소값을 가지게 되는 것이다.
- 객체 배열 각 칸에 new 명령어를 통해 객체를 생성해주거나 객체 주소를 넣어줘야 한다
배열의 개념
int [] numbers = new int[8];
- 배열은 프리미티브 타입이 아니다. int, float 같은 프리미티브 타입의 배열이라고 하더라도 배열의 각 원소가 프리미티브 타입인 것이지 배열 자체가 프리미티브 타입은 아니다. 따라서 위 코드에서 배열의 이름 numbers는 참조 변수이다.
객체 배열
Person1 [] members = new Person1 [8];
- 위 코드에서 members는 배열의 이름이므로 당연히 참조 변수이다.
- 배열의 각 칸은 Person1 타입이다. 그런데 Person1은 프리미티브 타입이 아니므로 배열의 각 칸도 참조 변수이다.
- 각 칸에는 객체의 주소를 저장해주어야 한다.
- 따라서 아래 코드는 잘못되었다. (아직 객체의 주소가 저장되어 있지 않기 때문이다)
members[2].name = “John”;
members[2].number = “010232432”;
- 위 코드를 고치면 아래와 같다.
Person1 first = new Person1();
first.name = “John”; first.number = 01023456”;
Person1 [] members = new Person1 [8];
members[0] = first;
members[1] = new Person1();
members[1].name = “David"; members[1].number = "024343432";
- 배열 칸 [0] 과 [1]에는 객체의 주소가 저장되었고, 각 배열 칸을 참조해서 name과 number에 접근 가능하다.
값에 의한 호출 vs 참조에 의한 호출
public static void bubbleSort(int [] data2, int n) {
for ( int i=n-1; i>0; i--) {
for ( int j=0; j<i; j++ ) {
if (data2[j] > data2[j+1]) {
int tmp = data2[j];
data2[j] = data2[j+1];
data2[j+1] = tmp;
}
}
}
}
bubbleSort(data, count);
- 위에서 정의된 함수를 보면 매개 변수에 int 배열형 변수와, int형 변수가 필요하다.
- 앞에서 설명했듯이 배열은 프리미티브 타입이 아니라 참조 변수로 작동한다.
- 따라서 bubblesort가 호출되면 매개 변수인 data는 객체의 주소를 저장하고 있는 참조 변수이기 때문에 주소를 통해 객체에 직접 접근한다.
- 그러므로 객체의 실제 데이터값이 변경된다. "참조에 의한 호출"
- 반면, int형은 프리미티브 타입이기 때문에 복사된 값을 제공한다.
- 복사된 값을 제공했기 때문에 아무리 값이 변경되어도 원본 데이터 값은 변경되지 않는다. "값에 의한 호출"
'Computer Science > 자바' 카테고리의 다른 글
[JAVA] 객체 생성 및 사용법 (0) | 2023.03.23 |
---|---|
[JAVA] 클래스 소스파일 작성 유의점 (0) | 2023.03.23 |
[Java] 객체지향개념(요약) (0) | 2023.03.17 |
[JAVA] 다항함수 만들기 (0) | 2023.02.10 |
[JAVA] 사각형의 면적 구하기 (0) | 2023.02.10 |