객체 지향 프로그래밍

2024. 1. 31. 15:53Java

◎ 객체 지향 프로그램 & 절차 지향 프로그래밍

-> 절차 지향 프로그래밍

 - 절차를 지향하는 프로그래밍으로 실행 순서를 중요하게 생각하는 프로그래밍 방식이다.

 - 프로그램의 흐름을 순차적으로 따르면서 처리한다. 

 

-> 객체 지향 프로그래밍

 - 객체를 중요하게 생각하는 프로그래밍 방식이다.

 - 실제 세계의 사물이나 사건을 객체로 보고, 객체 간의 상호작용을 중심으로 프로그래밍을 한다. 

 

-> 객치 지향 프로그래밍과 절차 지향 프로그래밍의 차이점

 - 절차 지향은 데이터와 해당 데이터에 대한 처리 방식이 분리되어 있다. 

 - 객체 지향은 데이터와 해당 데이터에 대한 기능이 하나의 객체에 포함되어있다.

 

-> 아래 코드는 절차 지향 기반으로 작성되어 있다.

public class MusicPlayerMain1 {
    public static void main(String[] args) {
        int volume = 0;
        boolean isOn = false;

        // 음악 플레이어 켜기
        isOn = true;
        System.out.println("음악 플레이어 시작");

        // 볼륨 증가
        volume++;
        System.out.println("음악 플레이어 볼륨 : " + volume);
        // 볼륨 증가
        volume++;
        System.out.println("음악 플레이어 볼륨 : " + volume);
        // 볼륨 감소
        volume--;
        System.out.println("음악 플레이어 볼륨 : " + volume);
        // 음악 플레이어 상태
        System.out.println("음악 플레이어 상태 확인");
        if (isOn) {
            System.out.println("음악 플레이어 on, 볼륨 : " + volume);
        }else {
            System.out.println("음악 플레이어 off");
        }
        // 음악 플레이어 끄기
        isOn = false;
        System.out.println("음악 플레이어 종료");
    }
}

-> 결과

-> 코드의 순서에 따라 순차적으로 동작하며 결과가 출력된다.

 

-> 이번에는 MusicPlayerData라는 클래스를 추가하여 MusicPlayerData의 볼륨과 전원 상태를 멤버변수로 담는다.

public class MusicPlayerData {
    int volume;
    boolean isOn;
}

-> 또한 기존 코드에서 볼륨 조절과 음악 플레이어의 전원 상태를 매번 코드로 작성했는데 볼륨 조절과 음악 플레이어의 전원 상태를 메서드로 만들어 반복을 줄인다.

package oop;

public class MusicPlayerMain2 {
    public static void main(String[] args) {
        MusicPlayerData data = new MusicPlayerData();

        // 음악 플레이어 켜기
        on(data);

        // 볼륨 증가
        volumeUp(data);

        // 볼륨 증가
        volumeUp(data);

        // 볼륨 감소
        volumeDown(data);

        // 음악 플레이어 상태
        musicPlayerStatus(data);

        // 음악 플레이어 끄기
        off(data);
    }

    static void on(MusicPlayerData data) {
        data.isOn = true;
        System.out.println("음악 플레이어 시작");
    }
	
    static void off(MusicPlayerData data) {
        data.isOn = false;
        System.out.println("음악 플레이어 끄기");
    }

    static void volumeUp(MusicPlayerData data) {
        data.volume++;
        System.out.println("음악 플레이어 볼륨 : " + data.volume);
    }

    static void volumeDown(MusicPlayerData data) {
        data.volume--;
        System.out.println("음악 플레이어 볼륨 : " + data.volume);
    }

    static void musicPlayerStatus(MusicPlayerData data) {
        System.out.println("음악 플레이어 상태 확인");
        if (data.isOn) {
            System.out.println("음악 플레이어 on, 볼륨 : " + data.volume);
        }else {
            System.out.println("음악 플레이어 off");
        }
    }
}

-> 이제 코드의 중복 없이 메서드 호출만으로 원하는 기능이 동작한다.

-> 현재 코드에서 MusicPlayerData와 MusicPlayer의 데이터(volume, isOn)를 사용하는 MusicPlayerMain2 코드는 각각 분리되어 있다. 음악 플레이어의 데이터는 MusicPlayerData에서 사용해야 하고, 음악 플레이어의 기능(볼륨 조절, 음악 플레이터 상태 확인 기능)은 MusicPlayerDataMain2에서 사용해야 한다.

