Java를 사용하다 보면 메소드나 변수 심지어 클래스 앞에 public, private, final, abstract등을 볼 수 있습니다. 이러한 것을 modifier(제어자)라고 합니다. 오늘은 제어자에 대해서 이야기 해보려고 합니다.
Modifier란?
제어자는 클래스, 변수 또는 메서드에 함께 사용되어 부가적인 의미를 부여합니다. 제어자의 종류로는 크게 접근 제어자와 그 외 제어자로 나눌 수 있습니다.
- 접근 제어자: public, protected, default, private
- 그 외 제어자: static, final, abstract 등
- 주로 제어자는 클래스나 멤버변수, 메서드에 사용되고 하나의 대상에 여러 제어자를 조합하여 사용이 가능합니다. 그러나 접근 제어자는 접근에 관련된 제어이기에 하나의 대상에 여러 접근 제어자를 사용하는 것은 불가능합니다.
접근 제어자
접근 제어자는 말 그래도 접근을 제한하는 역할하는 제어자입니다. 접근 제어자는 클래스, 멤버변수, 메서드, 생성자에서 사용할 수 있습니다. 종류로는 다음과 같습니다.
public
: 접근제한이 없어 어디서나 클래스나 메서드 변수등을 접근할 수 있습니다.protected
: 같은 패키지 내에서, 또한 다른 패키지의 자손 클래스에서 접근이 가능합니다.default
: 같은 패키지 내에서만 접근이 가능합니다.private
: 같은 클래스 내에서만 접근이 가능합니다.
private → default → protected → public 순으로 접근할 수 있는 범위가 넓어집니다. 위에서 접근 제어자를 클래스, 멤버변수, 메서드에서 사용이 가능하다고 하였습니다. 하지만 모든 접근 제어자를 다 사용할 수 있는 것은 아닙니다.
- Class : public, (default)
- method : public, protected, (default), private
- member variable : public, protected, (default), private
접근 제어자의 종류와 어떻게 사용해야 하는지에 대해 알아보았습니다. 그럼 이제 왜 접근제어자를 사용하는지에 대해 알아보겠습니다
접근 제어자를 사용하는 이유
접근 제어자를 이용하여 외부로부터 접근을 제한할 수 있습니다. 이로인해 데이터를 감출 수 있고 흔히 객체지향에서 말하는 캡슐화(encapsulation)를 할 수 있습니다. 이처럼 접근제어자를 사용하는 이유는 클래스와 클래스 내부에 선언된 데이터를 보호하기 위해서 사용합니다. 또한 내부에서만 사용하는 데이터의 경우 보호 목적도 있지만, 외부로 노출을 안 시킴으로써 복잡성을 줄일 수도 있습니다.
Static
static
의 사전적 의미를 보면 '정적인' 이러 의미가 있습니다.
class를 만들고 해당 class를 이용하여 인스턴스를 만들면 보통 인스턴스 변수는 인스턴스마다 다른 값을 갖습니다. 하지만 static 키워드가 멤버 변수 앞에 붙으면 모든 인스턴스가 같은 값을 갖게 됩니다. 그 이유는 하나의 변수를 모든 인스턴스가 공유하기 때문입니다. static 멤버변수는 모든 인스턴스가 공유하는 클래스 변수가 되기에 클래스가 메모리에 로드될 때 생성됩니다. 또한 인스턴스를 생성하지 않고도 사용이 가능합니다.
static이 붙은 메서드도 마찬가지입니다. 인스턴스를 생성하지 않고 호출이 가능합니다. 따라서 static method안에서 instance 멤버 변수들을 사용하면 안됩니다. instance 변수는 클래스를 instace화하였을 때 생성이 되므로 static method에서 사용하게 되면 오류가 발생합니다. 반대로 instance method에서 staic 변수를 사용하는 것은 가능합니다. 클래스가 instance가 되었다는 말이 class가 이미 메모리에 올라가 있기에 static 변수도 메모리에 존재합니다.
다음과 같은 코드를 통해서 static 변수와 method는 인스턴스화 하지 않아도 사용 가능한 것을 볼 수 있습니다.
final
final
은 사전적 의미로 '마지막의', '최후의' 라는 의미를 가지고 있습니다. 이 제어자는 클래스, 메서드 ,멤버변수, 지역변수 등 거의 모든 대상에 사용될 수 있습니다. '마지막의'라는 사전적 의미처럼 변수에 사용되면 값을 변경할 수 없는 상수가 되고, 메서드에 사용되면 Overriding을 할 수 없습니다. Overloading은 가능합니다. 클래스에 사용되면 자신을 상속받는 자손 클래스를 정의하지 못합니다.
final이 붙은 멤버 변수의 초기화는 생성자를 이용해서 초기화를 할 수 있습니다. 생성자를 이용하여 초기화를 못하게 된다면 모든 instance가 같은 값을 가져야 하기에 static과 별다른 차이가 없습니다. final로 지정한 멤버 변수는 변경할 수 없는 상수이지 모든 인스턴스에서 같이 공유하는 값이 아닙니다.
사용법은 다음과 같이 사용하면 됩니다.
abstract
abstract
는 '추상적인' 이라는 의미를 가지고 있습니다. 말 그대로 추상 메서드나 추상 클래스를 선언할 때 사용됩니다. 추상 클래스의 경우 추상 메서드가 하나라도 존재하면 추상 클래스이기에 abstract 제어자를 붙여줘야 합니다. 추상 메서드가 없을 때도 클래스에 abstract 제어자를 선언할 수 있지만 굳이 그렇게 사용하지는 않습니다.
추상 메서드는 쉽게 말해 추상적으로 두루뭉실하게 메서드를 정의하는 것을 말하면 실제 동작 완성은 해당 class를 상속하여 완성합니다. 따라서 위에서 언급한 static과 final은 abstract 제어자와 같이 사용하면 안됩니다. 그 이유는 final의 경우 메서드를 Override할 수 없다고 하였는데 abstract은 method를 override하여 완성시켜야 하기 때문에 모순이 됩니다. 또한 static 메서드의 경우 인스턴스화가 필요없이 클래스에서 바로 사용이 가능해야하지만 abstract은 선언만 하였기 때문에 같이 사용될 수 없습니다.
※ 틀린 내용이나 궁금한 내용은 댓글 부탁드립니다.
참고자료
https://codechobo.tistory.com/22
[[자바의 정석 기초편] 요약집 pdf
'프로그래밍 언어 > Java' 카테고리의 다른 글
[JUnit5] test code에서 Array 비교(assertarrayEquals vs assertEquals vs assertTrue) (0) | 2023.01.04 |
---|---|
[JAVA] Java란? (JVM 아키텍처 (2)) (0) | 2022.05.12 |
[JAVA] Java란? (JVM 아키텍처 (1)) (0) | 2022.05.11 |