[윤성우의 열혈 Java 프로그래밍] Chapter 10 클래스 변수, 클래스 메소드
개인적으로 헷갈리는 것 중요한 것 위주로 정리해두고 연습문제를 풀어본 글입니다.
- 클래스 변수
클래스 내 변수 앞에 static 선언 : 인스턴스 변수 -> 클래스 변수
//예제1
class InstCnt {
static int instNum = 0; //클래스 변수
InstCnt() { //생성자
instNum++;
System.out.println("인스턴스 생성 : " + instNum);
}
}
class ClassVar {
public static void main(String[] args) {
InstCnt cnt1 = new InstCnt();
InstCnt cnt2 = new InstCnt();
InstCnt cnt3 = new InstCnt();
}
}
/*
출력결과
인스턴스 생성 : 1
인스턴스 생성 : 2
인스턴스 생성 : 3
*/
예제1에서
static int instNum을 선언함으로써 변수 instNum은 클래스에 종속되지 않는다.
그렇지만 클래스 내부라 public, private 등 의 영향은 받는다.
같은 클래스에 있는 InstCnt 생성자는 instNum 변수에 자유롭게 접근할 수 있다.
인스턴스를 생성해서 변수의 값을 1씩 증가시킬 때 그 값은 instNum에 공유되어 저장된다.
따라서, 출력 결과가 1이 증가하면서 저장됨이 반복하여 1, 2, 3으로 나타나는 것이다.
클래스 변수(static 변수)는 그 클래스의 모든 인스턴스가 공유하는 변수이다.
- 클래스 변수 접근 방법
내부 접근 : 변수의 이름으로 직접 접근
외부 접근 : 클래스 또는 인스턴스 이름으로 접근 (public이면 그냥접근가능)
//예제2
class AccessWay {
static int num = 0; //접근제어 default
AccessWay() {
incrCnt();
}
void incrCnt() {
num++; //내부 접근
}
}
class ClassVarAccess {
public static void main(String[] args) {
AccessWay way = new AccessWay();
way.num++; //외부접근1 : 인스턴스 way
AccessWay.num++; //외부접근2 : 클래스 AccessWay★
System.out.println("num = " + AccessWay.num);
}
}
* 인스턴스보다 클래스로 접근하는 것이 둘 다 오류는 발생하지 않지만 더 명확하다.
* 클래스 변수는 생성자 이전에 초기화해야 인스턴스들이 공유할 수 있다. (생성자 내부 시 계속 초기화)
static 을 사용하는 상황
: 변수 값의 참조가 목적, 값의 공유가 목적
외부에서 참조해야 하는 경우 public선언
- 클래스 메소드
클래스 변수와 유사하다.
인스턴스 생성 전에 접근이 가능하고, 인스턴스에 속하지 않는다.
외부에 기능을 제공할 수 있고, 인스턴수 변수와 관련이 없다.
//예제3
class AAA {
int num = 0; //인스턴스 변수
static void addNum(int n) { //클래스 메소드
num += n;
}
}
/*클래스 메소드는 인스턴스 변수와 관련이 없으므로
변수에 직접접근이 불가하다.*/
//예제4
class AAA {
static int num = 0;
static void showNum() { //클래스 내 다른 클래스 메소드
System.out.println(num); //클래스 변수 num에 접근함
}
static void addNum(int n) {
num += n; //클래스 변수는 접근이 가능하다.
showNum(); //클래스 메소드로 클래스 변수를 호출할 수 있다.
}
}
/*클래스 메소드는 같은 클래스 내 다른 클래스 메소드와
성격이 같은 클래스 변수에 접근이 가능하다.*/
- public static void main(-) {System.out.println(-)}
public static void main
main메소드 호출이 클래스 외부에서 이뤄진다.
인스턴스 생성과 관계없이 제일 먼저 호출되는 메소드이다.
System. out. println
클래스이름/클래스변수/인스턴스호출
: 클래스에 있는 클래스 변수가 참조하는 인스턴스 메소드를 호출한다!
* main메소드는 static이 붙어 클래스와 관련이 없어서 어떤 클래스에 넣던 상관은 없다,
실행방법만 달라진다. (java ______)
- static 초기화 블록
클래스 변수는 생성자 전에 초기화를 해야한다고 했다.
그래서 보편적으로 선언과 동시에 "= 값" 으로 초기화를 한다.
그런데 이때, 초기화 하는 값이 내가 지정하기 힘든 값(얻어와야 하는 값)이면 (ex. 날짜, 시간, 계속해서 바뀌는 값)
static 초기화 블록을 사용한다.
import java.time.LocalDate; //import선언은 Ch08
class DateOfExecution { //날짜를 출력하려는 클래스
static String date;
static { //static 초기화 블록
LocalDate nDate = LocalDate.now();
date = nDate.toString();
}
public static void main(String[] args) {
System.out.println(date);
}
}
/*
출력결과
2020-08-03
*/
<문제 10-1.>
class Accumulator {
static int sum; //클래스변수(값이 공유됨)
static void add(int num) { //클래스메소드
sum += num; //클래스변수 sum값이 공유되어 저장됨
}
static void showResult() { //클래스메소드
System.out.println("sum = " + sum); //add메소드에서 저장된 sum값이 출력
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++)
Accumulator.add(i);
Accumulator.showResult();
}
}
/*
출력결과
sum = 45
*/