[이것이 자바다] 06 클래스 - 1
1. 클래스의 두 가지 용도
-라이브러리 클래스) 실행할 수 없으며 다른 클래스에서 이용하는 클래스
-실행클래스) main()메소드를 가지고 있는 실행 가능한 클래스
-Student 클래스는 라이브러리 클래스, StudentExample클래스는 실행 클래스
-일반적으로 자바 프로그램은 하나의 실행 클래스와 여러 개의 라이브러리로 구성, 실행 클래스는 실행하면서 라이브러리 클래스를 내부에서 이용한다.
2. 필드와 로컬변수의 차이점
*** 이 부분은 교수님 수업 시간에 확실하게 이해가 된 부분이지만 그래도 정리하면서 복습하자
- 로컬 변수는 생성자와 메소드 블록에서 선언되며 생성자와 메소드 호출 시에만 생성되고 사용된다
-필드는 클래스 블록에서 선언되며, 객체 내부에서 존재하고 객체 내외부에서 사용 가능하다.
구분 | 필드 | 로컬변수 |
선언 위치 | 클래스 선언 블록 | 생성자, 메소드 선언 블록 |
존재 위치 | 객체 내부에 존재 | 생성자, 메소드 호출 시에만 존재 |
사용 위치 | 객체 내외부 어디서든 사용 가능 | 생성자, 메소드 블록 내부에서만 사용 |
*** 필드의 타입은 참조타입도 가능(배열, 클래스, 인터페이스)
3. 생성자 선언과 호출
*** 스터디 하면서 제일 이해가 어려웠던 부분이지만 다시 보니까 한 번에 이해됐음! 까먹지 말고 더 필요한 개념들이 있으면 확실하게 채우자
*** 생성자의 영어 명칭은 "constructor" , 솦프가 영어 강의여서 시험도 영어로 출제될 거고 앞으로를 위해서 알아두기
-new 연산자는 객체를 생성한 후 연이어 생성자를 호출하여 객체를 초기화하는 역할을 함, 객체 초기화란 필드 초기화를 하거나 메소드를 호출하여 객체를 사용할 준비를 하는 것을 의미.
-생성자가 성공적으로 실행이 끝나면 new 연산자는 객체의 주소를 리턴, 리턴된 주소는 클래스 변수에 대입되어 객체의 필드나 메소드 접근 시 이용한다.
- 생성자가 메소드와 다른 점은 리턴 타입에 대한 선언이 없다는 점인데, 항상 객체의 주소를 리턴타입으로 가지기 때문에 관용적인 부분에 있어 생략함.
-모든 클래스는 생성자가 존재하며 하나 이상을 가질 수 있음, 클래스에 생성자 선언이 없다면 컴파일러는 다음과 같은 기본 생성자를 바이트코드 파일에 자동으로 추가시킨다.
public class_name(){};
-객체를 다양하게 초기화하기 위해서 개발자는 생성자를 직접 선언할 수 있음
-생성자는 메소드와 비슷한 모양을 가지고 있으나 리턴 타입이 없고 클래스 이름과 동일하다.
-클래스에 개발자가 선언한 생성자가 있다면 컴파일러는 기본 생성자를 추가하지 않음, 기본 생성자를 사용하기 위해서 추가적으로 개발자가 직접 기본 생성자를 추가해주어야 함.
public class Car{
Car(String model, String color, int maxSpeed){
...}
} // 생성자 선언
public class CarExample{
public static void main(String[] args){
Car myCar = new Car("그랜저", "검정", 250);
}
} //기본 생성자 호출 시 에러
- 생성자를 이용한 초기화를 할 때, 매개변수의 이름이 너무 짧으면 코드의 가독성이 좋지 않기 때문에 가능하면 초기화 시킬 필드 명과 동일한 이름을 사용하는 것이 좋음
- 위와 같은 경우에는 매개변수명이 필드 명과 동일하기 때문에 필드임을 구분하기 위해 this 키워드를 필드명 앞에 붙여줌, this는 현재의 객체를 이야기하며, this.name은 현재 객체 데이터(필드)로서의 name을 뜻한다.
public class Korean{
String nation="대한민국";
String name;
String ssn;
public Korean(String name, String ssn){
this.name=name;
this.ssn=ssn;
}
}
-객체마다 동일한 값을 가진다면 필드 선언시 초기화를 해 주는 것 좋고, 객체마다 다른 값을 가진다면 생성자에서 필드를 초기화하는 것이 좋다.
-매개값으로 객체의 필드를 다양하게 초기화하기 위해서는 생성자 오버로딩 (Overloading)이 필요, 생성자 오버로딩이란 매개변수를 달리하는 생성자를 여러 개 선언하는 것을 이야기한다.
-매개변수의 타입과 개수, 그리고 선언된 순서가 동일하고 매개변수의 이름만 바꾸는 것은 생성자 오버로딩이 아니다.
Car(String model, String color){...}
Car(String color, String company){...} // 오버로딩이 아님, 컴파일 에러 발생
-생성자 오버로딩이 많아질 경우 생성자 간의 중복된 코드가 발생 가능, 생성자 내부의 코드 중복은 코드를 가독성이 떨어지게 함.
-이 경우 공통 코드를 한 생성자에만 집중적으로 작성하고, 나머지 생성자는 this(...)를 사용하여 공통 코드를 가지고 있는 생성자를 호출하는 방법으로 개선이 가능하다.
Car(String model){
this(model, "은색", 250);
}
Car(String model, String color){
this(model, "은색", 250);
}
Car(String model, String color, int maxSpeed){
this.model=model;
this.color=color;
this.maxSpeed=maxSpeed; // 공통 초기화코드 위에 호출
}
-this(매개값)는 생성자의 첫줄에 작성이 되며, 다른 생성자를 호출하는 역할을 함, 호출하고 싶은 생성자의 매개변수에 맞게 매개값을 제공하면 된다.
4. 가변길이 매개변수 (varargs)
-메소드를 호출할 때에는 매개변수의 개수에 맞게 매개 값을 제공해야 함, 만약 메소드가 가변길이 매개변수를 가지고 있다면 매개변수의 개수와 상관 없이 매개값을 줄 수 있다.
-가변길이 매개변수는 선언에 있어 ... 키워드를 사용하며 메소드 호출 시 매개값을 쉼표로 구분하여 개수와 상관 없이 제공할 수 있음, 이는 내부적으로 배열을 생성하여 이들을 저장하는 것이기 때문에 남발하지는 말아야 함.
int sum(int...values){}
int result=sum(1,2,3);
int result2=sum(1,2,3,4,5);
-다시 한 번 이야기하면, 매개값들은 자동으로 배열 항목으로 변환되어 메소드에서 사용, 그렇기 때문에 메소드 호출 시 직접 배열을 매개값으로 제공해도 된다.
int[] values={1,2,3}
int result=sum(values); //이렇게 해도 되고
int result=sum(ner int[] {1,2,3}); // 이렇게 해도 된다