
프로그래밍 방식은 크게 두 가지로 나눌 수 있다.
절차 지향 프로그래밍
실행 순서를 중요하게 생각한다. 프로그램의 흐름을 순차적으로 따라가며 처리하며, 즉 “어떻게”에 초점을 맞춘다. 데이터와 데이터를 처리하는 기능이 분리되어 있다 .
객체 지향 프로그래밍
객체 자체를 중요하게 생각한다. 현실 세계의 사물이나 사건을 객체로 보고, 이들의 상호작용을 중심으로 프로그래밍한다. 즉 “무엇을”에 초점을 맞춘다. 데이터와 데이터를 처리하는 기능이 하나의 객체 안에 함께 포함된다 .
간단한 음악 플레이어를 절차 지향 방식으로 구현하면 아래와 같다.
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("음악 플레이어를 종료합니다");
}
}
실행 결과:
음악 플레이어를 시작합니다
음악 플레이어 볼륨:1
음악 플레이어 볼륨:2
음악 플레이어 볼륨:1
음악 플레이어 상태 확인
음악 플레이어 ON, 볼륨:1
음악 플레이어를 종료합니다
순차적으로만 작성되어 있어 데이터와 기능이 분리된 전형적인 절차 지향 코드다.
음악 플레이어의 상태를 MusicPlayerData라는 클래스로 묶으면 관리가 편해진다.
public class MusicPlayerData {
int volume = 0;
boolean isOn = false;
}
이제 관련 데이터가 객체 하나에 속하므로 식별하기 쉬워지고, 음악 플레이어 전용 데이터를 명확히 구분할 수 있다.
중복되는 기능을 메서드로 분리하면 재사용성과 가독성이 향상된다.
static void on(MusicPlayerData data) {
data.isOn = true;
System.out.println("음악 플레이어를 시작합니다");
}
static void volumeUp(MusicPlayerData data) {
data.volume++;
System.out.println("음악 플레이어 볼륨:" + data.volume);
}
static void showStatus(MusicPlayerData data) {
System.out.println("음악 플레이어 상태 확인");
if (data.isOn) {
System.out.println("음악 플레이어 ON, 볼륨:" + data.volume);
} else {
System.out.println("음악 플레이어 OFF");
}
}
하지만 여전히 데이터(MusicPlayerData)와 기능(MusicPlayerMain 메서드들)이 분리되어 있다.
세상의 사물을 단순하게 추상화하면 속성과 기능으로 설명할 수 있다.
자동차
동물
게임 캐릭터
객체 지향 프로그래밍은 세상을 이렇게 속성과 기능으로 나누어 객체로 보고, 이 객체들 간의 상호작용으로 프로그램을 설계한다.
데이터와 기능을 하나의 객체에 묶으면 진정한 객체 지향이 된다.
public class MusicPlayer {
int volume = 0;
boolean isOn = false;
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);
}
void showStatus() {
System.out.println("음악 플레이어 상태 확인");
if (isOn) {
System.out.println("음악 플레이어 ON, 볼륨:" + volume);
} else {
System.out.println("음악 플레이어 OFF");
}
}
}
사용자 입장에서는 이제 단순히 객체를 만들고 필요한 기능을 호출하기만 하면 된다.
MusicPlayer player = new MusicPlayer();
player.on();
player.volumeUp();
player.showStatus();
player.off();
데이터와 기능이 하나의 클래스에 온전히 들어와 있어, 사용하는 입장에서는 내부 구조를 몰라도 된다.
MusicPlayer 클래스는 속성과 기능을 마치 하나의 캡슐처럼 묶어 제공한다.
외부에서는 객체의 내부 상태(volume, isOn)를 알 필요 없이, 제공되는 메서드만 사용하면 된다.