남궁성님의 Java의 정석 3판 "Chapter 07 객체지향 프로그래밍 2"를 읽고 저의 방식대로 정리 한 글입니다.
제어자는 클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여한다. 제어자의 종류는 크게 접근 제어자와 그 외의 제어자로 나눌 수 있다.
public, protected, default, privatestatic, final, abstract, native, transient, synchronized, volatile, strictfpstatic + 멤버 변수static + 메서드static + 초기화 블럭final + 클래스final + 메서드final + 멤버변수, final + 지역변수abstract + 클래스abstract + 메서드접근 제어자는 멤버 또는 클래스에 사용되어, 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 한다. 접근 제어자가 지정되어 있지 않다면, 접근 제어자가 default임을 뜻한다. 클래스는 접근 제어자 중 public을 붙이거나 default로만 쓸 수 있다.
private : 같은 클래스 내에서만 접근이 가능하다.default : 같은 패키지 내에서만 접근이 가능하다.protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근이 가능하다.public : 접근 제한이 전혀 없다.접근 제어자를 사용하는 이유는 클래스의 내부에 선언된 데이터를 보호하기 위해서이다. 또 다른 이유로는 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서이다. 객체지향개념의 캡슐화(encapsulation)를 하는 방법이라고 할 수도 있다. 접근 제어자를 private으로 하여 외부에서 직접 접근하지 못하도록 하고 겟터(getter)와 셋터(setter)를 이용해 접근하고 변경하도록 설계할 수 있다.
생성자에 접근 제어자를 사용함으로써 인스턴스의 생성을 제한할 수 있다. 보통 생성자의 접근 제어자는 클래스의 접근 제어자와 같지만, 다르게 지정할 수도 있다. 하나의 예시로, 생성자를 통해 직접 인스턴스를 생성하지 못하게 하고 public 메서드를 통해 인스턴스에 접근하게 함으로써 사용할 수 있는 인스턴스의 개수를 제한할 수 있다.
생성자의 접근 제어자를 private으로 지정하면, 외부에서 생성자에 접근할 수 없으므로 인스턴스를 생성할 수 없게 된다. 대신 인스턴스를 생성해서 반환해주는 public 메서드를 제공함으로써 외부에서 이 클래스의 인스턴스를 사용하도록 할 수 있다. 이 메서드는 인스턴스를 사용하지 않고도 호출할 수 있어야 하므로 public인 동시에 static이어야 한다.
생성자가 private인 클래스는 다른 클래스의 조상이 될 수 없다. 자손클래서에서 생성자를 호출하는 것이 불가능하기 때문이다. 그래서 해당하는 클래스 앞에 final을 붙여 상속할 수 없는 클래스라는 것을 알리는 것이 좋다.
final class Singleton {
// getInstance()에서 사용될 수 있도록 인스턴스가 미리 생성되어야 하므로 static이어야 한다.
private static Singleton s = new Singleton();
// private 생성자
private Singleton() { ... }
// 인스턴스를 반환해주는 메서드. 인스턴스를 생성하지 않고도 호출할 수 있어야 하므로 static이어야 한다.
public static Singleton getInstance() {
if (s == null)
s = new Singleton();
return s;
}
}
대상에 따라 사용할 수 있는 제어자
public, (default), final, abstractpublic, (default), protected, private, final, abstract, staticpublic, (default), protected, private, final, staticfinal제어자를 조합해서 사용할 때 주의해야 할 사항