[Java 기본] 3. 객체 지향 프로그래밍
by Hi.Claire🖥️ 김영한의 실전 자바 - 기본편 (김영한, 인프런)
섹션3. 객체 지향 프로그래밍
3-1. 절차 지향 프로그래밍 vs 객체 지향 프로그래밍
절차 지향 프로그래밍
절차 지향 프로그래밍은 절차를 지향한다.
즉, 실행 순서를 중요하게 생각하는 방식이다.
따라서 프로그램의 흐름을 순차적으로 따르며 처리한다.
"어떻게"를 중심으로 프로그래밍 한다.
객체 지향 프로그래밍
객체 지향 프로그래밍은 객체를 지향한다.
즉, 객체를 중요하게 생각하는 방식이다.
실제 세계의 사물이나 사건을 객체로 보고, 이러한 객체들 간의 상호작용을 중심으로 프로그래밍하는 방식이다.
"무엇을"을 중심으로 프로그래밍 한다.
절차 지향과 객체 지향의 중요한 차이
- 절차 지향은 데이터와 해당 데이터에 대한 처리 방식이 분리되어 있다.
- 반면 객체 지향에서는 데이터와 그 데이터에 대한 행동(메서드)이 하나의 객체 안에 함께 포함되어 있다.
지금까지 섹션1과 섹션2에서는 절차 지향 프로그래밍 방식을 사용해서 개발했다.
이번 장에서는 객체 지향 프로그래밍 방식을 사용해서 문제를 풀어보자.
3-2. 클래스와 메서드
클래스는 속성(데이터, 멤버 변수)과 기능(메서드)을 정의할 수 있다.
객체는 자신의 메서드를 통해 자신의 멤버 변수에 접근할 수 있다.
이때, 객체의 메서드 내부에서 접근하는 멤버 변수는 객체 자신의 멤버 변수이다.
3-3. 객체 지향 프로그래밍
(문제) 음악 플레이어 만들기
- 요구사항
- 음악 플레이어를 켜고 끌 수 있어야 한다.
- 음악 플레이어의 볼륨을 증가, 감소할 수 있어야 한다.
- 음악 플레이어의 상태를 확인할 수 있어야 한다.
- 접근 방식
- 음악 플레이어라는 객체를 지향해보자. 이를 위해서는 데이터와 기능을 하나로 묶어서 음악 플레이어라는 개념을 온전히 하나의 클래스에 담아야 한다. 즉, 음악 플레이어가 어떤 속성(데이터)을 가지고, 어떤 기능(메서드)를 제공하는지에 초점을 맞추어야 한다.
- 데이터 묶음 : MusicPlayer 라는 클래스를 만들고, 음악 플레이어에 사용되는 데이터인 isOn, volume 등을 여기에 묶어서 멤버 변수로 사용하자.
- 메서드 추출 : 음악 플레이어 켜기/끄기, 볼륨 증가/감소, 음악 플레이어 상태 출력 등의 기능은 재사용될 가능성이 높다. 해당 기능을 메서드로 만들면 중복을 제거할 수 있고, 각각의 기능을 모듈화할 수 있다.
- 지금은 음악 플레이어를 개발하는 데에 집중하고, 음악 플레이어를 어떻게 사용할지는 분리해서 생각하자.
- 음악 플레이어라는 객체를 지향해보자. 이를 위해서는 데이터와 기능을 하나로 묶어서 음악 플레이어라는 개념을 온전히 하나의 클래스에 담아야 한다. 즉, 음악 플레이어가 어떤 속성(데이터)을 가지고, 어떤 기능(메서드)를 제공하는지에 초점을 맞추어야 한다.
(참고) 모듈화
쉽게 레고 블럭을 생각하면 된다.
필요한 블럭을 가져다 꼽아서 사용하듯이, 특정 기능들을 메서드로 만들어서 메서드를 조립해서 프로그램을 작성할 수 있다.
(참고) 메서드 추출의 장점
- 중복 제거 : 로직 중복을 제거할 수 있다. 같은 로직이 필요하면 해당 메서드를 여러 번 호출하면 된다.
- 변경 영향 범위 줄이기 : 기능을 수정할 때 해당 메서드 내부만 변경하면 된다.
- 가독성 : 메서드 이름을 통해 코드를 더 쉽게 이해할 수 있다.
- MusicPlayer 객체 설계
- 속성 : volume, isOn
- 기능 : on(), off(), volumeUp(), volumeDown(), showStatus()
(풀이)
MusicPlayer.java
package oop1;
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 클래스에 음악 플레이어에 필요한 속성과 기능을 모두 정의했다.
이제 음악 플레이어가 필요한 곳에서 이 클래스만 있으면 온전한 음악 플레이어를 생성해서 사용할 수 있다.
MusicPlayerMain.java
package oop1;
public class MusicPlayerMain {
public static void main(String[] args) {
MusicPlayer player = new MusicPlayer();
// 음악 플레이어 켜기
player.on();
// 볼륨 증가
player.volumeUp();
// 볼륨 증가
player.volumeUp();
// 볼륨 감소
player.volumeDown();
// 음악 플레이어 상태 확인
player.showStatus();
// 음악 플레이어 끄기
player.off();
}
}
음악 플레이어를 시작합니다.
음악 플레이어 볼륨: 1
음악 플레이어 볼륨: 2
음악 플레이어 볼륨: 1
음악 플레이어 상태 확인
음악 플레이어 ON, 볼륨: 1
음악 플레이어를 종료합니다.
캡슐화
MusicPlayer를 보면 음악 플레이어를 구성하기 위한 속성과 기능이 마치 하나의 캡슐에 쌓여있는 것 같다.
이렇게 속성과 기능을 하나로 묶어서 필요한 기능을 메서드를 통해 외부에 제공하는 것을 캡슐화라고 한다.
필요한 모든 것은 MusicPlayer 안에 다 들어있기 때문에 MusicPlayer를 사용하는 코드에서는 MusicPlayer 내부에 어떤 속성(데이터)이 있는지 전혀 몰라도 된다.
단순히 MusicPlayer가 제공하는 기능 중에 필요한 기능을 호출해서 사용하기만 하면 된다.
캡슐화 덕분에 코드가 더 읽기 쉬워질 뿐만 아니라 변경도 더 쉬워진다.
MusicPlayer 내부 코드가 변하더라도 MusicPlayer를 사용하는 개발자는 코드를 전혀 변경하지 않아도 된다.
예를 들어, MusicPlayer의 volume이라는 필드 이름을 다른 이름으로 변경하거나, 메서드 내부에서 출력하는 메시지를 변경할 때에도 MusicPlayer 내부만 변경하면 된다.
MusicPlayer를 사용하는 개발자는 MusicPlayer 내부 코드나 구현의 변경에 영향받지 않으므로 자신의 코드를 전혀 변경하지 않고 여전히 MusicPlayer를 사용할 수 있다.
(물론 외부에서 호출하는 MusicPlayer의 메서드 이름을 변경한다면 해당 메서드를 호출하는 곳의 코드도 변경되어야 한다.)
객체
음악 플레이어처럼 세상의 모든 사물을 단순하게 추상화하면 속성과 기능을 가지는 객체가 된다.
(물론 실세계와 객체가 항상 1:1로 매칭되는 것은 아니다.)
객체에는 속성과 기능만 존재하며, 이러한 객체 간의 상호작용을 중심으로 프로그래밍을 하는 것이 바로 객체 지향 프로그래밍이다.
앞으로 강의를 통해 캡슐화뿐만 아니라 상속, 다형성, 추상화, 메시지 전달 등 객체 지향의 다양한 특징들을 공부해보자.
'☕️ Java > 김영한의 실전 자바 - 기본편' 카테고리의 다른 글
[Java 기본] 6. 접근 제어자 (1) | 2024.09.16 |
---|---|
[Java 기본] 5. 패키지 (0) | 2024.09.16 |
[Java 기본] 4. 생성자 (2) | 2024.09.16 |
[Java 기본] 2. 기본형과 참조형 (0) | 2024.08.25 |
[Java 기본] 1. 클래스와 데이터 (0) | 2024.08.25 |
블로그의 정보
Claire's Study Note
Hi.Claire