course 2021/JAVA

day12 - access modifier, encapsulation

코딩하는토끼 2021. 9. 2. 05:02

> 접근제한자 access modifier

클래스, 멤버변수, 메소드, 생성자로의 접근을 제어할 수 있는 제한자

클래스 설계 시 외부에서 접근할 수 있는 멤버와 그렇지 않은 멤버를 구분하여 -접근제한자를 사용하여- 설계하는 것이 좋음

접근제한자 종류

public - 모두 접근가능

protected - 같은 패키지, 같은 클래스, 다른 패키지의 상속 관계 클래스 접근가능 / 다른 패키지의 무관한 클래스 접근 불가

default(접근제한자 쓰지 않음) - 같은 패키지, 같은 클래스 접근 가능 / 다른 패키지 접근 불가

private - 같은 클래스 내에서만 접근 가능

*클래스에 적용 가능한 접근제한자 - public, default

//패키지 pac1
package pac1;
class A {  //default 클래스 A
}

//패키지 pac2
package pac2; 
import pac2.*;  //다른 패키지 pac2 의 모든 클래스 import 
public class C {
    A a = new A();  //클래스 A의 접근제한자가 default이므로 다른 패키지에서 접근할 수 없음
}
package pac1;
public class A {
    
    //멤버변수
    public int a;
    int b;
    private int c;
    
    //생성자
    public A(int a) { }
    A(boolean b) { }
    private A(String s) { }
    
    //메소드
    public void method1() { }
    void method2() { }
    private void method3() { }
}

//같은 패키지, 다른 클래스
package pac1;
public class B {
    public B() {  //생성자
        //생성자 확인
        A a1 =  new A(1); //public 가능
        A a2 = new A(true); //default 가능
        A a3 = new A("안녕"); //private 불가능
        
        //멤벼변수 확인
        a1.a = 1; //public 가능
        a1.b = 1; //default 가능
        a1.c =1; //private 불가능
        
        //메소드 확인
        a1.method1(); //public 가능
        a1.method2(); //default 가능
        a1.method3(); //private 불가능
    }
}

//다른 패키지
package pac2;
import pac1.A;
public class C {
    public C() {  //생성자
            //생성자 확인
            A a1 =  new A(1); //public 가능
            A a2 = new A(true); //default 불가능
            A a3 = new A("안녕"); //private 불가능
        
            //멤벼변수 확인
            a1.a = 1; //public 가능
            a1.b = 1; //default 불가능
            a1.c =1; //private 불가능
        
            //메소드 확인
            a1.method1(); //public 가능
            a1.method2(); //default 불가능
            a1.method3(); //private 불가능
        }
    }
}
//패키지 pac1
package pac1;
public class A { 
    
    //멤버변수
    protected String var;
    
    //생성자
    protected A() { }
    
    //메소드
    protected void method() { }
}

//다른 패키지 pac2
package pac2;
import pac1.A;
public class C {
    public C() {  //생성자
        //생성자 확인
        A a = new A(); //protected 불가능
        //멤버변수
        a.var = "hi"; //protected 불가능
        //메소드
        a.method(); //protected 불가능
    }
}

//다른 패키지이지만, 상속관계
package pac2;
import pac1.A;
public class C extends A { //상속(부모클래스A, 자식클래스C)
    public C() {
        super(); //생성자 protected 가능
        super.var = "hi"; //멤버변수 protected 가능
        super.method(); //메소드 protected 가능
    }
}

 

객체지향 프로그래밍 기술 - 상속, 은닉, 다형성

> 은닉 encapsulation

은닉 - 캡슐화

사용자에게 상세한 내부 구현을 숨기고 필요한 부분만 보이게 하는 것

클래스 내 멤버변수의 접근제한자를 private로 설정 

 

공개된(public) 메소드를 통해 은닉된 멤버변수에 접근 가능

- setter 메소드 (set+멤버변수명) : 변수에 값을 저장/변경 

- getter 메소드 (get+멤버변수명) : 변수의 값을 얻어옴/조회함(return)

*빠르게 생성하는 방법: alt+shift+s → generate getters and setters → 선택 후 generate

이렇게 데이터 변경시킬 경우, 메소드 내에 데이터 유효성을 검증하는 루틴을 넣을 수 있음

접근 권한을 체크할 수 있는 로직을 포함시키면 인가되지 않은 사용자에게 중요한 데이터를 숨길 수 있음

멤버변수뿐 아니라 외부에 공개하고 싶지 않은 메소드도 private로 선언 가능

public class MyDate {
    private int day;
    private int month;
    private int year;  //멤버변수 private
    
    //setter메소드
    public void setDay(int day) { 
        this.day = day;
        }
    }
    
    //혹은 setter메소드 내에 데이터 유효성을 검증하는 루틴을 추가할 수 있음
     public void setDay(int day) {  //setter메소드
        if(day < 1 || day > 31) {
            System.out.println("유효한 값이 아님");
        } else {
            this.day = day;
        }
    }
    
    //getter메소드
    public int getDay() {
        return day;
    }
    
//main 클래스
public static void main(String[] args) {
    MyDate me = new MyDate(); //객체생성
    me.setYear(20); //me.day = 20; 대신 setter메소드 이용하여 변수에 값 저장
    
    int day = me.getDay();
    System.out.println("날짜는 " + day + "일"); //getter메소드 이용하여 변수에 저장된 값 알아냄
}