본문 바로가기
개발/JAVA

자바 객체지향 (4) - static, static 멤버 변수의 활용, static 키워드가 정의된 메소드

by chansungs 2020. 6. 14.
728x90
반응형

static 키워드

// static 키워드
// - 클래스의 정적 변수 / 정적 메소드를 선언할 때 사용하는 키워드
// - static 키워드를 사용하여 선언한 멤버 변수/메소드는 객체의 생성없이
//   사용할 수 있는 멤버입니다.
// - static 키워드가 선언되지 않은 멤버 변수/메소드는 인스턴스 변수, 인스턴스 메소드
// - 인스턴스 변수/메소드는 객체가 반드시 만들어져야만 사용할 수 있습니다.

// static 키워드가 적용된 멤버는 프로그램의 시작 이전부터 프로그램의 종료때까지
// 데이터를 유지할 수 있는 멤버입니다.

// EX
// System.out.print();

// 자바프로그램의 구동과정
// 1. 상수/static 멤버/메소드의 메모리 로딩
// 2. 메모리에 로딩된 static 메소드 중 main 메소드를 실행

class StaticA {
	public static int static_number = 10;
	public int normal_number = 20;
}

public class Class_13_Static {
	public static void main(String[] args) {
		
		// 일반적인 멤버 변수의 접근방법
		// 1. 객체 생성
		StaticA s = new StaticA();
		// 2. 객체를 참조하고 있는 레퍼런스 변수를 사용하여 멤버에 접근
		System.out.println(s.static_number);
		System.out.println(s.normal_number);
		
		// static 멤버의 접근방법
		// - 클래스의 이름으로 객체의 생성없이 직접 접근이 가능
		System.out.println(StaticA.static_number);
		// - 주의! 일반 멤버(static이 아닌)들은 클래스의 이름으로 
		//   접근할 수 없습니다.(객체를 생성한 후에 사용가능)
		// System.out.println(StaticA.normal_number);
		
	}
}

static 멤버 변수의 활용방법

// static 멤버 변수의 활용방법
// - static 멤버 변수는 각각의 객체마다 할당되는 것이 아닌
//   클래스로부터 생성된 모든 객체들이 '공유'하는 변수가 됩니다.

class Counter {
	// 프로그램의 시작 이전에 static 메모리 영역에 4byte 공간을 할당받아
	// Counter 클래스의 count 라는 이름을 붙임. 초기화 값으로는 0을 할당.
	private static int count = 0;
	// Counter 클래스의 각 객체를 생성하면서 이름을 저장하기 위한 용도의
	// 인스턴스 변수를 선언
	private String name;
	
	public Counter(String name) {
		this.name = name;
		// Counter 클래스의 객체가 생성될 때 마다
		// count의 값을 증가
		count++;
	}
	
	public void checkCount() {
		System.out.printf("%s -> %d\n", 
				this.name, count);
	}
}
public class Class_14_Static {
	public static void main(String[] args) {
		// Counter 클래스의 static(공유) 변수 count 값이 1증가
		Counter c1 = new Counter("C1");
		c1.checkCount();
		System.out.println("=================");
		
		// Counter 클래스의 static(공유) 변수 count 값이 1증가
		Counter c2 = new Counter("C2");
		c1.checkCount();
		c2.checkCount();
		System.out.println("=================");
		
		// Counter 클래스의 static(공유) 변수 count 값이 1증가
		Counter c3 = new Counter("C3");
		c1.checkCount();
		c2.checkCount();
		c3.checkCount();
		System.out.println("=================");
	}
}

// static 멤버는 공용변수를 선언할 때 사용할 수 있습니다.
// - 프로그램 전체에서 사용되는 배열의 크기와 같은 정보
class Info {
	// static 변수는 대다수의 경우 변수명을 대문자로 지정합니다.
	// - 눈에 잘 띄기 위해서
	public static int ARRAY_SIZE = 1000;
}

