자바

[Java] 캡슐화, 추상화

juhoyang 2024. 9. 26. 14:24

캡슐화

- 특정 클래스내 데이터는 해당 클레스만 접근해야한다.

- 해당 클래스의 데이터를 다른 클래스가 직접적으로 바꿀 수 없고 변경하려면 해당 클래스의 메서드를 이용 해야한다. 

- 캡슐화는 특정 데이터에 접근해 값을 설정하는 데이터와 메서드 이다.

 

소스 예시

- 자동차 클래스를 만들어서 main에서 호출해 사용해보자.

 

Car.java

public class Car {
    String name;

    public void go(){
        System.out.println(name + " Car go");
    }
}

- 간단하게 name변수가 있고 메서드는 go가 있다.

 

main클래스

public static void main(String[] args) {
    Car kia = new Car();

    kia.name = "니로";
    kia.go();
}

 

결과

니로 Car go

 

위 소스의 문제점을 확인해보면

Car클래스의 내부 변수를 main에서 직접 접근하고 있다. -> 데이터를 외부 제어 하면 안된다.

 

변경할 내용

 

수정

1. 클래스 내부에서 제어할 변수는 private로 접근제어 설정한다.

 - 외부에서 해당 변수를 직접 변경할 수 없음

 - 접근제어 참고

 

2. 외부에서 데이터의 값을 설정, 가져올 수 있도록 메소드를 생성한다.

 - get, set메서드라고 칭한다.

 

 Car.java

public class Car {
    private String name;

    public String getName() {
        return name;
    }

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

    public void go(){
        System.out.println(name + "Car go");
    }
}

 

main메서드

- 데이터를 접근할때는 set메서드를 이용하고 값을 받고 싶으면 get메서드를 사용한다.

    public static void main(String[] args) {
        Car kia = new Car();

        kia.setName("니로");
        System.out.println("설정한 이름확인 : " + kia.getName());

        kia.go();
    }

 

결과

설정한 이름확인 : 니로
니로Car go

 

장점

1.  잘못된 데이터의 객체 접근을 막아준다.

 - 외부에서 데이터를 접근할 때 왜 메서드를 거쳐서 사용해야할까?

 - 잘못된 데이터 설정을 set메서드에서 막아주는 로직을 넣을수 있다.

 

Car.java 예시

public class Car {
    private String name;
    private int price;

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        if (price >0) { //0보다 작은 가격은 반영안함
            this.price = price;
        }
    }
....
}

- 새롭게 생성한 가격 변수는 음수로 설정하면 안된다. -> set매서드에 음수일 경우 값을 안넣는다.

 

2. 비즈니스 로직을 객체안에 캡슐화가능하다.

 - 로직의 중복제거, 다른 클래스에서 사용가능한 범용성 제공

 

Car.java 에서 설정한 가격을 내리려면 main메서드는 아래와 같이 진행하는데

public static void main(String[] args) {
    Car kia = new Car();
    Car hyundai = new Car();

    //초기설정
    kia.setName("니로");
    kia.setPrice(10000);
    hyundai.setName("투싼");
    hyundai.setPrice(20000);


    //5000원씩 가격할인
    int kiaPrice = kia.getPrice();
    kiaPrice -= 5000; //5000원 가격할인
    kia.setPrice(kiaPrice);

    int hyundaiPrice = hyundai.getPrice();
    hyundaiPrice -= 5000; //5000원 가격할인
    kia.setPrice(hyundaiPrice);

    System.out.println("기아차 가격 " + kiaPrice + " 현대차 가격 " + hyundaiPrice);

}

- 위의 경우 가격할인 하는 로직이 중복되고, 객체의 수가 더 들어나면 작성할 코드들이 많아진다.

 

중복되는 가격할인 로직을 Car클래스 안에 메서드로 넣어보면

public class Car {
    private String name;
    private int price;

    public void priceDiscount(int discountPrice){
        price -= discountPrice;
        return;
    }
    
    ....}

- priceDiscount 클래스를 만들었다.

 

해당 매서드를 이용해서 main메서드를 수정하면

public static void main(String[] args) {
    Car kia = new Car();
    Car hyundai = new Car();

    //초기설정
    kia.setName("니로");
    kia.setPrice(10000);
    hyundai.setName("투싼");
    hyundai.setPrice(20000);
    
    //5000원씩 가격할인
    kia.priceDiscount(5000);
    hyundai.priceDiscount(5000);

    System.out.println("기아차 가격 " + kia.getPrice() + " 현대차 가격 " + hyundai.getPrice());

}

- 중복되는 부분을 제거하고 깔끔하게 코드를 단축시킬수 있다.

 

추상화

- 사용자가 메소드 내부의 로직 까지 알필요는 없다. -> 기대하는 기능을 사용하기만 하면 됨

- 캡슐화와 연관이 깊은데 좀더 포괄적인 개념으로 내부의 복잡한 내용을 숨기고 클라이언트는 기능을 사용

 

일상속 비교

- 사용자가 운전을 할 때 차 엔진이 어떻게 작동하는지 알 필요는 없음 -> 시동걸고 운전방법만 알면 된다.

 

위에 main 메소드를 보면

- 사용자는 set, get 메서드 부터 priceDiscount(가격할인), go(출발) 까지 Car클래스의 내부를 알 필요가 없이 기대한 기능을 사용하면 된다.

 

'자바' 카테고리의 다른 글

[Java] 기본형, 참조형데이터  (0) 2024.09.27
[Java] 생성자  (0) 2024.09.27
[java]Class, Object, Instance  (1) 2024.09.25
객체 지향과 절차지향 언어 비교  (0) 2024.09.25
7. 메서드  (0) 2024.09.24