관리 메뉴

클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지

클래스와 객체 15 - static 멤버 2 : static 활용 및 static 메서드의 제약 조건 본문

프로그래밍 언어/자바

클래스와 객체 15 - static 멤버 2 : static 활용 및 static 메서드의 제약 조건

huenuri 2024. 8. 19. 08:15

나머지 학습을 이어가기로 하자. 조금 졸리지만 그래도 30분만 더 공부를 해보자. 지난 포스트에서는 static에 대한 이론 학습 위주로 했지만 여기서는 예제 문제도 풀어보며 static과 좀 더 친해지는 시간을 가져볼 것이다.


 

 

1. static 멤버의 생성과 활용 예제 학습

지난번에 학습했던 예제를 이클립스에서 코드를 짜보며 직접 실습해보았다. 원래 예제 문제만 코드를 짜보는 편이지만 이 문제는 정말 중요한 것 같아 한번 실습해 보기로 했다.

 

객체. static 멤버

 

 

근데 몇 가지 코드에서 노란줄이 표시되고 있다. 이 부분을 한번 수정해보려고 한다.


 

 

 

이제 노란줄이 모두 없어졌다. 이 부분은 다음에 학습할 예제에 나오는 방식인데 static 멤버에 접근하는 두 번째 방법인 클래스 이름으로 접근하지 않았기 때문에 발생한 것 같다. 아마도 이 방식을 더 추천하는 모양이다.

 

 

값은 5가 되었다. m의 최종 수정된 값이 이것이다.


 

 

클래스명. static 멤버

 

StaticSample 클래스 부분은 앞의 예제와 같다. 하지만 여기서도 역시 노란줄이 뜨고 있다. 이 부분을 수정해 볼 것이다.

 

 

 

 

 

그래도 s1의 노란줄은 사라지지 않아서 경고 표시를 넣어주었다.  이제 시간이 너무 많이 되어서 나머지 부분은 내일 새벽에 진행하려고 한다.


 

 

2. static의 활용

 

전역 변수와 전역 함수를 만들 때 활용

자바에서는 C++과 달리 어떤 변수나 함수도 클래스 바깥에 존재할 수 없으며 클래스의 멤버로 존재해야 한다. 이는 자바의 캡슐화 원칙 때문이다. 한편 응용 프로그램 작성 시 모든 클래스에서 공유하는 전역 변수나 모든 클래스에서 호출할 수 있는 전역 함수가 필요한 경우가 있다. static은 이런 문제에 대한 해결책이다.

static 멤버를 가진 대표적인 클래스로 java.lang.Math가 있다. 이 클래스는 다음과 같이 객체를 생성하지 않고 바로 호출할 수 있는 static 타입의 멤버를 제공한다.

public class Math {
	public static int abs(int a);
    public static double cos(double a);
    public static int max(int a, int b);
    public static double random();
    ...
}

 

응용 프로그램에서 Math의 멤버들을 사용하기 위해 다음과 같이 하지 않는다.

Math m = new Math();	// 오류. 생성자 Math()는 private으로 선언되어 있어 객체 생성 안 됨
int n = m.abs(-5);

 

대신 다음과 같이 클래스 이름 Math로 static 멤버를 직접 호출한다.

int n = Math.abs(-5);	// 바른 사용

 

 

 

공유 멤버를 만들고자 할 때 활용

static으로 선언된 필드나 메서드는 하나만 생성되어 클래스의 객체들 사이에서 공유된다.

 

static 멤버를 가진 Cals 클래스 작성

전역 함수로 작성하고자 하는 abs, max, min의 3개 함수를 static 메서드로 작성하고 호출하는 사례를 보여라.

 

 

클래스를 각각 다른 곳에 작성하였다. 이 메서드는 static 메서드만 가진 클래스이다. 결과는 다음과 같다.

 

 


 

 

 

3. static 메서드의 제약 조건

static 메서드는 일반 메소드와 달리 다음 두 가지 제약 사항이 있다

 

static 메소드는 static 멤버만 접근할 수 있다

static 메소드는 객체 없이도 존재하기 때문에 객체와 함께 생성되는 non-static 멤버를 사용할 수 없고 static 멤버들만 사용 가능하다. 반면 non-static 멤버들을 사용할 수 있다.

class StaticMethod {
    int n;
    void f1(int x) { n = x; }	// 정상
    void f2(int x) { m = x; }	// 정상
    
    static int m;
    static void s1(int x) { n = x; }	// 컴파일 오류 : static 메소드는 non-static 필드 사용 불가
    static void s2(int x) { f1(3); }	// 컴파일 오류 : static 메소드는 non-static 필드 사용 불가
    
    static void s3(int x) { m = x; }	// 정상 : static 메소드는 non-static 필드 사용 가능
    static void s4(int x) { s3(3); }	// 정상 : static 메소드는 non-static 메소드 호출 가능
 }

 

 

static 메소드는 this를 사용할 수 없다

static 메소드는 객체 없이도 존재하기 때문에 this를 사용할 수 없다.

class StaticAndThis {
    int n;
    static int m;
    void f1(int x) { this.n = x; }	
    void f2(int x) { this.m = x; }		// non-static 메소드에서는 static 멤버 접근 가능
    static void s1(int x) { this.n = x; }	// 컴파일 오류. static 메소드는 this 사용 불가
    static void s2(int x) { this.m = x; }	// 컴파일 오류. static 메소드는 this 사용 불가
}

 

 

 

static을 이용한 환율 계산기

static 멤버를 이용하여 달러와 원화를 변환해 주는 환율 계산기를 만들어보자.

 

 

 


 

 

 

 

핵심 체크 문제 풀기

 

 

3번 문제

 

this 키워드는 사용 불가해서 빼주었더니 코드의 오류가 수정되었다.


 

 

 

 

4번 문제


 

이 오류는 static 요소 안에 인스턴스 변수를 직접 접근하려고 할 때 발생한다. 인스턴스 변수 s에 접근하려면 반드시 객체를 생성한 후 객체를 통해 접근해야 한다 객체를 만들기는 했으나 접근한 후에 만들었기에 오류가 뜨는 것이다.

그리고 static 변수는 객체를 통해 접근하기보다 클래스 이름을 통해 접근하는 것이 좋다. 여기서 출력할 때 obj 대신 StaticCheck라는 클래스 이름을 사용하면 경고가 사라진다.

 

 

이 문제는 코드만 보고는 오류를 알 수 없어서 직접 작성하며 어디서 오류가 발생하는지 고민해 보았다.


 

 

 

학습을 마치고

여기까지 해서 static 공부를 마쳤다. 어제 다 했어야 했는데 다음날 일어나서 마무리했다. static 생각보다 어려웠다. 특히 어떻게 할 때 접근이 가능하고 가능하지 않은지 처음에는 파악하기 힘들었다. 하지만 문제를 풀어보고 예제 코드를 작성해 보며 이제는 조금 알게 되었다.

나중에 한번 더 복습을 하면 그때는 확실하게 이해할 수 있을 것 같다.