국비교육

국비지원 59일차 (JAVA - 접근제어자, 캡슐화)

재밌는개발러 2023. 10. 17. 18:59

※ JAVA - 접근제어자

 

1. 접근제어자
   1) 변수, 메서드, 생성자에 대한 접근 권한을 지정하는 역할을 함.
   2) 클래스의 외부에서 클래스의 변수, 메서드, 생성자에 접근할 수 있는지 여부를 지정하는 키워드
   3) 객체의 속성들에 대해 쓸데없는 접근 또는 잘못된 접근을 막기 위해서 사용

2. 접근 제어자의 종류
   1) private : 같은 클래스 내부에서만 접근가능
   2) default : 같은 패키지 내부에서만 접근 가능
   3) protected : 같은 패키지 또는 상속관계의 클래스에서 접근가능
                      필드, 생성자, 메소드 선언 시 사용
   4) public : 아무데서나 접근 가능

   *클래스에는 주로 public, default 만 사용하는 편이다.

   *외부클래스의 메서드를 내 클래스에서 쓰려고하면 내클래스에서 메서드를 선언하고 그 안에 다가 메서드를 적용할 수        있다. (System.out.println() 메서드에 일종이고 main(String [] args) 도 메서드의 일종이다.  

 

※ 접근제어자 예제

public class Ex23_1_접근제한자 {
    private String prv = "private"; //같은 클래스
    /*default*/ String def = "default"; //같은 패키지
    protected String pro = "protected"; // 같은 패키지 + 다른패키지(상속관계)
    public String pub = "public"; //아무데서나

    public void printMenber(){
        System.out.println(prv); //ok
        System.out.println(def); //ok
        System.out.println(pro); //ok
        System.out.println(pub); //ok
    }

}
class  MyParent {

    public static void main(String[] args) {
    Ex23_1_접근제한자 tmp = new Ex23_1_접근제한자();
    tmp.printMenber();
        System.out.println("============================");
//        System.out.println(tmp.prv); //접근안됨 private 는 같은 클래스 네에서만 호출가능
        System.out.println(tmp.def); //ok
        System.out.println(tmp.pro); //ok
        System.out.println(tmp.pub); //ok
    }
}

///////////////////////아래는 다른 패키지파일이다///////////////////////////////////
/////////다른패키지의 Ex23_1_접근제한자 상속받고있는 클래스가 있다 /////////////////

class MyChild extends Ex23_1_접근제한자{
    public void printMenber(){
//        System.out.println(prv); //에러, private은 해당 클래스에서만 가능
//        System.out.println(def); //에러, default는 같은 패키지에서만 가능
        System.out.println(pro); //ok
        System.out.println(pub); //ok
    }


}
public class Ex23_2_접근제한_외부파일 {

    public static void main(String[] args) {
        Ex23_1_접근제한자 tmp = new Ex23_1_접근제한자();
        tmp.printMenber();
//        System.out.println(tmp.prv); //에러, private은 해당 클래스에서만 가능
//        System.out.println(tmp.def); //에러, default는 같은 패키지에서만 가능
//        System.out.println(tmp.pro); //에러, 자식클래스가 아니니 에러남.
        System.out.println(tmp.pub); //ok
    }
}

1. private tmp.def 는 다른 클래스 MyParent에서 쓰려면 접근이 안된다 그래서 출력이 안되는 걸 볼 수 있을 것이다.

->  보통 getter setter 메서드를 통해 출력가능하게 할 수 있다.

 

2. 패키지가 다른 클래스에서의 상속관계 클래스 들을 default 값이 적용이 안될 것이다. defaliut 값은 같은 패키지 내에서 만 가능합니다.

 

3. protected는 상속관계이면서 다른 패키지에 있는 것까지 적용할 수 있습니다.

 

4. public은 상속관계이든 아니든 다른 패키지 이든 아니든 모든 클래스들을 어울릴 수 있다.

 

* 그리고 보통 다른 패키지에서 클래스를 가져오려고 하면 그 클래스가 있는 패키지 값을 같이 적어서 갖고 와야 되는데 매번 갖고 올 때마다 앞에 패키지이름도 적는 것이 번거로울 것이다. 이럴 때 패키지이름아래에 import를 적용해 갖고 올클래스에 

패키지이름. 클래스이름을 경로지정하여 다른 패키지의 클래스를 가지고 올 때 그냥 클래스 이름만 적용해 갖고 올 수 있을 것이다.

다만, 그 다른 패키지의 갖고 올 클래스이름이랑 현재 있는 패키지의 클래스이름이 같으면 오류가 날것이다 조심하자.

 

※ JAVA - 캡슐화

1. 캡슐화란 
    객체지향 프로그래밍에서 핵심중에 하나(다형성 다음으로 중요)
    클래스 안에 있는 변수나 메서드를 외부에서 접근하지 못하도록 은닉하는 것.
    (쉽게 말하면 데이터를 쉽게 바꾸지 못하게 할 때 사용) 
 
2. 캡슐화의 목적
     1) 데이터보호(정보 은닉) -> setter로 if문을 통해 정보를 거르고 거르고 맞는 정보만 리턴되게 할 수 있다.(유효성검사)
      -> 생성자를 통해 맨 처음 매개변숫값 넣어 객체생성 시 변수들의 (유효성검사)를 할 수 있다.
     2) 데이터 외부 노출 방지 -> 이 개념도 기억해 놓기
        
3. 캡슐화하는 방법
     1) 은닉하려는 정보의 접근제어자를 private으로 놓는다
     2) public 한 getter 나 setter 메서드를 이용해서 해당 데이터에 돌아서 접근하도록 한다.
        - setter/getter의 경우 필요하면 유효성 검사 로직을 넣어줄 수 있다.(조건식으로)

 

※ 캡슐화 예제

class Capsule {
    
    private  int seqno; //고객번호
    private  String name; //고객이름

    public int getSeqno() {
        return seqno;
    }

    public void setSeqno(int seqno) { //이렇게 정보은닉한 값을 setter 로 값을받아서 if문 유효성검사를 할수있다.
        if (seqno >= 100 ) {
            this.seqno = seqno;
        }
        else {
            System.out.println("100 이상으로 입력 필요");
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Capsule{" +
                "seqno=" + seqno +
                ", name='" + name + '\'' +
                '}';
    }
}

public class Ex24_1_캡슐화 {
  public static void main(String[] args) {
    Capsule c = new Capsule();
//      c.seqno= 10; //public 일때 사용가능
//      c.name= "홍길동";
        
        c.setSeqno(100);
        c.setName("홍길동");
        
        System.out.println(c); //Capsule{seqno=100, name='홍길동'}
    }
}

1.  private  int seqno;
     private  String name; 

-> 이렇게 private 한 변수를 설정해 정보은닉을 해준다. 그리고 이걸  다른 클래스에서 사용하기 위해서는 getter setter 메서드를 이용해 정보를 넣어줄 수 있고 위에처럼 해당 Seqno에 if문으로 Seqno 가 100 이상이면 this. Seqno (해당클래스의 Seqno를 뜻한다.) 에 매개변수로 받은 Seqno 를 받아서 해당클래스의 리터널값에 넣어주게 한다.

-> 100 미만으로 입력 시 '100 이상으로 입력필요 '라는 문구가 뜰 것이다. [