들어가며
클래스 내에 정의된 메소드에
static 선언을 하면
'클래스 메소드'가 된다.
그리고 클래스 메소드는 그
성격이 클래스 변수와 유사하다.
접근 방법도 동일하며, 인스턴스
생성 이전부터 호출이 가능한,
그리고 어느 인스턴스에도
속하지 않는 메소드라는 점도
클래스 변수와 유사하다.
클래스 메소드의(static 메소드의) 정의와 호출
앞서 공부한 클래스 변수의
특성 2가지는 다음과 같다.
- 인스턴스 생성 이전부터 접근이 가능하다.
- 어느 인스턴스에도 속하지 않는다.
이 두가지는 클래스 메소드도
동일하게 갖는 특성이다.
따라서 이 사실을 다음 예제를
통해서 확인해보겠다.
더불어 클래스 변수의 접근
방법과 동일한 '클래스 메소드의
호출 방법'도 확인해보자.
class NumberPrint {
private int myNum = 0;
static void showInt(int n) { // 클래스 메소드(static 메소드)
System.out.println(n);
}
static void showDouble(double n) { // 클래스 메소드
System.out.println(n);
}
void setMyNumber(int n) { // 인스턴스 메소드
myNum = n;
}
void showMyNumber(){ // 인스턴스 메소드
showInt(myNum); // 클래스 내부에서 클래스 메소드 호출
}
}
class ClassMethod {
public static void main(String[] args){
NumberPrint.showInt(20); // 클래스 이름을 통한 클래스 메소드 호출
NumberPrint np = new NumberPrint();
np.showDouble(3.14); // 인스턴스 이름을 통한 클래스 메소드 호출
np.setMyNumber(75);
np.showMyNumber();
}
}
/*
실행 결과
20
3.14
75
*/
위 예제에서 다음과 같이 클래스의
이름을 통해서 메소드를 호출하였다.
NumberPrinter.showInt(20);
사실 위의 메소드 호출만 가지고도
클래스 메소드가 어느 인스턴스에도
속하지 않는다는 사실을 알 수 있다.
인스턴스 생성 이전에 호출이 되었기
때문이다.
그리고 예제의 주석에서 설명하고
있듯이
클래스 내부와 외부에서 클래스
메소드를 호출하는 방법은
클래스 변수에 접근하는 방법과
차이가 없다.
클래스 메소드로 정의하는 것이 더 나은 경우
다음 예제를 분석하는 시간을
가져보자.
특히 SimpleCalculator 클래스에
정의된 메소드들을 관찰하자.
class SimpleCalculator {
static final double PI = 3.1415;
double add(double n1, double n2) {
return n1 + n2;
}
double min(double n1, double n2) {
return n1 - n2;
}
double calCircleArea(double r){
return PI * (r * r);
}
double calCirclePeri(double r){
return PI * (r * 2);
}
}
class UseCalculator {
public static void main(String[] args){
SimpleCalculator sc = new SimpleCalculator();
System.out.println("3 + 4 = " + sc.add(3, 4));
System.out.println("반지름 2.2, 원의 넓이: " + sc.calCircleArea(2.2));
System.out.println("15 - 7 = " + sc.min(15, 7));
System.out.println("반지름 5.0, 원의 둘레: " + sc.calCirclePeri(5.0));
}
}
/*
실행 결과
3 + 4 = 7.0
반지름 2.2, 원의 넓이: 15.204860000000004
15 - 7 = 8.0
반지름 5.0, 원의 둘레: 31.415000000000003
*/
위 예제에서 클래스 SimpleCalculator에
정의된 메소드가 갖는 특징 2가지는
다음과 같다.
- 모두 외부에 기능을 제공하기 위한 메소드들이다.
- 모두 인스턴스 변수의 값을 참조하거나 수정하지 않는다.
즉 SimpleCalculator에 정의된
메소드들은 인스턴스에 속할
이유가 없다.
따라서 위 예제는 다음과 같이
수정하는 편이 낫다.
다음 예제에서는 클래스의 이름을 SC로 단순하게 바꾸었다.
class SC {
static final double PI = 3.1415;
static double add(double n1, double n2) {
return n1 + n2;
}
static double min(double n1, double n2) {
return n1 - n2;
}
static double calCircleArea(double r){
return PI * (r * r);
}
static double calCirclePeri(double r){
return PI * (r * 2);
}
}
class UseCalculator {
public static void main(String[] args){
SC sc = new SC();
System.out.println("3 + 4 = " + sc.add(3, 4));
System.out.println("반지름 2.2, 원의 넓이: " + sc.calCircleArea(2.2) + '\n');
System.out.println("15 - 7 = " + sc.min(15, 7));
System.out.println("반지름 5.0, 원의 둘레: " + sc.calCirclePeri(5.0));
}
}
/*
실행 결과
3 + 4 = 7.0
반지름 2.2, 원의 넓이: 15.204860000000004
15 - 7 = 8.0
반지름 5.0, 원의 둘레: 31.415000000000003
*/
위 예제에서 보이듯이, 메소드에 static
선언을 추가함으로 인해
불필요한 인스턴스 생성 과정을
생략할 수 있게 되었다.
실제로 '클래스 메소드'로 구성된,
인스턴스의 생성을 목적으로
설계되지 않은 클래스들도
존재하고,
프로그래머가 이러한 유형의
클래스를 직접 설계하는 경우도
종종 있다.
클래스 메소드에서 인스턴스 변수에 접근이 가능할까?
다음 질문에 답을 해보라.
클래스 메소드의 특성을 잘
이해했다면 답을 할 수 있다.
클래스 메소드에서 같은 클래스에 선언된
인스턴스 변수에 접근이 가능한가?
이는 다음과 같은 코드의
작성이 가능한지를 묻고 있다.
class AAA {
int num = 0;
static void addNum(int n){
num += n; // 이 문장은 유효한가?
}
}
논리적으로 생각을 하면, 위와 같은
문장 구성이 불가능하다는 것을
알 수 있다.
인스턴스 변수는 인스턴스에
속한다.
더불어 인스턴스가 생성이 되어야
메모리 공간에 존재하게 된다.
반면 클래스 메소드는 인스턴스
생성 이전부터 호출이 가능하다.
그런데 어떻게 위와 같은 문장을
구성할 수 있겠는가?
따라서 위 질문에 대해서 다음과
같이 답을 할 수 있어야 한다.
클래스 메소드는 인스턴스에 속하지 않으므로, 인스턴스 변수에 접근이 불가능하다.
&
같은 이유로, 클래스 메소드는 인스턴스 메소드의 호출도 불가능하다.
그러나 다음과 같이 클래스 메소드는
같은 클래스에 정의되어 있는
다른 클래스 메소드나 성격이 동일한
클래스 변수에는 접근이 가능하다.
class AAA {
static int num = 0;
static void showNum() {
System.out.println(num); // 클래스 변수 접근 가능
}
static void addNum(int n) {
num += n; // 클래스 변수 접근 가능
showNum(); // 클래스 메소드 호출 가능
}
}
참고 및 출처
|