접근 제어자

고동현·2024년 6월 5일
0

JAVA

목록 보기
6/22

접근제어자 예제

public class Speaker {
    int volume;
    Speaker(int volume){
        this.volume = volume;
    }

    void volumeUp(){
        if(volume>=100){
            System.out.println("음량을 증가 할 수 없습니다. 최대 음량입니다.");
        }else{
            volume+=10;
            System.out.println("음량을 10 증가합니다.");
        }
    }

    void volumeDown(){
        volume-=10;
        System.out.println("volumedown 호출");
    }

    void showVolume(){
        System.out.println("현재음량:"+volume);
    }
}

Speaker객체를 만들고, volume을 100이상 못넘어가게 만들었다.

public class SpeakerMain {
    public static void main(String[] args) {
        Speaker speaker = new Speaker(90);
        speaker.showVolume();
        speaker.volumeUp();;
        speaker.showVolume();
        speaker.volumeUp();
        speaker.showVolume();

        //volume필드 직접 접근 -> 접근제어자 없음
        speaker.volume=200;
        speaker.showVolume();
    }
}

메서드 호출로는 100이상 올라가지 못하지만, 필드에 직접접근하면 필드를 바꿀수 있다. -> 접근제어자가 없기 때문이다.

그러면 해당 객체의 필드에 외부에서 직접 접근하지 못하게 하려면 private으로 막으면된다.

private int volume;

접근제어자 종류

  • private: 모든 외부 호출을 막는다.
  • default: 같은 패키지 안에서 호출 허용
  • protected: 같은패키지 안에서 호출 허용 + 패키지가 다르더라도 상속관계 호출 가능
  • public: 모든 호출을 허용

private -> default -> protected -> public

접근제어자의 위치는 클래스, 메서드, 필드, 생성자에 위치가 가능하다.

접근제어자 예제

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 innerAccess(){
        System.out.println("내부 호출");
        publicField = 100;
        defaultField = 200;
        privateField = 300;
        publicMethod();
        defaultMethod();
        privateMethod();
    }
}

해당 패키지 a에 들어있음을 확인하자.

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.innerAccess();
    }
}

클래스 레벨

클래스에는 public,default만 사용가능
public 클래스는 반드시 파일명과 이름이 같아야한다.
하나의 자바 파일 -> public 클래스는 1개 -> default class는 무한정

패키지 a에 만들었다. public class 1개, 접근제어자 명시를 안한 default클래스가 여러개있다.

package access.a;

public class PublicClass {
    public void main(String[] args) {
        PublicClass publicClass = new PublicClass();
        DefaultClass1 class1 = new DefaultClass1();
        DefaultClass2 class2 = new DefaultClass2();
    }

    class DefaultClass1{

    }
    class DefaultClass2{

    }
}
package access.b;

import access.a.PublicClass;

public class PublicClass2 {
    public static void main(String[] args) {
        PublicClass publicClass = new PublicClass();
       // Defaultclass1 defaultclass1 = new DefaultClass1(); 패키지가 다르므로 default class 접근오류
    }
}

캠슐화

객체에는 속성(데이터)와 기능(메서드)가 있다.

데이터는 항상 private을 사용하여서 외부에서 접근을 막고 메서드를 통해서 접근하게 해야한다.

기능(메서드)는 외부에서 꼭 필요한 메서드만 public으로 열고,객체 내부에서 사용하는 메서드는 private으로 설정한다.

예제,

public class BankAccount {
    private int balance;
    public BankAccount(){
        balance=0;
    }

    public void deposit(int amount){
        if(isAmountValid(amount)){
            balance+=amount;
        }else{
            System.out.println("유효하지 않는 금액입니다.");
        }
    }

    public void withdraw(int amount){
        if(isAmountValid(amount) && balance - amount >=0){
            balance-=amount;
        }else{
            System.out.println("유효하지 않는 금액이거나 잔액이 부족합니다.");
        }
    }

    public int getBalance(){
        return balance;
    }

    private boolean isAmountValid(int amount) {
        return amount >0;
    }
}

balance를 private으로 설정
deposit,withdraw같이 꼭 필요한 기능 public,
isAmountValid같은 객체 내부에서 사용하는 메서드는 private,
balance를 접근하기위해서는 항상 메서드 getBalance를 이용

profile
항상 Why?[왜썻는지] What?[이를 통해 무엇을 얻었는지 생각하겠습니다.]

0개의 댓글