Java - 접근제한자, Getter Setter

김민1·2023년 2월 8일
3

Java

목록 보기
3/8

접근제한자란?

말 그대로 접근을 제한하기 위해 사용
여기서 말하는 접근은 클래스 및 인터페이스 그리고 이들이 가지고 있는 멤버의 접근을 뜻함

쓰는 이유?

클래스와 인터페이스를 다른 패키지에서 사용하지 못하도록 막을 필요가 있을 때,
객체 생성을 막기 위해 생성자를 호출하지 못하게 하도록 하거나
필드나 메소드를 사용하지 못하게 하기 위함

접근제한자의 종류

  1. public 접근제한자
  2. protected 접근제한자
  3. private 접근제한자
  4. default 접근제한자

클래스 접근 제한

클래스 선언 시, 해당 클래스를 같은 패키지 내에서만 사용할 것인지 다른 패키지에서도 사용할 수 있도록 할 것인지 결정해야 함
클래스는 public, default 접근 제한을 가짐

default 접근 제한

클래스 선언 시 public 접근 제한자를 생략하면 클래스는 default 접근 제한을 갖게 됨.
default 접근 제한을 가지면 같은 패키지에서는 아무런 제한이 없지만
다른 패키지에선 사용할 수 없게 됨.

public 접근 제한

클래스 선언 시 public 접근 제한자를 붙이면 클래스는 public 접근 제한을 갖게 됨.
public 접근 제한을 가지면 같은 패키지든 다른 패키지든 아무런 제한 없이 사용 가능.
-> 다른 개발자가 사용할 수 있도록 라이브러리 클래스로 개발시 반드시 public 접근 제한으로
-> 인터넷에 배포되는 라이브러리 클래스도 모두 public 접근 제한을 가지고 있음


생성자 접근 제한

객체 생성 -> new 연산자로 생성자 호출 but 어디에서나 호출할 수 있는 것이 아님
생성자가 어떤 접근 제한을 갖는가에 따라 호출 가능 여부가 결정
생성자는 public, protected, default, private 접근 제한을 가짐.

클래스에 생성자를 선언하지 않으면 컴파일러에 의해 기본 생성자가 추가되는데, 이 때 기본 생성자의 접근 제한은 클래스의 접근 제한과 동일.

public 접근 제한

모든 패키지에서 아무런 제한 없이 생성자 호출 가능

protected 접근 제한

default 접근 제한과 유사함 but 다른 패키지에 속한 클래스가 해당 클래스의 자식 클래스라면 생성자 호출 가능

default 접근 제한

같은 패키지에선 아무런 제한 없이 생성자 호출 가능 but 다른 패키지에선 호출 불가능

private 접근 제한

동일한 패키지이건 다른 패키지이건 상관없이 생성자 호출 제한됨
오직 클래스 내부에서만 생성자 호출 및 객체 생성 가능


필드와 메소드 접근 제한

필드와 메소드 선언 시 클래스 내부에서만 사용할 것인지 패키지 내에서만 사용할 것인지 다른 패키지에서도 사용할 수 있도록 할 것인지 필드와 메소드가 어떤 접근 제한을 갖느냐에 따라 결정
필드와 메소드 또한 public, protected, default, private 접근 제한을 가짐.

public 접근 제한

모든 패키지에서 필드와 메소드 사용 가능

protected 접근 제한

default 접근 제한과 유사함 but 다른 패키지에 속한 클래스가 해당 클래스의 자식 클래스라면 사용 가능

default 접근 제한

같은 패키지에선 아무런 제한 없이 사용 가능 but 다른 패키지에선 사용 불가능
필드와 메소드 선언 시 접근 제한자를 생략하면 default 접근 제한을 갖게 됨.

private 접근 제한

동일한 패키지이건 다른 패키지이건 상관없이 필드와 메소드 사용 불가
오직 클래스 내부에서만 사용 가능


Getter와 Setter 메소드

일반적으로 객체 지향 프로그래밍에서는 외부에서 마음대로 변경할 경우 객체의 무결성이 깨질 수 있기 때문에 객체의 필드를 객체 외부에서 직접적으로 접근하는 것을 막음.

이러한 문제점을 해결하기 위해 메소드를 통해서 필드를 변경하는 방법을 선호함
필드는 외부에서 접근할 수 없도록 막고,
메소드는 공개해서 외부에서 메소드를 통해 필드에 접근하도록 유도
메소드는 매개값을 검증해서 유효한 값만 객체의 필드로 저장할 수 있기 때문
이 역할을 하는 메소드가 Setter 메소드

