Java 접근 제어자 - 변수, 메소드

변수와 메소드 사용하는 상황에서 접근 제어자를 확인한다.

💡
실습에서 패키지 위치를 주의 깊게 살펴보도록 한다.

AccessData 접근 제어자 준비하기

access
└data
    └AccessData.class (+)

AccessData.java

package access.data;

public class AccessData {

    public int publicVar;
    int defaultVar;
    private int privateVar;

    public void publicMethod() {
        System.out.println("by publicMethod " + publicVar);
    }

    void defaultMethod() {
        System.out.println("by defaultMethod " + defaultVar);
    }

    private void privateMethod() {
        System.out.println("by privateMethod " + privateVar);
    }

    public void innerMethod() {
        System.out.println("== by innerMethod== ");
        publicVar = publicVar + 1;
        defaultVar = defaultVar + 1;
        privateVar = privateVar + 1;
        publicMethod();
        defaultMethod();
        privateMethod();
    }
}

AccessData 패키지 용도

  • 패키지 위치는 package access.data 이다.
  • public, default, private 순서대로 변수와 메소드에 사용
  • innerMethod 메소드는 AccessData 클래스의 메소드로 자신의 public, default, private 변수와 메소드에 사용한 접근 제어자를 접근할 수 있다.

AccessInner - 내부 패키지의 클래스

같은 패키지의 AccessInner 클래스로 AccessData 클래스를 불려와 main 함수로 실행해보도록 한다.

access
└data
    ├AccessData.class
    └AccessInner.class (+)

AccessInner.java

package access.data;

public class AccessInner {
    public static void main(String[] args) {
        AccessData data = new AccessData();

        // public 변수와 메소드 불려오기
        data.publicVar += 1;
        data.publicMethod();

        // defualt 변수와 메소드 불려오기
        data.defaultVar += 2;
        data.defaultMethod();

        // private 변수와 메소드 불려오기
        // data.privateVar += 3;
        // data.privateMethod();

        // AccessData 클래스 내부 호출해보기
        data.innerMethod();
    }
}

출력결과

by publicMethod 1
by defaultMethod 2
== by innerMethod== 
by publicMethod 2
by defaultMethod 3
by privateMethod 1
  • 패키지 위치는 모두 동일한 package access.data; 패키지이다.
  • public 접근 제어로 설정한 변수와 메소드 모두 호출 가능하다.
  • default 접근 제어로 설정한 변수와 메소드 모두 호출 가능하다. AccessInner 클래스도 동일한 package access.data; 패키지로 가리켜 default 접근 제어로 접근할 수 있다.
  • private 는 동일한 클래스가 아니기에 호출할 수 없다.
  • AccessData.innerMethod() 메소드는 public 이고, AccessData 객체에 포함되어 메소드로 호출할 수 있었다. 호출한 경우 메소드 내부의 private 변수와 메소드를 접근하여 출력해주고 있다.

AccessOuter - 외부 패키지의 클래스

외부 패키지를 만들어 해당 클래스를 만들어 주도록 한다.

access
├data
│ ├AccessData.class
│ └AccessInner.class
└foo (+)
    └AccessOuter.class (+)

AccessOuter.java

package access.foo;

import access.data.AccessData;

public class AccessOuter {
    public static void main(String[] args) {
        AccessData data = new AccessData();

        // public 변수와 메소드 불려오기
        data.publicVar += 1;
        data.publicMethod();

        // defualt 변수와 메소드 불려오기
        // data.defaultVar += 2;
        // data.defaultMethod();

        // private 변수와 메소드 불려오기
        // data.privateVar += 3;
        // data.privateMethod();

        // AccessData 클래스 내부 호출해보기
        data.innerMethod();
    }
}

출력 결과

by publicMethod 1
== by innerMethod== 
by publicMethod 2
by defaultMethod 1
by privateMethod 1
  • 패키지 위치는 AccessData 클래스와 다른 package access.foo; 패키지이다.
  • public 접근 제어로 설정한 변수와 메소드 모두 호출 가능하다.
  • default 같은 패키지에서만 접근 가능. access.data.AccessInner 와 access.foo.AccessOut 클래스는 서로 다른 패키지이다. 따라서 default 접근이 불가하다.
  • private 는 동일한 클래스가 아니기에 호출할 수 없다.
  • 앞서 설명한 것과 동일. AccessData.innerMethod() 메소드는 public 이고, AccessData 객체에 포함되어 메소드로 호출할 수 있었다. 호출한 경우 메소드 내부의 private 변수와 메소드를 접근하여 출력해주고 있다.