IT 개발노트
제어자 본문
1. 제어자(modifiers)
1.1 제어자란?
- 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여한다.
- 제어자는 크게 접근 제어자와 그 외의 제어자로 나뉜다.
- 하나의 대상에 여러 개의 제어자를 조합해서 사용할 수 있으나, 접근제어자는 단 하나만 사용할 수 있다.
1.2 static - 클래스의, 공통적인
- static이 사용될 수 있는 곳 : 멤버변수, 메서드, 초기화 블럭
1.3 final - 마지막의, 변경될 수 없는
- final이 사용될 수 있는 곳 - 클래스, 메서드, 멤버변수, 지역변수
1.4 생성자를 이용한 final 멤버변수 초기화
- final이 붙은 변수는 상수이므로 보통은 선언과 초기화를 동시에 하지만, 인스턴스변수의 경우 생성자에서 초기화 할 수 있다.
class Card {
final int NUMBER; // 상수지만 선언과 함께 초기화 하지 않고
final String KIND; // 생성자에서 단 한번만 초기화할 수 있다.
static int width = 100;
static 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);
// c. NUMBER = 5; // 에러발생!!!
System.out.println(c.KIND);
System.out.println(c.NUMBER);
}
1.5 abstract - 추상의, 미완성의
- abstract가 사용될 수 있는 곳 - 클래스, 메서드
[참고] 추상메서드가 없는 클래스도 abstract를 붙여서 추상클래스로 선언하는 것이 가능하기는 하지만 그렇게 해야 할 이유는 없다.
1.6 접근 제어자(access modifier)
- 멤버 또는 클래스에 사용되어, 외부로부터의 접근을 제한한다.
- 접근 제어자가 사용될 수 있는 곳 : 클래스, 멤버변수, 메서드, 생성자
1.7 접근 제어자를 이용한 캡슐화
--> A패키지의 클래스에서 B패키지의 클래스 멤버변수에 접근할 때는 B패키지의 메서드를 통해서만 가능하다. 직접 접근을 못하고 패키지의 내부로직은 내부에서만 확인 가능하도록 캡슐화하는것.
1.8 생성자의 접근 제어자
- 일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치한다.
- 생성자에 접근 제어자를 사용함으로써 인스턴스의 생성을 제한할 수 있다.
final class Singleton {
// getInstance()에서 사용될 수 있도록 인스턴스가 미리 생성되어야 하므로 static이어야 한다.
private static Singleton s = new Singleton();
private Singleton() { // 생성자
// ...
}
public static Singleton getInstance() {
if(s==null) {
s = new Singleton();
}
return s;
}
// ...
}
class SingletonTest {
public static void main(String args[]) {
// Singleton s = new Singleton(); // 에러!!!
Singleton s1 = Singleton.getInstance(); // 정상작동
}
}
--> 생성자의 접근 제어자를 private로 하게되면, 다른 클래스의 조상이 될 수 없다. 만일 자손 클래스에서 인스턴스를 생성하게 되면 기본생성자를 컴파일러가 자동으로 생성하게 되는데, private로 막아놓으면 생성자를 만들 수 없기 때문이다. 그래서 final을 통해서 상속을 통해서 확장할 수 없다고 알려주는 것이 좋다.
1.9 제어자의 조합
- 메서드에 static과 abstract를 함께 사용할 수 없다.
-> static메서드는 몸통(구현부)이 있는 메서드에만 사용할 수 있기 때문이다.
- 클래스에 abstract와 final을 동시에 사용할 수 없다.
-> 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고, abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문이다.
- abstract메서드의 접근제어자가 private일 수 없다.
-> abstract메서드는 자손클래스에서 구현해주어야 하는데 접근 제어자가 private이면, 자손클래스에서 접근할 수 없기 때문이다.
- 메서드에 private와 final을 같이 사용할 필요는 없다.
-> 접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문이다. 이 둘 중 하나만 사용해도 의미가 충분하다.
--> 같이 사용할 수는 있지만 의미가 없다는 것.