제어자란?
제어자(modifier)는 변수와 메서드의 선언부에 함께 사용되어 부가적인 의미를 나타낸다.
제어자는 2가지 종류로 나뉜다.
- 접근제어자
public
,protected
,default
,private
- 접근제어자 외의 것들
static
,final
,abstract
,native
,transient
,synchronized
,volatile
,strictfp
제어자는 하나의 대상에 하나만 쓸수 있는 것이 아니라 하나의 대상에 대해서 여러 제어자를 조합하여 사용하는 것이 가능하다.
Static
static
은 클래스의 라는 의미와 공통적인이라는 의미를 가지고 있다.
이러한 static
이 붙은 메서드나 맴버변수는 인스턴스에 관계없이 같은 값을 가진다
static
은 멤버변수, 메서드, 초기화 블럭에 사용된다.
static
(클래스 변수) 와 인스턴스 변수의 차이점이 궁금하다면 이곳에 자세히 나와있다.
- 멤버변수에서 사용이 되면 클래스변수가 되어서 모든 인스턴스에서 공통적으로 사용할 수 있다. 또한, 인스턴스를 생성하지 않고도 사용이 가능하다.
- 메서드에서 사용이 되면 인스턴스를 생성하지 않고도 호출이 가능하다. 또한,
static
메서드 내에서 인스턴스 멤버들을 직접 사용할 수 없다.
Final
final
은 마지막의 또는 변경될 수 없는이라는 의미를 가지고 있다.
final
도 2장의 상수를 다루면서 설명하였다. 설명
final
은 클래스, 메서드, 멤버변수, 지역변수에서 사용할 수 있다.
- 클래스에서 사용이 되면 확장 될 수 없는 클래스가 된다. 그래서 다른 클래스의 부모클래스가 될 수 없다.
- 메서드에서 사용이 되면 오버라이딩을 통해 재정의 될 수 없다.
- 변수에서 사용이 되면 값을 변경할 수 없는 상수가 된다.
final
은 항상 선언과 동시에 초기화를 하는 변수이다.
하지만 인스턴스변수인 경우는 생성자에서 초기화를 할 수 있다.
class Car {
final String NAME;
Car(String name){
NAME = name;
}
}
생성자를 사용하면 인스턴스마다 각기 다른값을 final
로 가지게 할 수 있다.
Abstract
abstract
는 미완성의 의미를 가지고 잇다. abstract
가 붙으면 추상이라는 말이 따라온다.
abstract
는 클래스와 메서드에 사용이 가능하다.
abstract
가 클래스에 붙으면 추상클래스라고 말하고 이는 설계도에 비유하면 미완성 설계도라고 만 알고가자
추상클래스는 나중에 따로 작성할 것이다.
abstract
가 메서드에 붙으면 추상메서드라고 말하고 이는 이러이러한 기능이 있다는 것만 설명하고 기능을 구현을 하지 않은 것이다.
선언부는 작성되어있지만 구현부는 작성이 되지 않은 것이다.
abstract class Car{
abstract void move();
}
이는 아무런 구현이 없어 쓸모없어 보이지만 이 클래스를 상속받는 클래스에게 원하는 기능을 오버라이딩을 해야한다
접근 제어자 (access modifier)
접근 제어자는 멤버 또는 클래스에 사용하여 이를 외부에서 접근하지 못하도록 제한하는 역할을 한다.
접근 제어자의 종류는 다음과 같다.
- private : 같은 클래스 내에서만 접근이 가능하다.
- default : 같은 패키지 내에서만 접근이 가능하다.
- protected : 같은 패키지 안에서 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.
- public : 모두 접근이 가능하다.
넓은쪽 에서 좁은 쪽 순서로는 다음과 같다.
public > protectd > (default) > private
캡슐화(encapsulation)
접근 제어자를 사용하는 이유는 클래스의 내부에 선언된 데이터를 보호하기 위해서이다.
이를 보통 캡슐화라고 한다.
또한, 클래스 내부에서만 사용하는 맴버들을 private
로 지정하여 외부에 노출시키지 않음으로 복잡성을 줄이는 것 또한 캡슐화라고한다.
캡슐화된 값들을 사용하기 위해서는 Getter/Setter라는 메소드를 이용하여 값을 접근한다.
class Car{
private String name;
String getName(){
return name;
}
void setName(String name){
this.name = name;
}
}
Getter
는 멤버 변수의 값을 반환하는 역할을 한다.
Setter
는 멤버 변수의 값을 설정하는 역할을 한다.
Singleton 패턴
Singleton은 디자인 패턴줄하나로 인스턴스를 단 하나만 생성할 수 있게 하는 방법이다.
이는 생성자에 접근 제어자를 사용하는 방식으로 이루어져있다.
생성자의 접근 제어자를 private
로 지정한다면 외부에서 생성자에 접근할 수 없으므로 인스턴스를 생성할 수 없게 된다.
class Car{
private static Car car = new Car(); // static을 사용
private Car(){
/...
}
}
public static void main(String[] argc){
Car car = new Car() // -> 불가능 Car()는 private이기 때문이다.
}
생성자가 private이기 때문에 더이상의 인스턴스를 생성할 수 없다.
private
이기 때문에 인스턴스에 접근조차 할수가 없다. 그러므로 class 안에서 생성된 인스턴스를 불러올 방법을 찾아야한다.
// 해결방법
class Car{
private static Car car = new Car(); // static을 사용
private Car(){
/...
}
public static Car getInstance(){
return car;
}
}
getInstance()
메서드를 사용하여 미리생성된 car
인스턴스를 반환한다.
또한, static
으로 생성되었기 때문에 main함수에서 접근이 가능하다.
이는 생성자가 private
이기 때문에 다른 클래스의 조상이 될 수 없다.
이러한 싱글톤 패턴에는 문제점이있다.
- 단 하나의 인스턴스를 사용하기 때문에 동시에 객체의 변수를 변경하고 요청한다면 오류가 생길 수 있다.
- 싱글톤 패턴을 구현하는 코드 자체가 많이들어간다.
private
생성자 이기때문에 자식을 만들기가 어려워진다.
이러한 문제점들이 존재한다.
제어자의 조합
제어자는 조합이 가능한데 마음대로 쓸수 있는 것들은 아니다.
제어자는 다음과 같은 사항을 준수해야한다.
- 메서드에
static
과abstract
를 함께 사용할 수 없다.abstract
는 메서드를 구현하지 않지만static
은 메서드 구현이 필요하기 때문이다.
- 클래스에
abstract
와final
을 동시에 사용할 수 없다.abstract
는 항상 상속을 받아야한다는 의미이다. 하지만final
은 클래스에서 상속을 받을수 없다는 의미 이기 때문에 서로 상반된다.
abstract
메서드의 접근 제어자가private
일 수 없다.abstact
는 상속을 받아서 자식클래스에서 구현이 되야한다. 하지만private
일 때는 자식클래스에서abstact
메서드를 접근할 수 없기 때문이다.
- 메서드에
private
과final
을 같이 사용할 필요는 없다.private
와final
을 쓰면 서로 의미가 같아져서 하나만 써도 의미가 충분하다. (메소드의 오버라이딩 금지)
Reference
- 자바의 정석
'Java > Java' 카테고리의 다른 글
[Java/Study] 추상클래스 (0) | 2021.09.11 |
---|---|
[Java/Study] 다형성 (0) | 2021.09.10 |
[Java/Study] Package 와 Import 및 터미널로 자바 실행방법 (0) | 2021.09.08 |
[Java/Study] 오버라이드 (0) | 2021.09.07 |
[Java/Study] 상속 (0) | 2021.09.07 |