☕
Java Concept: OOP 4 Principles & Methods
이 포스팅은 객체 지향의 4대 원칙과 관련 문법, 사용 이유를 정리한 글입니다.
자바(Java)를 공부하다 보면 숨 쉬듯이 듣게 되는 단어가 있습니다. 바로 객체 지향 프로그래밍(OOP, Object-Oriented Programming)입니다.
"그냥 클래스 만들고 객체 생성하면 되는 거 아냐?"라고 생각하기 쉽지만, 실무에서 유지보수하기 좋은 코드를 짜기 위해서는 OOP의 4가지 핵심 원칙을 제대로 이해하고 있어야 합니다.
오늘은 캡슐화, 상속, 다형성, 추상화가 도대체 왜 필요하며, 자바에서 이를 구현하기 위해 어떤 키워드와 메서드를 사용하는지 완벽하게 파헤쳐 보겠습니다.
캡슐화 (Encapsulation)
캡슐화는 데이터(변수)와 그 데이터를 처리하는 코드(메서드)를 하나로 묶고, 외부로부터 보호하는 것입니다.
왜 사용하는가? (Why)
- 데이터 보호 (Data Integrity): 외부에서 변수에 직접 접근해 엉뚱한 값(예: 나이에 -5살)을 넣는 것을 방지합니다.
- 유지보수성: 내부 구현이 바뀌어도 외부에서는 메서드 이름만 알면 되므로 영향이 적습니다.
핵심 키워드 및 메서드
| 구분 | 설명 |
|---|---|
| 접근제어자 | private(나만), default(같은 패키지), protected(상속), public(모두) |
| Getter / Setter | 데이터를 읽고(Get), 검증 후 저장(Set)하는 메서드 |
public class BankAccount {
private int balance; // 1. private으로 잠금
// 2. Setter 메서드로 검증 로직 추가
public void setBalance(int amount) {
if (amount < 0) {
System.out.println("유효하지 않은 금액입니다.");
return;
}
this.balance = amount;
}
// 3. Getter 메서드로 읽기 권한 제공
public int getBalance() {
return this.balance;
}
}
상속 (Inheritance)
상속은 부모 클래스의 속성과 기능을 자식 클래스가 물려받아 확장하는 것입니다.
왜 사용하는가? (Why)
- 코드 재사용 (Reusability): 똑같은 코드를 여러 번 짤 필요 없이 부모의 것을 가져다 씁니다.
- 계층 구조 형성: 사물 간의 관계(IS-A)를 명확하게 표현하여 체계적인 설계가 가능합니다.
핵심 키워드 및 메서드
| 구분 | 설명 |
|---|---|
| extends | 클래스를 상속받을 때 사용하는 키워드 |
| super() / super. | 부모의 생성자를 호출하거나, 부모의 변수/메서드에 접근할 때 사용 |
class Car { // 부모
void drive() { System.out.println("운전합니다."); }
}
class SuperCar extends Car { // 자식 (extends 사용)
void booster() {
super.drive(); // 부모의 drive() 메서드 호출
System.out.println("부스터 가동!");
}
}
다형성 (Polymorphism)
다형성은 "하나의 객체나 메서드가 여러 가지 다른 형태를 가질 수 있는 성질"입니다. OOP의 꽃이라고 불립니다.
왜 사용하는가? (Why)
- 유연성 및 확장성: 새로운 클래스를 추가해도 기존 코드를 거의 수정하지 않고 그대로 사용할 수 있습니다.
- 일관된 인터페이스: 서로 다른 객체들을 하나의 타입(부모)으로 묶어서 관리할 수 있습니다. (예: `List list = new ArrayList()`)
핵심 키워드 및 메서드
| 구분 | 설명 |
|---|---|
| Overriding | 부모의 메서드를 자식 입맛에 맞게 재정의(덮어쓰기) |
| Overloading | 같은 이름의 메서드를 매개변수만 다르게 하여 여러 개 정의 |
| instanceof | 객체가 특정 클래스의 인스턴스인지 확인하는 연산자 |
class Animal {
void speak() { System.out.println("소리를 냅니다"); }
}
class Dog extends Animal {
@Override // 오버라이딩
void speak() { System.out.println("멍멍!"); }
// 오버로딩 (같은 이름, 다른 매개변수)
void speak(String mood) { System.out.println(mood + " 멍멍!"); }
}
추상화 (Abstraction)
추상화는 불필요한 세부 정보는 숨기고, 중요한 공통 기능(본질)만 추출하여 정의하는 것입니다.
왜 사용하는가? (Why)
- 설계의 표준화: 개발자들에게 "이 기능은 반드시 구현해야 해!"라고 강제성을 부여하여 일관된 설계를 유도합니다.
- 복잡도 감소: 구체적인 동작 방법(How)은 몰라도, 무슨 역할(What)을 하는지만 알면 사용할 수 있습니다.
핵심 키워드 및 메서드
| 구분 | 설명 |
|---|---|
| abstract | 추상 클래스나 추상 메서드를 선언할 때 사용 (미완성 설계도) |
| interface | 구현체가 없는 100% 껍데기, 다중 상속 가능 (설계 표준) |
| implements | 인터페이스를 구현할 때 사용하는 키워드 |
// 추상화: "그림을 그린다"는 기능만 정의 (껍데기)
interface Shape {
void draw(); // abstract method
}
// 구체화: 실제 어떻게 그릴지는 구현 클래스가 담당
class Circle implements Shape {
@Override
public void draw() { System.out.println("원을 그립니다."); }
}
OOP를 사용하는 이유
마지막으로 객체 지향 프로그래밍의 4대 원칙을 한눈에 정리해 봅시다.
| 원칙 | 핵심 키워드 | 사용 이유 (Benefit) |
|---|---|---|
| 캡슐화 | private, Getter/Setter | 데이터 보호 및 무결성 유지 |
| 상속 | extends, super | 코드 중복 제거, 재사용성 향상 |
| 다형성 | Overriding, Overloading | 유연한 확장, 변경 최소화 |
| 추상화 | interface, abstract | 복잡도 감소, 설계 표준 제시 |
객체 지향의 장점
객체 지향 프로그래밍(OOP)을 도입했을 때 얻을 수 있는 강력한 이점들을 정리해 보았습니다.
| 장점 | 설명 |
|---|---|
| 🛠 유지보수 용이 | 하나의 객체 또는 클래스 단위로 수정이 가능하여, 전체 시스템의 안정성을 유지하기 쉽습니다. |
| ♻️ 재사용성 증가 | 잘 설계된 클래스와 객체는 다른 프로젝트나 다양한 상황에서 쉽게 재활용할 수 있습니다. |
| 📈 확장성 우수 | 기능 추가 시 기존 코드를 건드리지 않고, 새로운 객체만 추가하면 되어 확장이 유연합니다. |
| 🌏 현실 세계 모델링 | 사람, 동물, 식물 등 실체를 코드로 자연스럽게 표현(매핑)할 수 있어 설계가 직관적입니다. |
| 👀 코드 가독성 향상 | 객체와 클래스 중심으로 역할이 명확하게 분리되어 있어, 코드를 읽고 이해하기가 쉬워집니다. |
💡 결론:
OOP는 단순히 코드를 짜는 문법이 아니라, "유지보수하기 쉽고 유연한 소프트웨어"를 만들기 위한 철학입니다.
이 핵심 원칙과 장점들을 마음속에 새기고 코딩한다면, 여러분의 코드는 훨씬 더 견고해질 것입니다.
OOP는 단순히 코드를 짜는 문법이 아니라, "유지보수하기 쉽고 유연한 소프트웨어"를 만들기 위한 철학입니다.
이 핵심 원칙과 장점들을 마음속에 새기고 코딩한다면, 여러분의 코드는 훨씬 더 견고해질 것입니다.
'Language > Java' 카테고리의 다른 글
| [JAVA] Stack 구현 & Stack Class의 문제점 (feat. Deque) (0) | 2025.12.19 |
|---|---|
| [JAVA] Collection Framework & Collections Class _ Part 1 (0) | 2025.12.16 |
| [JAVA] Getter/Setter 이중성 & 문제점 Refactoring (1) | 2025.12.12 |
| [JAVA] 접근제한자 & 캡슐화 (0) | 2025.12.12 |
| [JAVA] String vs StringBuilder vs StringBuffer 비교 정리 (왜 문자열을 다루는 클래스가 3개나 있을까?) (1) | 2025.12.04 |
