JAVA

JAVA 클래스

Adev 2023. 1. 3. 14:11

1. 클래스 구성 멤버

: 필드, 생성자, 메소드로 이루어져 있다.

 

 

1) Field 

: 객체의 데이터가 저장된다.

생성자와 메소드 전체에 사용된다.


2) Constructor 

: 객체 생성 시 초기화 역할을 담당하는 중괄호 블록이다.

new 연산자로 호출할 수 있으며, 이때 생성된 객체들는 해당 클래스의 인스턴스들로 각각 독립되어 있다.
new 연산자로 생성된 객체는 메모리 heap영역에 생성된 후 객체의 주소를 리턴하는데, 이 주소를 참조타입인 클래스변수에 저장하면 stack영역의 변수가 객체를 참조하게 된다.


3) Method 

: 객체의 동작에 해당하 중괄호 블록이다.

객체 간의 데이터 전달의 수단으로 사용된다.

 

 

 

2. 예제로 알아보기

 

1) 예제 Car

[라이브러리용 클래스]

public class Car { //클래스 선언.
//여러개의 클래스 선언도 가능은 하지만 소스파일 하나당 클래스 하나만 선언하는 게 좋다.
//public은 파일명과 동일한 클래스선언에만 붙일 수 있다.

//int brand = "bmw"; //필드 선언 및 필드 초기화. 
//동일한 클래스로의 객체는 모두 bmw를 값으로 갖는다.
//기본 생성자 Car()를 호출해서 객체를 생성할 수 있다.

int speed; //필드 선언.
int model;
int gas;
//필드에 초기값을 주지 않아도 타입 별로 기본값이 설정되어있다.
//객체 생성 시점에 생성자의 매개값으로 다양한 값을 받아서 초기화할 수 있다.

public Car(int speed, String model) { //생성자 선언 및 필드 초기화 블록
this.speed = speed; //전자는 필드, 후자는 매개변수
this.model = model;
}




public Car() {} //따로 생성자를 선언하지 않을 시 자동으로 추가되는 기본생성자 선언. 
//모든 클래스에는 반드시 하나 이상의 생성자가 존재한다.
//new연산자로 기본 생성자를 호출해서 객체를 생성할 수 있다.
//public Car() { gas = 10;} //내부클래스 생성자에서 필드 값 변경.

void getGas(int gas) {this.gas = gas;} //메소드에서 필드 값 변경

boolean isLeftGas() { //메소드 선언
if(gas=0) { return false; }
return true;
}

void run() { //메소드 선언
while(run) {
if(gas>0) { gas -= -1; }
else { System.out.println ("가스 부족. 정지"); return;}
}
}

}

 

[실행용 클래스 - 실행 진입점인 main()를 제공한다]

public class CarExecute {
public static void main(String[] args) {
////new연산자로 생성자를 호출해서 객체를 생성할 수 있다.

//Car C1; //클래스변수 선언
//C1 = new Car(); //기본생성자의 객체생성

Car C1 = new Car("200", "i7"); //클래스변수 선언 및 객체생성.
C1.speed = 300; //외부클래스 필드 값 변경.
//외부 클래스에서 필드 사용 시 반드시 객체를 생성한 후 참조 변수 사용.




Car C2 = new Car(); //기본생성자의 클래스변수 선언 및 객체생성. 

C2.setGas(10); //리턴값 없는 메소드 호출. 필드값 변경.
//외부 클래스에서 메소드 호출 시 반드시 객체를 생성한 후 참조 변수 사용.
//리턴값이 있지만 받고 싶지 않은 경우에도 위와 같이 호출.

boolean gasState = C2.isLeftGas(); //리턴값 있는 메소드 호출 

if(C2.isLeftGas()) { //메소드 호출
System.out.println("가스 충분") }
else {System.out.println("가스 부족")}
}

if(gasState) {
System.out.println("가스 충분. 출발")
C2.run();
}

}

 

 

 

2) 예제 Calculator

[라이브러리용 클래스]

public class carculator {

void powerOn() {System.out.println("전원 켜기")} //메소드 선언

int plus(int x, int y) {int result = x+y; return = result;} //메소드 선언

int sum1(int[] values) {int sum = 0; for(int i = 0; i<values.length; i++){
sum +- values[i];}
return sum;} //메소드 선언 - 배열1
}

//int sum2(int ... values) {int sum = 0; for(int i = 0; i<values.length; i++){
//sum +- values[i];
//return sum;) 메소드 선언 - 배열2
//}

void powerOff() {System.out.println("전원 끄기")} //메소드 선언
}

 

[실행용 클래스 - 실행 진입점인 main()를 제공한다]

public class CalculatorExcute {
public static void main(String[] args) {

Calculator C1 = new Calculator(); //클래스 변수 선언 및 객체생성.

C1.powerOn(); //메소드 호출

int plusResult = C1.plus(1, 2); //메소드 호출
System.out.println("plus 결과" = plusResult);

int values1[] = {1, 2, 3}; //메소드 호출 - 배열1. 배열 생성 후...
int sumResult1 = C1.sum1(values1); //
System.out.println("sum1 결과" = sumResult1);

//int sumResult1 = C1.sum1(new int values[] = {1, 2, 3}); //메소드 호출 - 배열1
//System.out.println("sum1 결과" = sumResult1);

//int sumResult2 =C1.sum2(1, 2, 3); //메소드 호출 - 배열2
//System.out.println("sum2 결과" = sumResult2);

C1.powerOff(); //메소드 호출
}
}

 

 


 

 

3. 정적 멤버, 인스턴트 멤버

클래스 - 공용 데이터는 정적 멤버로 선언, 객체마다 가지는 데이터는 인스턴트 멤버로 선언한다.

정적 멤버는 외부에서 객체 생성 없이 클래스명+도트(.) 로 접근할 수 있어야 한다. 따라서 객체 생성 시 초기화 작업 및 this 사용이 불가능하며, 초기화는 선언 시 또는 정적 블록에서 진행한다.

(같은 클래스 내라도 정적 필드와 메소드에서 인스턴트 멤버를 사용한다면 객체 생성 후 참조변수로 접근해야 한다.)

//정적 블록
static {
...
}

 

 

4. 싱글톤 패턴 (Singleton)

: 단 하나의 객체만 생성해 사용한다.

정적필드에 private 접근 제한자를 붙여 외부에서 값을 변경할 수 없게 하고 객체를 생성해 초기화한다.

생성자에 private 접근 제한자를 붙여 외부에서 호출할 수 없게 한다.

정적 메소드 getInstance()를 선언하고 자신의 객체를 리턴한다.

외부에서는 정적 메소드 getInstance()를 호출해 동일한 객체 한 개를 얻어 사용한다.

public class Car {

private static Car singleton = new Car(); 

private Car() {}

static Car getInstance() {
return singleton;
}
}

 

 

5. final field와 상수(static final field, constant)

final 필드에 초기값 주는 방법

(1) 필드 선언 시 초기값 지정. ex) 국적

(2) 필드 선언 후 생성자에서 초기값 지정. ex) 주민번호

 

//라이브러리 클래스
final String nation = "Korea";
final String ssn;

public Person(String ssn) {
this.ssn = ssn;



//실행 클래스
Person P1 = new Person("123-123");

 

상수를 초기화하는 방법

(1) 상수 선언 시 초기값 지정.

(2) 정적 블록에서 초기값을 준다.

cf. 상수 표기 : 대문자, 단어 연결 시 언더바(_)