Java/객체지향

[객체지향][자바의 정석] - 7.4 제어자

얄루몬 2021. 11. 11. 21:42

※ 7.3 패키지와 import는 굳이 포스팅하지 않아도 될것 같아서 7.4로 넘어감

 

7.4 제어자

 

1. 제어자란?

- 클래스 ,변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여한다.

- 제어자는 크게 접근 제어자그 외의 제어자로 나뉜다.

- 하나의 대상에 여러 개의 제어자를 조합해서 사용할 수 있으나, 접근제어자는 단 하나만 사용할 수 있다.

접근 제어자 - public, protected, default, private
그 외 - static, final, abstract, native, transient, synchronized, volatile, strictfp 

 

 

2. static

- static이 사용될 수 있는 곳 - 멤버변수, 메서드, 초기화 블럭

제어자 대상 의미
static 멤버변수 -모든 인스턴스에 공통적으로 사용되는 클래스 변수가 된다.

- 클래스변수는 인스턴스를 생성하지 않고도 사용 가능하다.

-클래스가 메모리에 로드될 때 생성된다.
메서드 - 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다.

- static메서드 내에서는 인스턴스멤버들을 직접 사용할 수 없다.
package javaStandard;

class staticTest{
	static int width = 200;
	static int height = 120;
	
	static {
		
	}
	static int max(int a, int b) {
		return a>b ? a:b; 
	}
	
}

 

 

3. final

- final이 사용될 수 있는 곳 - 클래스, 메서드, 멤버변수, 지역변수

제어자 대상 의미
final 클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
메서드 변경될 수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다. 
멤버변수 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다. 
지역변수
package javaStandard;

final class FinalTest{
	
	final int MAX_SIZE = 10; //멤버 변수
	
	final void getMaxSize() {
		final int LV = MAX_SIZE; // 지역변수 ---> 메소드 안에 있으니까
		return MAX_SIZE;
	}	
}

clsaa Child extends FinalTest{
	void getMaxSize() {} // 에러, 오버라이딩 불가
}

 

 

4. 생성자를 이용한 final 멤버변수 초기화

- final이 붙은 변수는 상수이므로 보통은 선언과 초기화를 동시에 하지만 인스턴스마다 고정값을 갖는 인스턴스 변수의 경우 생성자에서 초기화한다.

package javaStandard;

class Card {
	
	final int NUMBER;
	final String KIND;
	final int width = 100;
	final int height = 250;
	
	Card(String kind, int num){
		KIND = kind;
		NUMBER = num;
	}
	
	Card(){
		this("HEART",1);
	}
	
	public String toString() {
		return "" + KIND + " "+NUMBER;
	}


public static void main(String args[]) {
	Card c = new Card("HEART",10);
	System.out.println(c.KIND);
	System.out.println(c.NUMBER);
	} 
}

// 여기 부분을 동영상 보면서 다시 익히기

 

 

5. abstract

- abstract가 사용될 수 있는 곳 - 클래스, 메서드

제어자 대상 의미
abstract 클래스 클래스 내에 추상메서드가 선언되어 있음을 의미한다.
메서드 선언부만 작성하고 구현부는 작성하지 않은 추상메서드임을 알린다.
abstract class AbstractTest { // 추상클래스
    abstract void move(); // 추상메서드
}

 

 

6. 접근 제어자(access modifier)

- 멤버 또는 클래스에 사용되어, 외부로부터의 접근을 제어한다.

private - 같은 클래스 내에서만 접근이 가능하다.
default - 같은 패키지 내에서만 접근이 가능하다.
protected - 같은 패키지내에서, 다른 패키지의 자손클래스에서 접근이 가능하다.
public - 접근제한이 전혀 없다.
package javajungsuk;

class MyParent {
	private int prv; //같은 클래스
			int dft; //같은 패키지 default
	protected int prt; // 같은 패키지 + 자손(다른패키지)
	public int pub; //접근제한 X
	
	public void printMembers() {
		System.out.println(prv);
		System.out.println(dft);
		System.out.println(prt);
		System.out.println(pub);
	}
}

public class MyParentTest{
	public static void main(String[] args) {
			MyParent p = new MyParent();
			System.out.println(p.prv); //에러 접근범위 안 맞음
			System.out.println(p.dft);
			System.out.println(p.prt);
			System.out.println(p.pub);

	}

}
//에러 이때 MyParent는 default가 접근제어자로 쓰이기 때문에 같은 패키지 안에서만 사용가능해서 에러가 난다. 
package javajungsuk;

class MyChild extends MyParent{ 
	public void printMembers() {
		System.out.println(prv);
		System.out.println(dft);
		System.out.println(prt);
		System.out.println(pub);
	}
}

public class MyParentTest2 {
	public static void main(String[] args) {
			MyParent p = new MyParent();
			//System.out.println(p.prv); //에러 접근범위 안 맞음
			System.out.println(p.dft);
			System.out.println(p.prt);
			System.out.println(p.pub);

	}

}

// 클래스 내에서 public 클래스는 하나만 사용가능

 

 

package javajungsuk;
//같은 클래스 내에 public 클래스는 한 번만 쓸 수 있다. 

public class MyParent {//접근 제어자 public
	private int prv; //같은 클래스
			int dft; //같은 패키지 default
	protected int prt; // 같은 패키지 + 자손(다른패키지)
	public int pub; //접근제한 X
	
	public void printMembers() {
		System.out.println(prv);
		System.out.println(dft);
		System.out.println(prt);
		System.out.println(pub);
	}
}

class MyParentTest{ //접근 제어자 (default)
	public static void main(String[] args) {
			MyParent p = new MyParent();
			//System.out.println(p.prv); //에러 접근범위 안 맞음
			System.out.println(p.dft);
			System.out.println(p.prt);
			System.out.println(p.pub);

	}

}
package javajungsuk2;


class MyChild extends MyParent{ 
	public void printMembers() {
		//System.out.println(prv); //에러 같은 클래스 내에서만 사용 가능
		System.out.println(dft); //에러 같은 패키지 안에서만 사용하면 됨. 
		System.out.println(prt); //에러 다른패키지지만 자손이라 OK
		System.out.println(pub); //에러
	}
}

public class MyParentTest2 {
	public static void main(String[] args) {
			MyParent p = new MyParent();
			//System.out.println(p.prv); //에러 접근범위 안 맞음
			System.out.println(p.dft);
			System.out.println(p.prt);
			System.out.println(p.pub);

	}

}

 

 

7. 접근 제어자를 이용한 캡슐화

접근 제어자를 사용하는 이유
- 외부로부터 데이터를 보호하기 위해서 (캡슐화)
- 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서
// 접근제한이 없는 경우 

public class Time{
    public int hour;
    public int minute;
    public int second;
}
package javajungsuk;

class Time{
	//접근제한을 해주어 캡슐화시켜 준다.
	private int hour; //0~23사이의 값을 가져야 한다.
	private int minute;
	private int second;
	
	public void setHour(int hour) {
		if(hour < 0 || hour > 23) return;
		this.hour=hour;
	}
	public int getHour() {
		return hour;
	};

}

public class java7_4_7{
	public static void main(String[] arge) {
    
        //접근제어자 때문에 직접 사용이 불가 t.hour 등에 바로 삽입 불가 
		Time t = new Time();
		//t.hour = -100;
		t.setHour(21);
		System.out.println(t.getHour());
//		t.setHour(100);
//		System.out.println(t.getHour());
	}
}

 

8. 생성자의 접근 제어자

9. 제어자의 조합