TIL/JAVA

[JAVA] 접근 제어자

아람2 2024. 12. 25. 14:21
반응형

접근 제어자 

접근 제어자 이해 

자바는 public, private 같은 접근 제어자 Access Modifier 를 제공한다 

접근 제어자를 사용하면 해당 클래스에서 특정 필드나 메서드에 접근하는 것을 허용하거나 제한할 수 있다 

 

🐣 다른 클래스에서 접근하지 못하도록 하려면 private 을 앞에 선언해 주면 된다 🐣

private 접근 제어자는 모든 외부의 호출을 막기 때문에, 해당 클래스 내부에서만 호출할 수 있다 

좋은 프로그램은 적절한 제약을 제공하는 프로그램이다 
package access;

public class Speaker {
    private int volume;
	...
}
package access;

public class SpeakerMain {
    public static void main(String[] args) {
        Speaker speaker = new Speaker(90);
        ...
        // 필드에 직접 접근 시도
        System.out.println("volume 200 으로 변경 시도");
        speaker.volume = 200;
        speaker.showVolume();
    }
}

// 실행 결과 
java: volume has private access in access.Speaker

 

접근 제어자 종류 

private 모든 외부 호출을 막는다 

default (package-private) 같은 패키지 안에서 호출은 허용한다 

protected 같은 패키지 안에서 호출은 허용한다, 패키지가 달라도 상속 관계의 호출은 허용한다 

public 모든 외부 호출을 허용한다 

package-private 

접근 제어자를 명시하지 않으면 default 접근 제어자가 적용된다 

default 라는 용어보다 package-private 가 더 정확한 표현이다 

왜냐하면 동일한 패키지 내의 다른 클래스에서만 접근이 가능하기 때문이다 

접근 제어자 사용 위치 

접근 제어자는 필드와 메서드, 생성자에 사용된다 

추가로 클래스 레벨에도 일부 접근 제어자를 사용할 수 있다 

🐣 지역 변수는 사용하지 못 한다, 어차피 그 지역 안에서만 쓰는 변수이기 때문에 의미 없음 🐣

접근 제어자 사용 - 필드, 메서드 

같은 패키지 안에 있는 필드와 메서드는 public, default 로 호출 가능하고, private 호출 불가하다 

다른 패키지에 있는 필드와 메서드는 public 만 호출 가능하고 default 와 private 은 호출 불가하다 

생성자도 접근 제어자 관점에서 메서드와 같다, 참고!

접근 제어자 사용 - 클래스 레벨 

클래스 레벨의 접근 제어자는 public, default 만 사용할 수 있다 

public 클래스는 반드시 파일명과 같아야 한다 

하나의 자바 파일에 public 클래스는 하나만 등장할 수 있다 

하나의 자바 파일에 default 접근 제어자를 사용하는 클래스는 무한정 만들 수 있다 

 

Public 은 다른 패키지에서도 접속이 가능하지만, Private 은 같은 패키지에서만 접속이 가능하다 

package b 에서 package a 의 Private Class 를 접근하려고 하려고 하면 아래와 같이 컴파일 에러가 발생한다 

 

캡슐화 Encapsulation 

캡슐화는 데이터와 해당 데이터를 처리하는 메서드를 하나로 묶어서 외부에서의 접근을 제한하는 것을 말한다 

캡슐화를 통해 데이터의 직접적인 변경을 방지하거나 제한할 수 있다 

정리하면, 속성과 기능을 하나로 묶고, 외부에 꼭 필요한 기능만 노출하고 나머지는 모두 내부로 숨긴다 

 

1. 데이터 숨기기 

객체에는 속성 (데이터) 과 기능 (메서드) 가 있다, 가장 필수로 숨겨야 하는 것은 데이터이다 

객체 내부의 데이터를 외부에서 함부로 접근하게 두면, 클래스 안에서 데이터를 다루는 모든 로직을 무시하고

데이터를 변경할 수 있다, 따라서 캡슐화가 깨진다 

객체의 데이터는 객체가 제공하는 기능인 메서드를 통해서 접근해야 한다 

2. 기능 숨기기 

