Java-객체지향 프로그래밍-캡슐화

캡슐화

객체지향 프로그래밍의 대표요소 중 캡슐화에 대해서 알아보자.
캡슐화란 클래수 내부의 서로 연관있는 필드와 메서드들을 캡슐처럼 하나의 객체로 패키징 하는 것이다.

캡슐화의 목적은 크게 두가지 이다.

  • 데이터 보호 - 클래스에 정의된 필드와 기능들을 외부로부터 보호
  • 데이터 은닉 - 클래스 내부의 데이터들을 감추고 필요한 부분만 외부에 노출

위와 같은 목적을 위해서 객체지향 프로그래밍에서는 캡슐화를 한다.
그렇다면, 어떻게 캡슐화를 구현할 수 있는지 한번 알아보자.

접근제어자

캡슐화의 첫번째 방법은 접근제어자를 이용하는 방법이다.
접근제어자는 클래스나 클래스 내부에 선언된 필드, 메서드에 선언이 가능하며 4가지의 접근제어자를 사용할 수 있다. 아래의 표는 4가지 접근제어자의 설명이다.

접근 제어자클래스 내부패키지 내부다른 패키지의
하위 클래스
패키지 외부설명
privateOXXX동일 클래스 내에서만 접근 가능
defaultOOXX동일 패키지 내에서만 접근 가능
protectedOOOX동일 패키지 +
다른 패키지 하위 클래스에서 접근가능
publicOOOO어디서든 접근 가능

위의 표를 바탕으로, 코드 예제를 보며 이해해보자.

우선 패키지 구조는 다음과 같다.
.
├── AccessModifier
│   ├── Main.java
│   └── Parent.java
├── AccessModifier1
│   └── Child.java

package AccessModifier;

public class Parent {
    private int a = 0;
    int b = 2;
    protected int c = 3;
    public int d = 4;

    public void print() {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }
}
package AccessModifier;

public class Main {
    public static void main(String[] args) {
        Parent p = new Parent();
//        System.out.println(p.a); //에러
//        // Parent클래스의 필드 a는 private 접근제어자로 동일 클래스만 접근 가능
        System.out.println(p.b);
        System.out.println(p.c);
        System.out.println(p.d);
    }
}
package AccessModifier1;

import AccessModifier.Parent;

class Child extends Parent {
    public void print(){
//        System.out.println(a);
//        System.out.println(b); //다른 패키지이므로 에러
        System.out.println(c);
        System.out.println(d);
    }
}

위와 같이 접근제어자를 이용하면, 클래스의 위치, 패키지의 위치, 상속여부등에 따라서 외부로부터의 접근제어 설정을 해줄 수 있다.
또한 현재 위의 코드에는 필드값만 예시로 나타냈지만, 클래스,메서드 또한 접근제어자를 통한 접근제어가 가능하다.

Getter와 Setter

캡슐화의 두 번째 방법은 Getter과 Setter 메서드 이용이다.
Getter와 Setter는 접근제어자를 통해 보호하면서 데이터를 변경하는 용도로 이용된다.
Getter,Setter 메서드는 get 또는 Set을 필드명 앞에 붙혀서 생성 및 사용한다.
예를 들어 필드의 이름이 name이라면 getName() or setName()와 같이 메서드를 생성한다.
Getter의 경우 데이터를 불러올 때, Setter의 경우 데이터를 수정할 때 사용한다.

아래의 코드 예시를 살펴보자.

package GetterSetter;

public class GetterSetter {
    public static void main(String[] args) {
        Human h = new Human();
        h.setName("홍길동");
        h.setAge(15);
        h.setCompany("뉴컴퍼니");

        System.out.println(h.getName());
        System.out.println(h.getAge());
        System.out.println(h.getCompany());

//        h.name = "홍길동"; //Human의 필드값이 private으로 에러
//        System.out.println(h.name); //Human의 필드값이 private으로 에러
    }
}

class Human{
    private String name;
    private int age;
    private String company;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }
}

//출력
홍길동
15
뉴컴퍼니

이처럼 클래스 내부 private 접근제어자로 감춰진 데이터를 h.name = "이름"으로 수정하는 것이아닌
Getter,Setter 메서드를 클래스 내부에 public 접근제어자로 선언하여 데이터를 보다 안전하게 가져오고 수정할 수 있다.


정리

  • 캡슐화란 데이터를 보호하고 은닉하기 위해 사용한다.
  • 접근제어자를 이용하여, 클래스 외부로 불필요한 데이터 노출을 방지하고 데이터를 보호한다.
  • Getter,Setter 메서드를 이용하여 보호된 데이터를 보다 안전하게 불러오고 수정한다.