Java - 접근제어자(Access Modifier)

JS · 15 Sep 2020

Java의 접근제어자(Access Modifier)에 대해서 알아봅니다. 접근제어자는 클래스 내부 또는 외부에서 어떤 메소드나 필드(변수)에 접근을 제어합니다. 여기서 접근은 메소드를 호출하거나, 변수의 값을 읽거나 설정하는 것을 말합니다. 심지어 클래스도 접근을 제어하여, 외부에서 생성하게 하거나 못하게 하거나 결정할 수 있습니다.

Java의 접근 제어자는 private, protected, public, default로 4개가 있습니다. 각각의 접근 제어자가 어떤 상황에서 접근을 허용하고, 어떤 상황에서 접근을 못하도록 하는지 알아보겠습니다.

Default

다음과 같이 int 앞에 아무것도 명시하지 않으면 default로 접근제어자가 설정됩니다. 아래 코드에서는 aaa라는 변수와 defaultMehotd() 메소드를 default 접근 제어자로 정의하였습니다. 또한, 클래스도 default로 정의하였습니다.

package example.accessmodifiers;

class AAA {
    int aaa = 0;
    void defaultMehotd() {
    }
}

default 접근제어자로 설정된 메소드와 변수, 그리고 클래스는 동일한 패키지에서 접근이 가능합니다. AAA 클래스는 example.accessmodifiers라는 패키지 아래 정의되었습니다. 따라서 example.accessmodifiers 아래의 모든 클래스 안에서 AAA 클래스, 변수, 메소드를 접근할 수 있습니다.

package example.accessmodifiers;

public class DefaultExample {
    DefaultExample() {
        AAA obj = new AAA();
        obj.defaultMehotd();
        obj.aaa = 10;
        System.out.println(obj.aaa);
    }
}

Public

다음과 같이 BBB 클래스에 aaa라는 변수와 publicMethod()라는 메소드를 정의하였습니다. 또한 클래스도 public으로 정의하였습니다.

package example.accessmodifiers.utils;

public class BBB {
    public int aaa = 0;
    public void publicMehotd() {
    }
}

위와 같이 public으로 설정된 클래스, 변수, 메소드는 외부 어디서나 접근이 가능합니다. 심지어 다른 패키지에서도 접근이 됩니다.

package example.accessmodifiers;

import example.accessmodifiers.utils.BBB;

public class PublicExample {
    PublicExample() {
        BBB obj = new BBB();
        obj.publicMehotd();
        obj.aaa = 10;
        System.out.println(obj.aaa);
    }
}

Protected

Protected로 접근제어자를 설정하면, 이 클래스를 상속하는 자식 클래스에서 접근이 가능합니다. 또한, 같은 package에 있는 클래스에서 접근이 가능합니다. 그 외의 경우는 접근이 제한됩니다.

package example.accessmodifiers;

public class CCC {
    protected int aaa = 0;
    protected void protectedMehotd() {
    }

    private void privateMethod() {
    }
    public void publicMethod() {
    }
}

다음과 같이 ProtectedExample 클래스는 위에서 정의한 클래스 CCC를 상속합니다. 그렇기 때문에 CCC에서 정의한 protected 변수 및 메소드 접근이 가능합니다. public은 어디서나 접근이 가능하기 때문에 호출할 수 있습니다. 하지만 private으로 정의한 메소드 또는 변수는 접근이 안됩니다.

package example.accessmodifiers;

public class ProtectedExample extends CCC {
    ProtectedExample() {
        aaa = 10;
        protectedMehotd();  // ok
        publicMethod();  // ok
        // privateMethod();  -> compile error
    }
}

Private

다음과 같이 private으로 변수 및 메소드를 정의하였습니다.

public class DDD {
    private int aaa = 0;

    private void privateMethod() {
        aaa = 20;
    }

    public void publicMethod() {
        privateMethod();
        aaa = 10;
    }
}

private으로 선언된 변수나 메소드는 클래스 내부에서는 자유롭게 접근이 가능합니다. 하지만 외부에서는 접근이 불가능합니다.

package example.accessmodifiers;

public class PrivateExample {
    PrivateExample() {
        DDD obj = new DDD();
        obj.publicMethod();
        // obj.aaa = 10;  -> compile error
        // obj.privateMethod();  -> compile error
    }
}

비교

아래 표는 접근 가능한 접근 제어자의 영역을 보여줍니다.

Access Modifier Class Package Subclass World
public O O O O
protected O O O X
default O O X X
private O X X X

정리

접근 제어자(Access Modifier)에 대해서 알아보았습니다. 접근 제어자를 사용하는 이유는 어떤 변수나 메소드의 접근을 다르게 설정하여 코드를 작성하는 사람의 의도를 전달하기 위해서 입니다.

만약 private으로 어떤 변수를 선언하였다면, 이 변수는 외부에 노출시키고 싶지 않다는 의도를 코드를 읽는 사람들에게 전달할 수 있습니다. 또한 실수로 이 변수를 접근하여 에러가 발생하거나 유지보수가 어려운 코드로 변하게 되는 것을 예방할 수 있습니다.

만약 default로 선언하였다면 이 메소드나 변수는 동일한 패키지에서만 자유롭게 접근이 가능합니다. 이런 코드들을 라이브러리로 제공하면, 이 라이브러리를 사용하는 외부 클래스는 default에 접근할 수 없습니다. 그렇기 때문에 외부 코드와 의존성 낮출 수 있습니다. 이런 이유로 내부 코드를 변경할 때 쉽게 변경할 수 있습니다.

댓글을 보거나 쓰려면 이 버튼을 눌러주세요.
codechachaCopyright ©2019 codechacha