ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java | 접근 제어자 with 상속
    JAVA/JAVA 2020. 1. 30. 17:40

    접근 제어자 with 상속

    클래스, 생성자, 멤버 변수, 메소드에 외부에서의 접근 가능성을 제어하는 것

    접근 제어자 설명
    public 외부 패키지 및 외부 클래스 어디에서나 접근 가능
    단, 멤버 변수와 메소드가 public이더라도
    해당 클래스가 public이 아니면 외부 패키지에서는 접근 불가
    하나의 java(class)파일에는 하나의 public 클래스만 작성 가능
    protected 같은 패키지 내부와 상속 관계의 클래스에서만 접근할 수 있고 그 외 클래스에서는 접근 불가
    외부 패키지에 있는 클래스여도 같은 패키지의 클래스를 상속받았다면 접근 가능
    데이터를 캡슐화하면서 외부 패키지에서도 상속이 가능하도록 하는 접근 제어자
    아무것도 없는 경우 default이며 같은 패키지 내부에서만 접근 가능,
    동일 패키지의 클래스를 상속받은 외부 패키지의 자식 클래스도 접근 불가
    같은 패키지 안에서만 상속 가능
    private 같은 클래스 내부에서만 접근 가능하며
    어떠한 종류의 상속도 허가하지 않음

    ※ 최상위 클래스 선언에서는 private, protected 사용 불가


    import

    외부 패키지에 존재하는 클래스를 현재 클래스로 불러올 때 사용
    같은 패키지에 있는 다른 클래스는 자동 인식(import할 필요 없음)

    java.lang 패키지는 기본패키지로 자동으로 import됨, [import java.lang.*]이 생략된 것
    그 외 패키지는 무조건 import를 해야 사용할 수 있음


    사용법

    import 최상위 패키지명.하위 패키지명.클래스명;
    // import는 대체로 소스코드 가장 위쪽에 작성
    // 패키지명.*; 작성시, 해당 패키지의 모든 클래스를 불러옴

    사용례

    두 개의 패키지에 세 개의 클래스를 만들어서 접근 제어자에 따른 접근 가능성에 대해 확인

    j200130.test package

    A.java

    package j200130.test;
    
    public class A {
        // Private
        private int i = 10;
    
        // Default
        int j;
    
        // Protected
        protected int k;
    
        // Public
        public int m;
    
        // Private, 자기 클래스 내부에서만 사용할 목적으로 만들어진 메소드에 부여
        // 외부에서 사용할 방법이 없음
        private void print() {
            System.out.println("private i: " + i);
        }
    
        // Default
        void print2() {
            System.out.println("default j: " + j);
        }
    
        // Protected
        protected void print3() {
            System.out.println("protected k: " + k);
        }
    
        // Public
        public void print4() {
            System.out.println("public m: " + m);
        }
    
        public static void main(String[] args) {
    
            // Public
            A a = new A();
    
            // Private_동일 클래스에서만 접근 가능
            System.out.println("=====private=====");
            a.i = 100;
            a.print();
    
            // Default_동일 패키지에서만 접근 가능
            System.out.println("=====default=====");
            a.j = 200;
            a.print2();
    
            // Protected
            System.out.println("=====protected=====");
            a.k = 300;
            a.print3();
    
            // Public
            System.out.println("=====public=====");
            a.m = 400;
            a.print4();
             /*
             =====private=====
             private i: 100
             =====default=====
             default j: 200
             =====protected=====
             protected k: 300
             =====public=====
             public m: 400
             */
        }
    
    }

    B.java

    package j200130.test;
    
    package j200130.test;
    
    public class B {
    
        public static void main(String[] args) {
    
            // Public_같은 패키지의 다른 클래스에서 접근 가능
            A a = new A();
    
            // Private_같은 패키지에서도 클래스가 다르다면 접근 불가
            System.out.println("=====private=====");
    //        a.i = 100;        // is not visible : 접근이 불가능할 때 출력되는 에러
    //        a.print();
    
            // Default_같은 패키지에서는 접근 가능
            System.out.println("=====default=====");
            a.j = 200;
            a.print2();
    
            // Protected_같은 패키지에서 접근 가능
            System.out.println("=====protected=====");
            a.k = 300;
            a.print3();
    
            // Public_같은 패키지의 다른 클래스에서 접근 가능
            System.out.println("=====public=====");
            a.m = 400;
            a.print4();
             /*
             =====private=====
             =====default=====
             default j: 200
             =====protected=====
             protected k: 300
             =====public=====
             public m: 400
             */
        }
    
    }

    j200130.test2 package

    C.java

    package j200130.test2;
    
    // A 클래스가 다른 패키지에 있기 때문에 import, *을 사용하면 해당 패키지의 모든 클래스 import
    import j200130.test.*;
    
    public class C extends A {
    
        public static void main(String[] args) {
            // Public_외부 패키지의 다른 클래스에서도 접근 가능
            A a = new A();
    
            // Private_외부 클래스 및 외부 패키지에서 접근 불가
            System.out.println("=====private=====");
    //        a.i = 10;
    //        a.print();
    
            // Default_외부 패키지에서 접근 불가
            System.out.println("=====default=====");
    //        a.j = 200;    
    //        a.print2();
    
            // j200130.test 패키지의 A 클래스를 상속받은 C 클래스의 인스턴스로도 접근 불가
            C c = new C();
    //        c.j= 300;
    //        c.print2();
    
            // Protected_외부 패키지에서 A 클래스로 생성한 인스턴스로는 접근 불가
            System.out.println("=====protected=====");
    //        a.k = 300;
    //        a.print3();
    
            // j200130.test.A 클래스를 상속받은 j200130.test2.C 클래스의 인스턴스로는 접근 가능
            c.k = 300;
            c.print3();
    
            // Public_외부 패키지의 다른 클래스에서도 접근 가능
            System.out.println("=====public=====");
            a.m = 400;
            a.print4();
    
             /*
             =====private=====
             =====default=====
             =====protected=====
             protected k: 300
             =====public=====
             public m: 400
             */
        }
    
    }

    접근 제어자는 이전에도 한 번 다룬 적이 있지만 조금 더 심화된 내용으로 상속과 함께 다루어보았습니다.

    예제가 조금 길지만 패키지와 클래스간 접근제어자의 접근 가능성을 확인하기 위함이니 천천히 봐주시길 바랍니다.

    접근 제어자의 범위를 정확히 알아야 상속할 때나 클레스의 멤버 변수 및 메소드에 접근할 때 헷갈리지 않기 때문에

    정확히 파악해 두는 것이 좋겠습니다.

    댓글

Designed by Tistory.