
앞선 포스팅에서 이어집니다.
[java] 접근 제어자의 이해와 구현 예제(Access Modifier)
접근 제어자의 이해접근 제어자란?선언한 클래스와 클래스의 멤버(변수와 메서드 등)에 대해 외부에서 접근할 수 있는 범위를 제어하는 키워드입니다.객체 지향에서의 정보 은닉을 목적으로 각
doinitright.tistory.com
final 접근제한자
final : final로 선언된 클래스, 메서드, 변수는 수정 불가능하게끔 그 값과 의미를 고정하는 데 그 목적이 있다.
- final int 로 선언된 변수 : 최초 값이 초기화되면 그 이후에 값 변경 불가
- final로 선언된 메서드 : 오버라이드(@Overide) 제한
- final로 선언된 클래스 : 상속(extend) 제한
final class fClass { final int fInt; fClass(int fInt){this.fInt = fInt;} /* 최초 입력값을 fInt로 지정하는 생성자*/ } //class ffClass extends fClass {} * 오류 : final로 선언된 class는 상속받을 수 없음
final이 붙은 class인 fclass를 선언했다. 이 클래스는 상속 불가, 메서드는 오버라이드 불가, 변수는 값 초기화 후 변경불가.
public static void main(String[] args) { // final fClass f1 = new fClass(3); System.out.println(f1.fInt); // f1.fInt = 4; /* 오류 : final로 선언된 변수는 최초 초기화값에서 수정 불가 */ final int fint2; /* final 변수 선언 후 초기화 안한 상태 */ fint2 = 1; /* 변수값 최초 초기화 완료 */ // fint2 = 2; /* 오류 : 변수값 초기화 한 후 값 변경은 제한 */
final은 상속이 불가능하다는 점을 활용해 최초 선언 후 1회에 한해 고정값을 지정하는데 사용이 되겠다.
static 접근제한자
static : '정적, 정지된'의 의미로, 메소드와 변수 앞에 붙으면 하나의 메모리 주소에 저장된다.
→ 즉, 해당 클래스로 생성된 객체들의 static 변수와 메서드는 객체들끼리의 그 값을 공유한다.
class sClass { static int sInt = 3; sClass(){} sClass(int x){ sInt = x; /* static 변수는 this가 필요없음, 객체가 아닌 클래스로 직접 접근*/ } }
보시다시피 sClass의 생성자에서 매개변수 x를 인스턴스 변수인 this.sInt를 초기화하는 게 아닌, 클래스의 변수인 sInt를 초기화한다.
→ 모든 sClass의 인스턴스는 sInt의 값을 공유하기 때문에 객체가 아닌 클래스 내 변수로 바로 접근하는 개념이다.
main함수에서 실행하면서 추가적으로 확인해보자.
public static void main(String[] args) { sClass s1 = new sClass(); sClass s2 = new sClass(); System.out.println(sClass.sInt); /* 인스턴스가 아닌 클래스로 호출 */ System.out.println(s1.sInt); /* 권장되지 않음 : static 선언 변수가 인스턴스를 통해 참조 */ sClass.sInt = 4; /* 클래스의 static 변수 값 변화 3 → 4 */ System.out.println(s1.sInt); /* 객체의 변수 값 또한 변화한다. */ System.out.println(s2.sInt); s1.sInt = 2; /* 인스턴스에서의 static 변수로 접근, 변수 값 변화 4 → 2 */ System.out.println(s1.sInt); System.out.println(s2.sInt); }
sClass 타입의 객체 s1과 s2를 생성하였다.
보시다시피 sClass의 static 변수인 sInt를 참조할 때는 인스턴스가 아닌 클래스로 호출이 가능하다.
* 일반 객체와 동일하게 인스턴스 변수로 호출도 가능하지만 static으로 선언된 변수는 권장되지 않는다.
하지만 굳이 뜯어보기 위해 클래스로도 접근하고, 인스턴스로도 접근해 sInt의 값을 변경해 보겠다.
Input | Output | 설명 | |
1 |
System.out.println(sClass.sInt);
|
3 | sClass 선언 시 sInt 기본값 : 3 |
2 |
System.out.println(s1.sInt);
|
3 | sclass로 생성된 s1, s2의 sInt 기본값 : 3 |
3 |
sClass.sInt = 4;
|
- | sclass로 접근해 sInt 값 변경 : 3 → 4 |
4 |
System.out.println(s1.sInt);
|
4 | static 변수의 값은 동일 클래스에서 공유됨 |
5 |
System.out.println(s2.sInt);
|
4 | static 변수의 값은 동일 클래스에서 공유됨 |
6 |
s1.sInt = 2;
|
- | 인스턴스에서 static 변수로 접근해 sInt 값 변경 |
7 |
System.out.println(s1.sInt);
|
2 | static 변수의 값은 동일 클래스에서 공유됨 |
8 |
System.out.println(s2.sInt);
|
2 | static 변수의 값은 동일 클래스에서 공유됨 |
클래스던 인스턴스던 그 값을 변경하면 동일 클래스 내 인스턴스의 static 변수는 변경된 같은 값을 공유함을 확인 가능하다.
private 접근제한자
private : 동일한 패키지건 다른 패키지건 private으로 선언된 클래스는 생성이 제한된다.
* 오로지 클래스 내부에서만 객체를 생성 및 호출할 수 있다.
* 싱글톤 패턴에 유용하게 사용되는 클래스이다.
class pClass { /* 싱글톤 패턴 시 유용하게 사용하는 private */ private pClass() {} /* 생성자를 private으로 선언 시 new 활용 생성 제한 */ private static pClass one; public static pClass getInstance() { /* 클래스 내부 메소드를 통해서만 인스턴스 생성이 가능하다. */ if (one == null) { /* 정적 변수 one을 통해 1개의 인스턴스만 생성 가능하게끔 제한 */ one = new pClass(); } return one; } }
위의 코드는 생성자를 private으로 선언함으로써 외부에서 객체 생성을 제한했으며,
클래스 내부의 정적변수 one을 통해 외부에서 getInstance() 메서드 호출 시
최초 1회만 pClass 객체 생성을 허용하게끔 설정할 수 있다.
public class Privatetest { public static void main(String[] args) { pClass p1 = new pClass(); /* 오류 : private으로 선언된 생성자는 new로 인스턴스 생성 불가 */ pClass p1 = pClass.getInstance(); /* getInstance 메소드를 통해 객체 최초 1회만 생성 가능 */ } }
'DEV > Java' 카테고리의 다른 글
[java] 멀티스레드(Multi thread)의 이해 / 구현 (0) | 2023.08.01 |
---|---|
[java] java 객체의 직렬화와 역직렬화 (Serialization / Deserialization) (0) | 2023.07.30 |
[java] 접근 제어자의 이해와 구현 예제(Access Modifier) (0) | 2023.07.26 |
[java] java 다형성, 슈퍼/서브(부모/자식) 클래스 형변환 (0) | 2023.07.26 |
[java] java 상속과 오버라이딩 (0) | 2023.07.25 |