개발일지/Java

Java 캡슐화 (Encapsulation)

E-room 2022. 9. 12. 12:55
728x90
특정 객체 안에 관련된 속성과 기능을 하나의 캡슐로 만들어 데이터를 외부로부터 보호하는 것

 

캡슐화의 목적

  • 데이터 보호
  • 내부적으로만 사용되는 데이터에 대한 불필요한 외부 노출 방지

 

패키지 (package)

  • 특정한 목적을 공유하는 클래스와 인터페이스의 묶음
  • 클래스들을 그룹 단위로 묶어 효과적으로 관리하게 위해 사용
  • Import문을 통해 접근하거나 (.)을 사용하여 접근

 

우리가 컴퓨터를 사용할 때 폴더를 만들어 그 폴더와 관련된 파일들을 관리하는 것과 같다

쉽게 말해 폴더를 만들어 자바 파일들을 모아 놓은 것

 

 

접근 제어자

제어자 (Modifier)

클래스, 필드, 메서드, 생성자 등에 부가적인 의미를 부여하는 키워드

 

접근 제어자와 기타 제어자로 구분

  • 접근 제어자 : public, protected, (default), private
  • 기타 제어자 : static, final, abstract, native, transient, synchronized 등

 

접근 제어자 (Access Modifier)

자바 객체지향 프로그래밍의 캡슐화 구현을 위한 핵심적인 방법

 

목적

  • 클래스 위부로의 불필요한 데이터 노출을 방지
  • 외부로부터 데이터가 임의로 변경되지 않도록 방지

 

종류

  • private : 동일 클래스내에서만 접근 가능
  • (default) : 동일 패키지 내에서만 접근 가능
  • protected : 동일 패키지 + 다른 패키지의 하위 클래스에서 접근 가능
  • public : 접근 제한 없음
접근 제어자 클래스 내 패키지 내 다른 패키지의 하위 클래스 패키지 외
private O X X X
(default) O O X X
protected O O O X
public O O O O
package package1; // 패키지명 package1 

//파일명: Parent.java
class Test { // Test 클래스의 접근 제어자는 default
    public static void main(String[] args) {
        Parent p = new Parent();

//        System.out.println(p.a); // 동일 클래스가 아니기 때문에 에러발생!
        System.out.println(p.b);
        System.out.println(p.c);
        System.out.println(p.d);
    }
}

public class Parent { // Parent 클래스의 접근 제어자는 public
    private int a = 1; // a,b,c,d에 각각 private, default, protected, public 접근제어자 지정
    int b = 2;
    protected int c = 3;
    public int d = 4;

    public void printEach() { // 동일 클래스이기 때문에 에러발생하지 않음
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }
}

// 출력값
2
3
4
package package2; // package2 

//파일명 Test2.java
import package1.Parent;

class Child extends package1.Parent {  // package1으로부터 Parent 클래스를 상속
    public void printEach() {
        // System.out.println(a); // 에러 발생!
        // System.out.println(b);
        System.out.println(c); // 다른 패키지의 하위 클래스
        System.out.println(d);
    }
}

public class Test2 {
    public static void main(String[] args) {
        Parent p = new Parent();

//        System.out.println(p.a); // public을 제외한 모든 호출 에러!
//        System.out.println(p.b);
//        System.out.println(p.c);
        System.out.println(p.d);
    }
}

 

getter, setter 메서드

데이터를 효과적으로 보호하면서도 의도하는 값으로 변경하여 캡슐화를 보다 효과적으로 달성할 수 있음

  • 해당 클래스 내부에 데이터 값을 변경 할 수 있는 메서드를 정의해서 외부에서 사용
  • 일반적으로 메서드명에 set, get을 메서드명 앞에 붙여서 사용

 

public class GetterSetterTest {
    public static void main(String[] args) {
        Worker w = new Worker();
        w.setName("김이룸");
        w.setAge(26);
        w.setId(5);

        String name = w.getName();
        System.out.println("이름은 " + name);
        int age = w.getAge();
        System.out.println("나이는 " + age);
        int id = w.getId();
        System.out.println("ID는 " + id);
    }
}

class Worker {
    private String name; // 변수의 은닉화. 외부로부터 접근 불가
    private int age;
    private int id;

    public String getName() { // 멤버변수의 값
        return name;
    }

    public void setName(String name) { // 멤버변수의 값 변경
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age < 1) return;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
// 출력값
이름은 김이룸
나이는 26
ID는 5
728x90