제어자(modifier)
클래스, 변수, 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여한다.
접근제어자 : public, protected, default, private
그 외 : static, final, abstract, native, transient, synchronized, volatile, strictfp
- 하나의 대상에 대해서 여러 제어자를 조합하여 사용하는 것이 가능하다.
- 접근제어자는 네가지 중 하나만 사용할 수 있다.
- 제어자 간의 순서는 관계없지만 주로 접근제어자를 제일 왼쪽에 놓는 경향이 있다.
static
클래스의, 공통적인 이라는 의미를 가지고 있다.
대상 | 의미 |
---|---|
멤버변수 | - 모든 인스턴스에 공통적으로 사용되는 클래스변수가 된다. - 클래스변수는 인스턴스를 생성하지 않고도 사용 가능하다. - 클래스가 메모리에 로드될 때 생성된다. |
메서드 | - 인스턴스를 생성하지 않고도 호출 가능한 static 메서드가 된다. - static메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 없다. |
초기화블럭 | - 클래스가 메모리에 로드될 때 단 한 번만 수행된다. - 주로 클래스변수(static 변수)를 초기화하는 데 사용된다. |
final
마지막의, 변경될 수 없는 이라는 의미를 가지고 있다.
대상 | 의미 |
---|---|
클래스 | - 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다. - 그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다. |
메서드 | - 변경될 수 없는 메서드가 된다. - final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다. |
멤버변수 지역변수 | - 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다. |
- 멤버변수가 final일 경우 선언과 함께 초기화하지 않고 생성자에서 단 한번 초기화할 수 있다.
1
2
3
4
5
6
7
8
9
class Item {
final int PRICE;
final String NAME;
Item(int price, String name) {
PRICE = price;
NAME = name;
}
}
abstract
추상의, 미완성의 라는 의미를 가지고 있다.
대상 | 의미 |
---|---|
클래스 | 클래스 내의 추상 메서드가 선언되어 있음을 의미한다. (추상 클래스) |
메서드 | 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다. |
1
2
3
abstract class AbstractClass { // 추상 클래스 (추상 메서드를 포함한 클래스)
abstract void move(); // 추상 메서드 (구현부가 없는 메서드)
}
- 추상 메서드가 없는 클래스에 abstract를 붙여서 추상 클래스로 만드는 경우도 있다.
- 메서드의 구현부에 아무 내용이 없어서 인스턴스를 생성해도 할 수 있는 게 없어서 인스턴스를 생성하지 못하게 붙여놓은 것이다.
- 다른 클래스가 이 클래스를 상속받아서 일부의 원하는 메서드만 오버라이딩해도 된다는 장점이 있다.
접근제어자 (access modifier)
멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 한다.
- 사용될 수 있는 곳 : 클래스, 멤버변수, 메서드, 생성자
- 접근 범위 : public > protected > default > private
- public은 접근 제한이 전혀 없다.
- protected는 패키지에 관계없이 다른 패키지의 자손클래스에서 접근할 수 있도록 하는 것이 제한목적이지만 같은패키지 내에서도 접근할 수 있다. 그래서 protected가 default보다 접근범위가 더 넓다.
- 접근 제어자가 지정되어 있지 않으면 접근제어자가 default임을 뜻한다.
대상 | 사용 가능한 접근 제어자 |
---|---|
클래스 | public, (default) |
메서드 멤버변수 | public, protected, (default), private |
지역변수 | 없음 |
접근제어자를 사용하는 이유
- 외부로부터 데이터를 보호하기 위해서
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
👉 둘 다 객체지향의 캡슐화에 해당하는 내용이다.
생성자의 접근제어자
사용할 수 있는 인스턴스의 개수를 제한하는 방법
- 생성자의 접근제어자를 private로 설정 (외부에서 생성자에 접근하지 못하도록)
- 대신 인스턴스를 생성해서 반환해주는 public static 메서드를 제공하여 외부에서 이 클래스의 인스턴스를 사용할 수 있도록 한다.
1
2
3
4
5
6
7
8
9
10
11
class Singleton {
// getInstance()에서 사용될 수 있도록 인스턴스가 미리 생성되어야 하므로 static 이어야 한다.
private static Singleton s = new Singleton();
private Singleton() {
// ...
}
// 인스턴스를 생성하지 않고도 호출할 수 있어야 하므로 static이어야 한다.
public static Singleton getInstance() {
return s;
}
}
상속할 수 없는 클래스라는 것을 알리는 방법
- 생성자의 접근 제어자를 private으로 설정 (자손 클래스에서 호출하지 못하도록)
- 클래스 앞에 final을 추가하여 상속할 수 없는 클래스라는 것을 알린다.
1
2
3
class final class Math {
private Math() {}
}
⭐ 제어자의 조합
대상 | 사용가능한 제어자 |
---|---|
클래스 | public, (default), final, abstract |
메서드 | 모든 접근 제어자, final, abstract, static |
멤버변수 | 모든 접근 제어자, final, static |
지역변수 | final |
제어자를 조합할 때 주의 사항
- 메서드에
static
과abstract
를 함께 사용할 수 없다. static 메서드는 인스턴스가 없어도 메서드 호출을 할 수 있는데 abstract는 구현부가 없기 때문이다.- 클래스에
abstract
와final
을 동시에 사용할 수 없다. 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고 abstract는 상속을 통해 완성되어야 한다는 의미이므로 서로 모순되기 때문이다.abstract
메서드의 접근제어자가private
일 수 없다. abstract 메서드에서는 자손 클래스에서 구현해주어야 하는데 접근 제어자가 private이면 자손클래스에서 접근할 수 없기 때문이다.- 메서드에
private
과final
을 같이 사용할 필요는 없다. 접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문이다. 둘 중 하나만 사용해도 의미가 충분하다.
출처📎
- 자바의 정석