public class Class_15_Static {
	public static void main(String[] args) {		
		// int [] array = new int[1000];
		int [] array = new int[Info.ARRAY_SIZE];
		
		// Java 언어에서 static 멤버를 사용하는 경우
		// - Math 클래스 (수학 공식을 정의한 클래스)
		System.out.printf("원주율 -> %f\n", Math.PI);
		
	}
}

static 키워드가 정의된 메소드

// static 키워드가 정의된 메소드
// - static 멤버 필드와 같이 프로그램의 구동전에 메모리에 로딩되어
//   객체의 생성없이 클래스의 이름을 사용해 호출할 수 있는 메소드
// 1. static 멤버필드를 초기화 하는 역할
// 2. 간단한 공용 기능을 구현할 때( ex - Math 클래스 )

class StaticB {
	// static 멤버 역시 접근지정자에 제약을 받습니다.
	// 아래와 같이 private 으로 지정된 static 멤버는 클래스의 외부에서
	// 접근할 수 없는 멤버가 됩니다.
	private static int number;
	
	// static 블럭
	// - static 멤버를 초기화하기 위해서 또는 
	// 프로그램의 구동시 단한번만 자동으로 실행하고자 하는 코드를 정의하는 영역
	static {
		System.out.println("static 영역 실행");
		number = 7;
	}
	
	// 위와 같은 경우 외부에서의 접근이 차단되므로 static 메소드를 제공하여 
	// private으로 지정된 멤버의 값을 수정할 수 있습니다.
	public static void setNumber(int number) {
		StaticB.number = number;
	}
	public static int getNumber() {
		return number;
	}
}

public class Class_16_Static {
	public static void main(String[] args) {
		// private 으로 지정된 static 멤버는 클래스 외부에서의 접근이 차단됩니다.
		// System.out.printf("StaticB.number = %d\n", StaticB.number);
		
		// public 접근권한의 static 메소드로 문제를 해결하는 방법
		System.out.printf("StaticB.number = %d\n", StaticB.getNumber());
		StaticB.setNumber(100);
		System.out.printf("StaticB.number = %d\n", StaticB.getNumber());
		
		// Java 언어에서 static 메소드를 사용하는 경우
		// - Math 클래스 (수학 공식을 정의한 클래스)
		
		// - 난수를 발생시킬 수 있는 random 메소드
		System.out.println(Math.random());
		// - 절대값을 반환하는 abs 메소드
		System.out.println(Math.abs(-15.3));
	}
}

// static 멤버는 프로그램의 시작 이전부터 메모리에 적재되는 멤버입니다.
// - static 메소드는 메소드의 내부에서 this를 사용할 수 없습니다.
//   (일반 멤버 필드(변수)를 사용할 수 없습니다.)
class StaticC {
	// static 멤버
	// - 클래스의 객체 생성없이 클래스명으로 접근할 수 있는 멤버
	public static int static_num = 100;
	// 일반(인스턴스) 멤버 - 클래스의 객체가 생성되어야만
	// 메모리에 적재되는 멤버
	public int normal_num = 50;
	
	public static void static_print() {
		System.out.printf("static_num = %d\n", static_num);
		// static 메소드는 클래스의 이름으로 호출되는 메소드이므로
		// 실제 객체의 생성없이 호출될 수 있습니다.
		// - 이러한 경우 어떠한 객체도 생성되지 않은 상태이므로
		// 아래와 같이 this 를 사용해야 하는 일반 인스턴스 멤버들은 
		// 사용될 수 없습니다.
		// System.out.printf("normal_num = %d\n", this.normal_num);
	}
	
	public void normal_print() {
		// 일반 메소드에서 static 멤버에 접근할 수 있습니다.
		System.out.printf("static_num = %d\n", static_num);
		System.out.printf("normal_num = %d\n", normal_num);
	}
}
public class Class_17_Static {
	public static void main(String[] args) {		
		StaticC.static_print();
	}
}
728x90
반응형