-> 이런 상황에서 만약 MusicPlayerData의 멤버 변수가 변경되면 그에 따라 MusicPlayerDataMain2에 있는 음악 플레이어 메서드들도 수정해야 하는 상황이 발생할 수 있다. 

-> 이런 문제를 객체 지향 프로그래밍을 통해 해결할 수 있다.

 

◎ 클래스 & 메서드

-> 클래스는 객체를 생성하기 위한 설계도이며, 객체가 가져야 할 속성과 기능을 포함한다고 했다.

-> 객체의 속성은 멤버변수로, 객체의 기능은 메서드로 구현한다.

-> 음악 플레이어 프로그램을 객체 지향적으로 리펙토링 해본다.

public class MusicPlayer { // 음악 플레이어 객체
    int volume; // 볼륨
    boolean isOn; // 음악 플레이어의 전원 상태

    // 음악 플레이어 전원 상태 기능(on/off)
    void on() {
        isOn = true;
        System.out.println("음악 플레이어 시작");
    }

    void off() {
        isOn = false;
        System.out.println("음악 플레이어 끄기");
    }
    
    // 볼륨 조절 기능(+/-)
    void volumeUp() {
        volume++;
        System.out.println("음악 플레이어 볼륨 : " + volume);
    }

    void volumeDown() {
        volume--;
        System.out.println("음악 플레이어 볼륨 : " + volume);
    }

    // 음악 플레이어의 상태 확인 기능(volume & on/off)
    void musicPlayerStatus() {
        System.out.println("음악 플레이어 상태 확인");
        if (isOn) {
            System.out.println("음악 플레이어 on, 볼륨 : " + volume);
        }else {
            System.out.println("음악 플레이어 off");
        }
    }
}

-> 음악 플레이어 객체인 MusicPlayer 클래스에 속성(volume, isOn)과 기능( on()/off(), volumeUp()/Down(), musicPlayerStatus())을 포함하였다.

-> 객체는 해당 객체 내부의 메서드를 통해 자신의 멤버변수 접근할 수 있다. 따라서 MusicPlayer 클래스의 메서드들 내부에 있는 변수들은 MusicPlayer의 멤버 변수다.

 

public class MusicPlayerMain4 {
    public static void main(String[] args) {
        MusicPlayer player = new MusicPlayer();

        // 음악 플레이어 켜기
        player.on();

        // 볼륨 증가
        player.volumeUp();
        // 볼륨 증가
        player.volumeUp();

        // 볼륨 감소
        player.volumeDown();

        // 음악 플레이어 상태
        player.musicPlayerStatus();

        // 음악 플레이어 끄기
        player.off();
    }
}

 

-> 결과

-> main()메서드 내부가 기존보다 훨씬 간결 해졌고, MusicPlayer에 대한 속성이나 기능에 대한 변경 사항은 MusicPlayer클래스만을 통해 변경하면 되기 때문에 유지보수 측면에서도 개선이 되었다.(물론 메서드 이름의 변경이 발생하면 main()메서드에서 메서드를 호출하는 코드도 변경해야 하긴 한다.)

-> main()메서드에서 MusicPlayer의 인스턴스를 생성하면 MusicPlayer 인스턴스에는 속성인 volume, isOn 변수와 음악 플레이어의 기능인 on(), off(), volumeUp(), volumeDown(), musicPlayerStatus() 메서드가 있다.

-> new 키워드를 통해 반환된 MusicPlayer의 참조값을 통해 .(dot)으로 MusicPlayer인스턴스의 멤버 변수와 메서드에 접근하여 멤버 변수 값을 지정하거나, 메서드를 호출할 수 있다.

main()메서드에서 volumeUp()을 호출한 경우

-> main()메서드에서 volume()을 호출하면 해당 메서드 내부에서 volume을 1 증가 시킨다.

-> 해당 volume은 x001위치에 있는 MusicPlayer 인스턴스의 volume이다.

 

캡슐화

-> MusicPlayer 클래스에는 음악 플레이어를 구성하는 속성(volume, isOn())과 기능(메서드)이 하나로 묶여있다. 속성과 기능을 하나의 클래스에 묶어 필요한 경우 메서드로 외부에 제공하는 것을 캡슐화라고 한다. 

 

 

 

 

'Java' 카테고리의 다른 글

접근 제어자  (0) 2024.02.05
생성자  (0) 2024.02.01
기본형 & 참조형  (0) 2024.01.30
클래스  (0) 2024.01.24
메서드  (0) 2024.01.17