필드값을 직접 사용하면 부적절한 경우도 있기 때문에
외부에서 객체의 데이터를 읽을 때도 메소드를 사용하는 것이 좋음
이런 경우에는 메소드로 필드값을 가공한 후 외부로 전달하면 됨
이 역할을 하는 메소드가 Getter 메소드

필드 타입이 boolean일 경우에는 Getter는 get으로 시작하지 않고 is로 시작하는 것이 관례.

클래스 선언 시 가능하다면 필드를 private로 선언해서 외부로부터 보호하고 필드에 대한
Setter와 Getter를 작성해 필드값을 안전하게 변경하고 사용하는 것이 좋음.

Getter와 Setter 메소드를 사용하는 이유

  1. 객체의 무결성을 보장하기 위해서
    ex) 자동차의 속력이 0보다 낮을 수 없지만 필드에 직접 접근할 수 있다면 0보다 낮은 값을 줄 수가 있게 됨 -> 무결성 깨짐

  2. 객체의 필드에 private 같은 접근 제한자를 둬서 객체지향의 목적인 정보은닉이 가능해짐


마치며

단순히 setter로 데이터를 수정할 경우 어떤 부분을 어디서 수정하는지 알 수 없어서
무분별한 사용은 오히려 무결성을 깰 수도 있다고 합니다.

데이터 무결성에 더 적합한 주제는 Builder 패턴이나 SOLID 개방폐쇄원칙이라는데 아직은 공부를 안 한 부분이나 추후 게시할 예정입니다.

수정할 사항이나 추가적인 내용이 있다면 댓글이나 이메일을 남겨주세요.

아래는 공부할 때 사용했던 코드입니다.


객체 생성

(생성자)

class StarbucksDrink {
    private int shot = 0;
    private boolean isIce = false;
    private int syrup = 0;
    private int caramel = 0;
    private int vanilla = 0;
    private boolean isWhipping = false;
    private boolean isChoco = false;

    public StarbucksDrink (int shot, boolean isIce) {
        this.shot = shot;
        this.isIce = isIce;
    }
    public StarbucksDrink (int shot, int syrup, boolean isIce) {
        this.shot = shot;
        this.syrup = syrup;
        this.isIce = isIce;
    }

    public StarbucksDrink ( int shot, boolean isChoco, boolean isWhipping, boolean isIce) {
        this.shot = shot;
        this.isChoco = isChoco;
        this.isWhipping = isWhipping;
        this.isIce = isIce;
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        StarbucksDrink drink2 = new StarbucksDrink(2, true);
    }

}

(Getter Setter)

class StarbucksDrinkSetterGetter {
    private int shot;
    private boolean isIce;
    private int syrup;
    private int caramel;
    private int vanilla;
    private boolean isWhipping;
    private boolean isChoco;

    public int getShot() {
        return shot;
    }

    public void setShot(int shot) {
        this.shot = shot;
    }

    public boolean isIce() {
        return isIce;
    }

    public void setIce(boolean ice) {
        this.isIce = ice;
    }

    public int getSyrup() {
        return syrup;
    }

    public void setSyrup(int syrup) {
        this.syrup = syrup;
    }

    public int getCaramel () {
        return caramel;
    }
    public void setCaramel(int caramel) {
        this.caramel = caramel;
    }
    public int getVanilla() {
        return vanilla;
    }

    public void setVanilla(int vanilla) {
        this.vanilla = vanilla;
    }

    public boolean isWhipping() {
        return isWhipping;
    }

    public void setWhipping(boolean whipping) {
        isWhipping = whipping;
    }

    public boolean isChoco() {
        return isChoco;
    }

    public void setChoco(boolean choco) {
        isChoco = choco;
    }


}

public class Main {
    public static void main(String[] args) throws Exception {
        StarbucksDrinkSetterGetter drink1 = new StarbucksDrinkSetterGetter();
        drink1.setShot(2);
        drink1.setIce(true);
    }

}

코드 출처 : https://www.beemo.co.kr/entry/%EC%9E%90%EB%B0%94-%EA%B0%9D%EC%B2%B4%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-3%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95

profile
일단 부딪혀보자

2개의 댓글

comment-user-thumbnail
2023년 2월 8일

최고십니다

1개의 답글