일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- IOC
- springwebmvc
- lambda
- 빌드툴
- 링킹
- 클린코드
- 토비의스프링3.1
- springboot
- 메이븐
- 토비의스프링
- Kotlin for Java Developers
- AutoConfiguration
- java
- 자바
- exception
- Spring
- JPA
- String
- beanfactory
- FunctionalInterfaces
- hibernate
- DispatcherServlet
- ORM
- 링커
- Immutable
- 프록시
- ApplicationContext
- 컴퓨터시스템
- gradle
- DesignPattern
- Today
- Total
엔지니어로 가는 길
Java 접근 제어자와 접근의 의미 본문
Java의 접근 제어자는 아래와 같다.
private: 클래스 내부에서만 접근 가능
default(package-private): 클래스 내부와 패키지 내의 다른 클래스에서 접근 가능
protected: default에 더해 다른 패키지라도 자식 클래스일 경우 접근 가능
public: 외계에서도 접근 가능
클래스 접근제어자
클래스에는 접근제어자 package-private와 public만 가능하다. (내부 클래스(nested class)의 경우 다른 접근 제어자를 쓸 수 있는데 이는 다음에 살펴보도록 한다.)
패키지 외부에서는 package-private 클래스가 보이지 않는다. 따라서 상속받을 수도 없고, 객체를 생성할 수도 없다.
package-private 클래스가 자식 클래스에서도 접근이 안된다고 말하는 것은 잘못된 말이다. 같은 패키지 내의 자식 클래스라면, 자식 클래스이든 아니든 같은 패키지 내에 있으므로 접근이 가능하고, 다른 패키지 내에 있다면 애초에 보이지 않기 때문에 자식 클래스로 만들 수 조차 없기 때문이다.
멤버 접근제어자
멤버에는 네 가지 접근제어자 모두 가능하다. 먼저 멤버에 접근하는 방법을 확실히 가고 가는 게 좋을 것 같다.
non-static 멤버(인스턴스 멤버)에 접근하는 방법
@ (자신의 멤버일 경우) this 키워드와 '.' 연산자를 통해 접근하는데 이는 생략 가능하다.
@ 객체를 생성한 뒤 '.' 연산자를 통해 접근한다.
@ 자식 클래스인 경우 클래스 내부의 non-static 메소드에서 부모 객체를 생성하지 않아도 접근할 수 있다.
static 멤버(클래스 멤버)에 접근하는 방법
@ 객체 생성 없이도 "클래스이름.멤버"로 바로 접근 가능하다.
멤버 접근 방법을 숙지했다면 접근의 의미를 살펴보도록 하자. (static 멤버 접근은 헷갈릴 것 없이 명확하므로 non-static만 살펴본다.)
접근의 의미(private)
Test2 클래스 내부에서 Test2 객체를 생성하여 a에 접근하는 것은 가능하다.
하지만 다른 클래스에서 같은 방식을 쓰면 에러가 난다. test2라는 이름으로 Test2 객체를 만들어서 test2.a로 접근했으니까 클래스 내부에서 접근한거 아닐까?
이는 '클래스 내부'라는 말과 '객체와 객체 멤버 사이의 관계'를 헷갈린 것이다. 객체 멤버는 객체 위에만 존재해야하므로 위의 'non-static 멤버에 접근하는 방법'에서 살펴봤듯 자신의 멤버가 아니고, 부모 자식 관계도 아니라면 객체를 생성해서 test2.a로만 접근해야 한다. 접근제어자와 관계없이 이건 멤버에 접근하려면 당연히 그래야만 하는 것이다. 접근제어자에서 말하는 클래스 내부라는 말은 말 그대로 멤버에 접근하려는 위치를 말한다. 어디서 'test2.a'를 사용하는가? Test2인가 아닌가? Test2가 아니라면 private 멤버인 a에는 접근할 수가 없다.
접근의 의미(protected)
Test 클래스에 a가 protected으로 선언되어 있다.
다른 패키지에서 Test를 상속받은 뒤에 'test.a'로 접근하는데 에러가 난다. protected가 다른 패키지의 자식 클래스에서 접근이 가능하다고 할 때 접근의 의미는 위와 같이 객체를 생성해서 멤버 변수에 접근할 수 있음을 뜻하는 것이 아니라 아래의 test 메소드처럼 클래스 내부의 메소드에서 부모 클래스의 protected 멤버를 바로 가져와서 쓰는 게 가능하다는 것을 말하는 것 같다.
여태까지 접근의 의미를 잘못 이해하고 있었다는 게 참 충격적이다. 다시 간략히 정리하는 게 좋겠다.
non-static 멤버에 접근하는 방법은
1. (자신의 멤버일 경우) this 키워드와 '.' 연산자를 통해 접근하는데 이는 생략 가능하다.
2. 객체를 생성한 뒤 '.' 연산자를 통해 접근한다.
3. (부모 자식 관계인 경우) 자식 클래스 내부의 non-static 메소드에서 부모 객체를 생성하지 않아도 접근할 수 있다.
헷갈리는 부분을 중심으로 정리하자면,
@ class A의 public 멤버 B는 다른 패키지의 클래스에서도 A 객체를 생성하여 멤버를 B를 '.' 연산자로 접근할 수 있다.
@ class A의 private 멤버 B는 오직 class A 안에서만 접근할 수 있다. 이때 말하는 접근은 1번과 2번이다.
@ class A의 package-private 멤버 B는 같은 패키지일 경우 2번으로 접근이 가능하다.
@ class A의 protected 멤버 B는 다른 패키지일 경우 부모 자식 관계라면 3번으로 접근이 가능하다. (2번으로도 접근할 수 없다.)
그러니까 자기 자신이라면 객체를 생성하지 않고도 멤버를 참조할 수 있고, 같은 패키지 내라면 private가 아닌 접근제어자 멤버 모두 객체를 생성해서 '.' 연산자로 접근할 수 있고, 다른 패키지라면 protected인 경우에는 부모-자식 관계를 이용해서만 접근할 수 있고, public인 경우에는 객체를 생성해서 '.' 연산자로 접근하는 게 가능하다.
'프로그래밍 > Java' 카테고리의 다른 글
JVM 런타임 메모리 영역 (0) | 2020.05.02 |
---|---|
Java 중첩 클래스 (11) | 2020.04.23 |
논리 연산자 &, |와 &&, ||의 차이 (0) | 2020.04.10 |
언어로서의 자바, 플랫폼으로서의 자바 (0) | 2020.03.29 |
JAVA 두 개 이상의 정렬 기준을 지원하는 방법: Comparator (0) | 2020.02.08 |