[JAVA] 접근제어자 & 캡슐화

림민지·2025년 2월 25일

Today I Learn

목록 보기
10/62

(인프런 김영한 선생님 강의를 보고 기록했습니다)
자바의 접근제어자에 대해 알아보자!

🤔 접근 제어자는 무엇일까?

접근 제어자의 종류

4가지 종류가 있다

public : 어디에서든지 불러와서 사용 가능
private : 모든 호출 다 안됨. 자기만 쓸거라고 하는거
default : 같은 패키지 안에서 사용 가능함
protect : 같은 패키지 안에서는 사용할 수 있지만, 다른 패키지에서는 불가능(상속 관계의 호출은 가능)

😎 접근 제어자 사용하기

이제 개념을 알았으니 직접 사용해보자!

패키지의 위치를 항상 유의하기

1. 메서드 & 필드

default는 같은 패키지면 다 접근 가능하다.
package 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);
    }

    public void privateMethod(){
        System.out.println("privateMethod 호출 " + privateField);
    }

    public void innerAccess(){
        System.out.println("call inner");
        publicField = 100;
        defaultField =200;
        privateField = 300;

        publicMethod();
        defaultMethod();
        privateMethod();
    }
}

위의 코드에서 볼 수 있다싶이, 같은 패키지, 같은 클래스 안에서 호출은 모두모두 가능하다.

하지만 같은 패키지에 위치하더라도,

package a;

public class AccessInnerMain {
    public static void main(String[] args) {
        AccessData accessData = new AccessData();
        //public 호출
        accessData.publicField = 1;
        accessData.privateMethod();

        //같은 패키지 default 호출
        accessData.defaultField = 2;
        accessData.defaultMethod();

        //private
//        accessData.privateField = 3;
//        accessData.privateMethod();

        accessData.innerAccess();
    }
}

접근 제어자가 private라면 이는 다른 클래스에서 호출이 불가능하다.

2. 클래스

  1. 클래스 레벨의 접근 제어자에는 default, public 만 사용 가능하다! (private, protected는 사용 불가함)
  2. 반드시 파일명 = class명
    : 파일명과 클래스명이 같아야하는데, 이때 하나의 파일에 public 클래스는 오직 1개!(default는 무제한)

package A 안에서 PublicClass를 정의하여 코드를 만들어보자

package A;

public class PublicClass {
    public static void main(String[] args) {
        DefaultClass1 defaultClass1 = new DefaultClass1();
    }
}

class DefaultClass {
}

같은 패키지 내의 class를 불러오는 것이니 당연히 DefaultClass 를 가져와 사용할 수 있을 것이다!
하지만, 만약 pacakge B에서 DefaultClass를 불러오려한다면? 오류가 난다.
==> default class 는 다른 패키지에서 불러와 사용할 수 없다!


💊 캡슐화 Encapsulation

: 객체 지향 프로그래밍의 중요한 개념 중 하나이다.
비슷한 기능을 하는 애들끼리 하나로 묶고, 중요한 것들은 숨기고, 필요한 것만 노출시켜서 사용할 수 있게하는 것이다.

  • 데이터가 보호되지 못하고 외부에서 접근하는 것을 막을 수 있기 때문이다.

데이터는 모두 숨기고, 기능은 꼭 필요한 것만 노출하자

은행 계좌를 관리하는 예제를 함께 보고 이해해보자!

package b;

public class BankAccount {
    private int balance;

    public BankAccount(){
        balance = 0;
    }

    //public method
    public void deposit(int amount){
        if (isAmountVaild(amount)){
            balance +=amount;
        }
    }

    private boolean isAmountVaild(int amount){
        //amount>0일때만 반환
        return amount>0;
    }

    public void withdraw(int amount){
        if (isAmountVaild(amount)&&balance-amount>=0) {
            balance-=amount;
        }else {
            System.out.println("not vaild");
        }
    }

    public int getBalance(){
        return balance;
    }

}

package b에 BankAccount라는 클래스를 만들어보자.

  • 은행에서 돈은 내부에서 관리되어야한다
    private balance
  • 하지만 고객에게 잔액은 알려주어야하니 관련된 기능을 추가하여 balance를 보호하자
    public BankAccount()
  • 잔액이 -가 되면 안되므로, 잔액이 0보다 클때를 구분할 수 있도록 하자 -> 이 로직은 밖으로 노출되면 안된다
    private boolean isAmountVaild(int amount){return amount>0}

이제 이 class를 사용해서 은행에서 조회하는 시스템을 만들어보자

package access.b;

public class BankMain {
    public static void main(String[] args) {
        BankAccount bankAccount = new BankAccount();
        bankAccount.deposit(1000);
        bankAccount.withdraw(500);

        System.out.println("your amount is : "+bankAccount.getBalance());
    }
}
  • 같은 패키지 b에서 작성해야한다~!
  • 메소드 직접 balance를 호출하지 않고, getBalance 메소드를 호출하여 가져올수 있따~! (물론 Private로 balance를 설정했으므로 호출되지도 않는다)

이런식으로 캡슐화를 사용하면 데이터는 보호하고 적절한 기능만 가져올 수 있다!
기능을 분리해서 넣었기때문에 다른 사람이 보더라도 쉽게 알아볼 수 있는건 덤><

🔮 사용 이유 (중요성)

접근제어자와 캡슐화를 함께 사용하면,

  • 데이터를 안전하게 보호
  • 해당 기능을 사용하는 복잡도 감소
profile
@lim_128

0개의 댓글