사용자 입장에서 꼭 필요한 기능만 외부에 노출하고, 나머지 기능은 모두 내부로 숨기는 것이 좋다 

-> 데이터는 모두 숨기고, 꼭 필요한 기능만 노출하는 것이 좋은 캡슐화이다 

📌 선생님의 팁

if-else 구문도 직관적이고 좋지만, 검증 로직과 실행 로직을 분리하여 

검증을 통과한 조건에서만 실행 로직이 수행되도록 코딩하는 방식도 좋은 방법이다 

🐣 코드의 가독성과 유지보수성을 높일 수 있고, 확장성도 좋다고 한다 🐣 

    public void increment() {
        // 검증 로직
        if (count >= max) {
            System.out.println("최대값을 초과할 수 없습니다");
            return;
        }
        // 실행 로직
        // 검증을 통과한 조건에서만 실행 로직 수행
        count++;
    }

 

📌 단축키 Generate 

cmd + n 생성자를 포함한 이것저것을 만들 수 있는 창을 보여주고, 선택한 옵션을 만들어준다 

 

📌 단축키 Context Actions 

Option + Enter (Alt + Enter) 선택한 표현식이나 메서드 호출의 결과를 변수로 자동 생성해준다 

 

📌 단축키 Context Actions 

Option + Alt + V (Ctrl + Alt + V) 

 

접근 제어자 예제 

/* ShoppingCartMain */
package access.ex;

public class ShoppingCartMain {
    public static void main(String[] args) {
        // 접근 제어자를 사용해서 데이터를 캡슐화하세요
        // 해당 클래스는 다른 패키지에서도 사용할 수 있어야 합니다
        // 장바구니에는 상품을 최대 10개만 담을 수 있다
        // 10개 초과 등록 시, "장바구니가 가득 찼습니다" 출력
        ShoppingCart cart = new ShoppingCart();

        Item item1 = new Item("마늘", 2000, 2);
        Item item2 = new Item("상추", 3000, 4);

        cart.addItem(item1);
        cart.addItem(item2);

        cart.displayItems();
    }
}
/* Item.java */
package access.ex;

public class Item {
    private String name;
    private int price;
    private int quantity;

    public Item(String name, int price, int quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }

    // 상품 이름을 반환하는 메서드
    public String getName() {
        return name;
    }

    // 총 가격을 구하고 반환하는 메서드
    public int getTotalPrice() {
        return price * quantity;
    }
}
/* ShoppingCart.java */
package access.ex;

public class ShoppingCart {
    private Item[] items = new Item[10];
    private int itemCount;

    // 장바구니에 상품을 10개까지만 넣는 메서드
    public void addItem(Item item) {
        if (itemCount >= items.length) {
            System.out.println("장바구니가 가득 찼습니다");
            return;
        }
        // 장바구니에 하나씩 넣기
        items[itemCount] = item;
        itemCount++;
    }

    public void displayItems() {
        int totalPrice2 = 0;
        System.out.println("장바구니 상품 출력");
        for (int i=0; i < itemCount; i++) {
            Item item = items[i];
            System.out.println("상품명 : "+item.getName()+", 합계 : "+item.getTotalPrice());
            // calculateTotalPrice 안 쓰고 이거 쓰면 됨
            totalPrice2 += item.getTotalPrice();
        }
//        System.out.println("합계 : "+calculateTotalPrice());
        System.out.println("합계 : "+totalPrice2);
    }

    // 총 가격 합을 구하는 메서드인데 굳이 필요 없음
    private int calculateTotalPrice() {
        int totalPrice = 0;
        for (int i=0; i < itemCount; i++) {
            Item item = items[i];
            totalPrice += item.getTotalPrice();
        }
        return totalPrice;
    }
}

 

갑자기 배열이 너무 헷갈린다 내일 다시 공부해야지 

반응형

'TIL > JAVA' 카테고리의 다른 글

[JAVA] Map Interface  (0) 2024.12.29
[JAVA] 어노테이션 사용  (0) 2024.12.26
[JAVA] 패키지  (1) 2024.12.19
[JAVA] 생성자  (0) 2024.12.11
[JAVA] 어노테이션 Annotation  (2) 2024.12.10