본문으로 바로가기

Java - 제어자

category 프로그래밍 언어/Java 2019. 7. 10. 01:38

1. 제어자

변수, 클래스, 메서드 등에 붙여서 사용됩니다.

 

  • 접근 제어자: public, private, protected, default
  • 그 외: static, final, abstract 등

2. static

static이 붙을 경우 인스턴스를 사용하는 것 없이 바로 사용이 가능합니다.

 

class A {

  // 클래스 변수
  static int w = 200;
  static int h = 100;

  // 클래스 초기화 블럭
  static {

  }

  // 클래스 메서드
  static int max(int a, int b) {
    return a > b ? a : b;
  }

}

위 static 변수 w와 h는 모든 인스턴스에 공통적으로 사용이 됩니다.

 

인스턴스 생성 없이 사용이 가능하고 클래스가 로딩 될 때 생성이 됩니다.

 

위 static 메서드 max는 인스턴스 생성없이 호출이 됩니다.

 

대신 이 메서드 내에서는 위의 w와 h를 사용할 수 없습니다.

 


3. final

흔히 불변이라는 말로 쓰입니다. 즉 변경될 수 없다라는 뜻입니다.

 

이는 오버라이딩, 자손클래스에 정의를 할 수 없습니다. String, Math 클래스 등이 있습니다.

 

final class A {   // 조상이 될 수 없는 클래스
  final int a = 10; // 값을 변경할 수 없는 멤버변수(상수)

  final void getMaxSize()  {  // 오버라이딩을 할 수 없는 메서드(변경불가)
    final int b = a; // 값을 변경할 수 없는 지역변수(상수)
  }
}

final 인스턴스 변수는 생성자에서 초기화가 가능합니다.

 

어떻게 가능하냐?

 

매개변수가 있는 생성자를 생성하여 매개변수를 통해 전달을 하여 처음 초기화를 진행합니다.

 

class A {
  final int a;       // 상수지만 선언과 함께 초기화하지 않고,
  final String b;      // 생성자에서 단 한번만 초기화 할 수 있다.

  public A(String aa, int bb) {
    a = aa;
    b = bb;
  }

  public A() {
    this("HI", 1);
  }

}

메인에서 생성자를 통해 인자를 넘겨주면 final 인스턴스 변수 a와 b가 초기화가 진행이 됩니다.

 


4. abstract

abstract은 말 그대로 미완성(?)의 뜻을 가지고 있습니다.

 

즉 메서드 선언부만 작성을 하고 실제 코드는 작성을 하지 않습니다. 

 

미완성이라 당연히 인스턴스는 생성하지 못합니다.

 

abstract class A {   // 추상 클래스(추상메서드를 포함한 클래스)
  abstract void a();         // 추상 메서드(구현부가 없는 메서드)
}

5. 접근 제어자

접근 범위

  • public > protected > default > private
제어자 같은 class 같은 package 자손 class 전체 class
public O O O O
proteced O O O X
default O O X X
private O X X X

즉 범위가 public이 제일 큰데 이는 전체에서 사용이 가능하며 점 점 뒤로 갈 수록 범위가 좁아지는 것을 볼 수 있습니다.

 

쉽게 말해서,

  • public: 어디든 사용 가능
  • protected: 같은 곳과 자손에선 어디든 사용 가능하지만 전체에선 접근 못함
  • default: 같은 곳에선 사용 가능하지만 자손에선 못사용함
  • private: 같은 클래스 안에서만 사용이가능하며 거의 철벽수준

이러한 접근제어자를 두는 이유는 무엇일까?

 

바로 클래스 내부 데이터들을 보호하기 위함입니다.

 

즉 public은 에러가 발생하면 전체 다 찾아봐야하지만 private는 같은 클래스 내에서 찾으면 됩니다.

 

캡슐화라고 하기도 합니다.

 

즉 클래스는 public으로 선언하고 내부 변수는 private로 선언 시 간접적으로 맴버변수를 컨트롤 할 수 있습니다.

 

public class Bol {
  public boolean a;

}

여기서 만약에 

Bol bol = new Bol();
bol.a = false;

이렇게 직접 접근을 하는데 만약 a가 false를 가져서는 안된다면 통제를 못하게 됩니다.

 

public class Bol {
  private boolean a;
  
  public boolean getA(){
  	return a;
  }
  
  public void setA(boolean a){
    this.a = a;
  }
}

로 캡슐화를 시켜주어서 내부 메서드들을 통해 값을 수정하도록 합니다.

 

또한 생성자의 접근제어를 할 수 있습니다.

 

즉 외부에서 인스턴스 생성을 막는 것이죠. 내부에서만 만들고 이를 반환하는 형태입니다.

 

class A {

  // getInstance()에서 사용될 수 있도록 인스턴스가 미리 생성되어야 하기 때문에 static
  private static A a = new A();
  private A() {

  }

  // 인스턴스를 생성하지 않고도 호출할 수 있어야하기 때문에 static
  public static A getInstance() {
    return a;
  }

}

 

 

 

'프로그래밍 언어 > Java' 카테고리의 다른 글

Java- 추상클래스  (0) 2019.07.10
Java - 다형성  (0) 2019.07.10
Java- 상속  (0) 2019.07.08
Java- 오버라이딩  (0) 2019.07.07
Java- 변수 초기화  (0) 2019.07.07