Language/JAVA [JAVA] 접근제어자
  • 728x90
    반응형

     

     

     

     

     

    접근제어자

    접근 제어자는 public 과 private 외에도 두가지가 더 있다. protected와 default가 그것이다. protected는 상속 관계에 있다면 서로 다른 패키지에 있는 클래스의 접근도 허용한다. default는 접근 제어 지시자가 없는 경우를 의미하는데, 접근 제어자가 없는 메소드는 같은 패키지에 있고 상속 관계에 있는 메소드에 대해서만 접근을 허용한다.

     

      public protected  default  private 
    같은 패키지, 같은 클래스 허용  허용  허용  허용 
    같은 패키지, 상속 관계  허용  허용  허용  불용 
    같은 패키지, 상속 관계 아님  허용  허용  허용   
    다른 패키지, 상속 관계  허용  허용  불용  불용 
    다른 패키지, 상속 관계 아님  허용  불용  불용  불용 

     

     

     

    클래스 접근 제어자

    클래스의 접근 제어자는 총 2개로 public과 default이다. default는 접근 제어자를 붙이지 않은 경우 defaul가 된다.

     

    클래스의 접근 제어자는 패키지와 관련된 개념이다. 즉 접근 제어자가 public인 클래스는 다른 패키지의 클래스에서도 사용할 수 있고, default인 경우는 같은 패키지에서만 사용 가능한다.

     

     

     

    abstract

    abstract 란 한국어로는 추상으로 번역된다. abstract는 상속을 강제하는 일종의 규제이다.

     

    abstract 클래스나 메소드를 사용하기 위해서는 반드시 상속해서 사용하도록 강제하는 것이 abstract다.

     

    추상 메소드란 아래 예제 4열과 같이 메소드의 시드니처만이 정의된 비어있는 메소드를 의미한다.

     

    package test;
    
    abstract class A {
        public abstract int b();    // 추상 메소드
        
        public void d() {
            System.out.println("world");
        }
    }
    
    class B extends A {
        // class A 의 추상 메소드 b() 를 overriding 
        public int b() {    
            return 1;
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            B obj = new B();
            System.out.println(obj.b());
        }
    }

     

    메소드 b의 선언 부분에는 abstract라는 키워드가 등장하고 있다. 이 키워드는 메소드 b는 메소드의 시그니처만

     

    정의 되어 있고 이 메소드의 구체적인 구현은 하위 클래스어서 오버라이딩 해야 한다는 뜻이다.

     

    이렇게 내용이 비어있는 메소드를 추상 메소드라고 부른다.

     

    추상 메소드를 하나라도 포함하고 있는 클래스는 추상 클래스가 되고 자연스럽게 클래스의 이름 앞에 abstract가 붙는다.

     

     

     

    추상 클래스를 사용하는 이유

    추상 클래스는 상속을 강제하기 위한 것이다. 즉 부모 클래스에는 메소드의 시그니처만 정의해놓고 그 메소드의 실제 동작 방법은 이 메소드를 상속 받은 하위 클래스의 책임으로 위임하고 있다.

     

    package test;
    
    abstract class Calculator {
        int left, right;
        
        public void setOprands(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public abstract void sum();    
        public abstract void avg();
        
        int _sum() {
            return this.left + this.right;
        }
        
        public void run() {
                sum();
                avg();
        }    
    }
    
    class ClaulatorDecoPlus extends Calculator {
        public void sum() {
            System.out.println("+ sum :" + _sum());
        }
        
        public void avg() {
            System.out.println("+ avg :" + _sum()/2);
        }    
    }
    
    class ClaulatorDecoMinus extends Calculator {
        public void sum() {
            System.out.println("- sum :" + _sum());
        }
        
        public void avg() {
            System.out.println("- avg :" + _sum()/2);
        }    
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            ClaulatorDecoPlus c1 = new ClaulatorDecoPlus();
            c1.setOprands(10, 20);
            c1.run();
            
            ClaulatorDecoMinus c2 = new ClaulatorDecoMinus();
            c2.setOprands(10, 20);
            c2.run();
        }
    }

     

    실행 결과

    + sum :30

    + avg :15

    - sum :30

    - avg :15

     

    경우에 따라서 합계와 평균을 화면에 출력하는 모습을 달리해야 하는 경우가 있다고 가정하면 그런 경우에 상황에 따라서 동작 방법이 달라지는 메소드(sum, avg)는 추상 메소드로 만들어서 하위 클래스에서 구현하도록 하고 모든 클래스의 공통분모(setOprands, run) 의 경우에는 상위 클래스에 두어서 코드의 중복, 유지보수의 편의성 등을 꾀할 수 있다.

     

     

     

    final 필드

    추상이 상속을 강제하는 것이라면 final은 상속/변경을 금지하는 규제다.

     

    필드와 변수는 같은 의미로 사용된다. 실행되는 과정에서 한번 값이 정해진 이후에는 변수 내의 값이 바뀌지 않도록 하는 규제다.

     

    package test;
    
    class Calculator {
        static final double PI = 3.15;
        int left, right;
        
        public void setOprands(int left, int right) {
            this.left = left;
            this.right = right;
        }
        
        public void sum() {
            System.out.println(this.left + this.right);
        }
        
        public void avg() {
            System.out.println((this.left + this.right)/2);
        }
    }
    
    public class Helloworld {
            
        public static void main(String[] args) 
        {
            Calculator c = new Calculator();
            System.out.println(c.PI);
    //        Calculator.PI = 10;
        }
    }

     

    실행 결과

    27 행 error

     

    위의 코드에서 주목할 점은 변수 앞에 final이 붙어있다는 점이다. Calculator.PI 를 통해서 클래스 변수 PI의 값을 변경하려고 했지만 자바는 이것을 허용하지 않는다. final로 지정된 변수에는 한번 값이 할당되면 그 값을 바꿀 수 없기 때문이다.

     

     

     

    final 메소드

    아래의 코드는 final 메소드 b를 상속하려하기 때문에 오류가 발생한다.

     

    package test;
    
    class A {
        final void b() {}
    }
    
    class B extends A {
        void b() {}
    }
    
    public class Helloworld {
        
    }

     

     

    final 클래스

    아래 코드는 final 클래스를 상속하려하고 있다. 따라서 오류가 발생한다.

     

    package test;
    
    final class C {
        void b() {}
    }
    
    class D extends C {}
    
    public class Helloworld {
        
    }

     

     

     

    728x90
    반응형

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

    [JAVA] 초기화 및 생성자  (0) 2018.06.11
    [JAVA] 기본 문법  (0) 2018.05.31
    [JAVA] 데이터 타입  (0) 2018.05.28
    [JAVA] 설치 및 실행  (0) 2018.05.28
상단으로