Java 문법 (7) - 접근 제어자
Java 문법 (7) - 접근 제어자
접근 제어자
자바는 public
, private
같은 접근 제어자(access modifier)를 제공합니다. 접근 제어자를 사용하면 해당 클래스 외부에서 특정 필드나 메서드에 접근하는 것을 허용하거나 제한할 수 있습니다.
접근 제어자 종류
private
: 모든 외부 호출을 막음default(package-private)
: 같은 패키지 안에서 호출만 허용protected
: 같은 패키지 안에서의 호출과, 상속관계의 호출은 허용public
: 모든 외부의 호출을 허용
접근 제어자 예시 - 필드, 메서드
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
// access.a 패키지의 AccessData 클래스
package access.a;
public class AccessData {
public int publicField;
int defaultField;
private int privateField;
public void publicMethod(){
System.out.println("publicMethod 호출 " + publicField);
}
void defaultMethod(){
System.out.println("defaultMethod 호출 " + defaultField);
}
private void privateMethod(){
System.out.println("privateMethod 호출 " + privateField);
}
public void innerMethod() {
System.out.println("내부 호출");
publicField = 100;
defaultField = 200;
privateField = 300;
publicMethod();
defaultMethod();
privateMethod();
}
}
access.a
라는 패키지 안에 AccessData
라는 클래스를 만들어서 각각 public
, default
, private
필드와 메서드를 선언했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// access.a 패키지의 AccessinnerMain 클래스
package access.a;
public class AccessinnerMain {
public static void main(String[] args) {
AccessData data = new AccessData();
// public 호출 가능
data.publicField = 1;
data.publicMethod();
// default 같은 패키지여서 호출 가능
data.defaultField = 2;
data.defaultMethod();
// private 호출 불가능
//data.privateField = 3;
//data.privateMethod();
// 내부를 건드리는 함수
data.innerMethod();
}
}
같은 패키지인 access.a
안에서 AccessinnerMain
클래스를 만들고, AccessData
객체를 생성해서 사용하는 테스트를 했습니다. public
은 호출 가능하고, default
도 같은 패키지에 있기 때문에 호출이 가능했으며, private
는 접근 불가능합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// access.b 패키지의 AccessOuterMain 클래스
package access.b;
import access.a.AccessData;
public class AccessOuterMain {
public static void main(String[] args) {
AccessData data = new AccessData();
// public 호출 가능
data.publicField = 1;
data.publicMethod();
// default 다른 패키지여서 호출 불가능
//data.defaultField = 2;
//data.defaultMethod();
// private 호출 불가능
//data.privateField = 3;
//data.privateMethod();
// 내부를 건드리는 함수
data.innerMethod();
}
}
이번엔 다른 패키지인 access.b
패키지에서 AccessOuterMain
클래스를 만들어서 AccessData
객체를 생성했습니다. public
은 호출이 가능하지만, 패키지가 다르기 때문에 default
는 호출 불가능했고, private
또한 호출이 불가능합니다.
접근 제어자 - 클래스 레벨
클래스 레벨의 접근 제어자는 public
, default
만 사용할 수 있습니다. 또한 public 클래스는 반드시 파일명과 이름이 같아야하고, 하나의 자바 파일에 하나의 public 클래스만 존재할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package access.a;
// public 클래스는 파일명과 이름이 같아야 한다.
// 클래스 레벨의 접근 제어자는 public, default만 있다.
public class PublicClass {
int test;
public static void main(String[] args) {
PublicClass publicClass = new PublicClass();
// 같은 파일 접근 가능
DefaultClass1 class1 = new DefaultClass1();
DefaultClass2 class2 = new DefaultClass2();
publicClass.test = 1;
}
}
class DefaultClass1{
}
class DefaultClass2{
}
예시처럼 public 클래스는 파일에 하나만 존재합니다. public으로 선언한 PublicClass는 파일명과 이름이 같아야합니다. 나머지 DefaultClass1, DefaultClass2 는 현재 패키지에서만 사용 가능한 default 클래스입니다.
캡슐화
캡슐화는 객체지향 프로그래밍의 중요한 개념 중 하나입니다. 캡슐화는 데이터와 해당 데이터를 처리하는 매서드를 하나로 묶어서 외부에서의 접근을 제한하는 방법을 말합니다. 캡슐화를 통해서 데이터의 직접적인 변경을 방지하거나 제한할 수 있습니다. 쉽게 이야기해서 속성과 기능을 하나로 묶고, 외부에는 꼭 필요한 기능만 노출하고 나머지는 모두 내부로 숨기는 것입니다.
객체에는 속성(데이터)
과 기능(매서드)
가 있습니다. 속성은 필수로 숨겨야합니다. 자동차의 속도를 사용자가 직접 변경하는게 아닌 것 처럼 속도(데이터)는 숨겨두고 엑셀을 밟는다는 기능을 통해 속도를 변경할 수 있게 해야합니다.
객체의 기능중에도 외부에서는 사용하지 않고 내부에서만 사용되는 기능들이 있습니다. 이러한 기능들도 private로 숨기는 것이 좋습니다.
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
32
33
34
35
36
37
38
// 캡슐화 예제
package access;
// 캡슐화 예제
public class BankAccount {
private int balance; // 속성 private로 숨기기
public BankAccount() {
balance = 0;
}
// 입금 기능 (public 외부에 노출)
public void deposit(int amount){
if (isAmountValid(amount)){
balance += amount;
}else {
System.out.println("유효하지 않은 금액입니다.");
}
}
// 출금 기능(public 외부 노출)
public void withdraw(int amount){
if(isAmountValid(amount) && balance - amount >= 0){
balance -= amount;
} else {
System.out.println("유효하지 않은 금액이거나, 잔액이 부족합니다.");
}
}
// 잔액 확인 기능(public 외부 노툴)
public void showBalance(){
System.out.println("현재 잔액: " + balance);
}
// 들어온 금액이 올바른지 판단 (private 내부에서만 사용하는 코드 숨김)
private boolean isAmountValid(int amount){
return amount > 0;
}
}
캡슐화
예제 코드입니다. balance
속성은 private
로 내부에 숨겼습니다. deposit, withdraw, showBalance
는 입금, 출금, 잔액확인
등 사용자가 써야할 꼭 필요한 기능으로 public
을 사용해 외부에서 접근할 수 있게 합니다. isAmountValid
는 입력으로 들어온 금액이 유효한지 판단하는 기능으로, 내부에서만 사용되기 때문에 private
로 숨겨줍니다.