객체지향 프로그래밍
객체지향 프로그래밍 (Object-Oriented Programming)
객체지향 프로그래밍(OOP)은 실제 세계를 독립적인 객체(Object)들의 집합으로 보고, 이 객체들 간의 상호작용을 통해 프로그램을 설계하는 패러다임입니다. 데이터와 그 데이터를 처리하는 로직(메서드)을 하나의 객체로 묶어, 코드의 재사용성과 유지보수성을 높이는 것을 목표로 합니다.
🏛️ OOP의 4가지 핵심 특징 (기둥)
- 캡슐화 (Encapsulation)
> * '정의': 관련된 데이터(속성)와 그 데이터를 조작하는 함수(메서드)를 하나의 '객체'로 묶는 것입니다. > * '목적': 외부에서 객체 내부의 상태를 직접 조작하는 것을 막고, 오직 객체가 제공하는 메서드를 통해서만 상태를 변경하도록 하여 데이터의 무결성을 보장합니다. 이를 정보 은닉(Information Hiding)이라 합니다.
- 상속 (Inheritance)
> * '정의': 부모 클래스(Superclass)의 속성과 메서드를 자식 클래스(Subclass)가 그대로 물려받아 사용하는 것입니다. > * '목적': 코드의 중복을 제거하여 재사용성을 높이고, 클래스 간의 계층적인 관계(is-a 관계)를 형성합니다.
- 다형성 (Polymorphism)
> * '정의': '여러 형태를 가질 수 있는 능력'으로, 하나의 인터페이스나 부모 클래스 타입으로 다양한 자식 클래스 타입의 객체를 참조할 수 있는 성질입니다. > * '목적': 코드의 유연성과 확장성을 높입니다. 오버라이딩(Overriding)(재정의)과 오버로딩(Overloading)(중복정의)이 다형성을 구현하는 대표적인 방법입니다.
- 추상화 (Abstraction)
> * '정의': 객체들의 공통적인 속성과 기능(메서드)을 추출하여, 복잡한 내부 구현은 숨기고 외부에 필요한 핵심적인 부분만 노출하는 것입니다. > * '목적': 불필요한 정보를 제거하여 모델을 단순화하고, 중요한 문제에 집중할 수 있도록 합니다. `abstract` 클래스나 `interface`가 추상화를 구현하는 주요 도구입니다.
💡 SOLID: 좋은 객체지향 설계의 5원칙
SOLID는 유지보수 및 확장이 용이한 소프트웨어를 개발하기 위한 다섯 가지 설계 원칙입니다.
- SRP (Single Responsibility Principle, 단일 책임 원칙) : 하나의 클래스는 하나의 책임만 가져야 합니다.
- OCP (Open-Closed Principle, 개방-폐쇄 원칙) : 소프트웨어 요소는 확장에는 열려 있어야 하지만, 수정에는 닫혀 있어야 합니다.
- LSP (Liskov Substitution Principle, 리스코프 치환 원칙) : 자식 클래스는 언제나 부모 클래스 타입으로 대체될 수 있어야 합니다.
- ISP (Interface Segregation Principle, 인터페이스 분리 원칙) : 클라이언트는 자신이 사용하지 않는 메서드에 의존해서는 안 됩니다.
- DIP (Dependency Inversion Principle, 의존관계 역전 원칙) : 구체적인 클래스에 의존하지 말고, 추상화(인터페이스, 추상 클래스)에 의존해야 합니다.
🤔 객체지향 vs 절차지향 vs 함수형
- 절차지향 프로그래밍 : 데이터와 데이터를 처리하는 절차(함수)가 분리되어 있으며, 순차적인 코드 실행을 중시합니다. (C, Fortran)
- 객체지향 프로그래밍 : 데이터와 그 데이터를 처리하는 메서드를 '객체'로 묶어 관리하며, 객체 간의 상호작용을 중시합니다. (Java, C++)
- 함수형 프로그래밍 : 프로그램을 순수 함수(Pure Function)들의 조합으로 구성하며, 부수 효과(Side Effect)를 지양하고 불변성(Immutability)을 중시합니다. (Haskell, Lisp, 최근의 JavaScript/Python)