1. 제어자란
- 클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여하는 것을 말한다.
- 제어자의 종류는 접근 제어자와 그 외의 제어자로 나눌 수 있다.
(1) 접근 제어자: public, protected, default, private
(2) 그 외: static, final, abstract, native, transient, synchronized, volatile, strictfp
2. final
- 클래스 앞에 붙으면: 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
(*조상이 되지 못함)
- 메서드 앞에 붙으면: 변경될 수 없는 메서드 또한 오버라이딩을 통해 재정의가 불가하다.
(*오버로딩은 가능하다.)
3. 생성자를 이용한 final멤버 변수의 초기화
- 일반적으로 변수를 final로 선언하면 바로 초기화를 해야한다. 그러나 인스턴스의 변수의 경우에는 생성자에서
초기화 되도록 할 수 있다.
- 그래서 아래의 코드처럼 생성자에서 변수 a에 대한 final을 초기화하지 않았다고 에러가 발생한다.
( 그러므로, 아래와 같이 생성자에서 초기화를 해주어야 한다. )
- 위에서 보았던 것처럼 생성자에서 final 변수를 초기화할 수 있다면 각 인스턴스마다 다른 값을 갖도록
하는 것이 가능하다.
4. abstract
- '미완성'의 의미를 가지고 있다. 그러므로 인스턴스를 생성할 수 없다.
- 클래스 앞에 붙으면: 클래스 내에 추상 메서드가 선언되어 있음을 의미한다.
- 메서드 앞에 붙으면: 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드를 의미한다.
5. 접근 제어자(public, protected, default, private)
( default: 클래스나 멤버 변수, 메서드, 생성자에 접근 제어자가 지정되어 있지 않으면, 컴파일러가 자동으로
추가해준다. )
( protected: 패키지에 상관 없이 상속관계에 있는 자손 클래스에서 접근할 수 있도록 하는 것이 제한 목적이지만,
같은 패키지 내에서도 접근이 가능하다. )
6. 접근제어자를 사용하는 이유 - (캡슐화 하는 이유)
(1) 외부로부터 데이터를 보호하기 위해서
(2) 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서
( 즉, 외부에 노출시키지 않음으로써 복잡성을 줄이는 목적이다. )
( *만약에 우리가 하나의 메서드를 변경할 때, 이 메서드를 변경 후에 문제가 없는지 확인해야 한다. )
( *public 이라면 전체를 살펴야 되고, private이라면 하나의 메서드만 보면 되고, default이라면 같은 패키지에서만
확인하면 된다. )
7. 예제(1) - 접근 제어자를 이용해 데이터 변경 및 오류를 막기
8. 생성자의 접근 제어자
- 생성자에 private를 지정함으로써, 외부로부터 인스턴스 생성을 막을 수 있다.
- 단, 클래스 내의 접근은 가능하므로, 클래스 내의 인스턴스는 생성할 수 있다.
- 대신 인스턴스를 대신 생성하여 반환해주는 아래와 같은 public static 메서드를 이용해야 한다.
( 이렇게 함으로써 얻을 수 있는 것은 생성자의 갯수를 하나로 정할 수 있으며 이것을 싱글톤이라고 부른다. )
( 또 한 가지 중요한 점은 생성자에 private를 선언한다면, 조상 클래스가 될 수 없다. )
( 그 이유는 자손 클래스의 인스턴스를 생성할 때 조상 클래스의 생성자를 호출하여야 되는데 private 때문에 호출이
불가능하기 때문이다. )
( 그래서 클래스 앞에 final을 더 추가하여 조상 클래스가 될 수 없다는 것을 알린다. )
- Math 클래스는 에초부터 생성자 앞에 private이다.
그 이유는 몇 개의 상수와 static 메서드로 구성되어 있기 때문에, 외부로부터의 불필요한 접근을 막기 위해
사용되었다.
( ex: Math.random() )
9. 제어자의 조합
(1) 메서드에 static과 abstract를 함께 사용할 수 없다.
(2) 클래스에 abstract와 final을 동시에 사용할 수 없다.
( abstract는 상속을 통해 확장하는 것이고, final은 상속을 금지하기 위해 있는 것이므로 모순된다. )
(3) abstract 메서드의 접근 제어자가 private일 수 없다.
(4) 메서드에 private와 final을 같이 사용할 필요가 없다.
( 둘의 의미가 같기 때문에, 둘 중 하나를 골라서 사용한다. )