객체지향(OOP - Object Oriented Programming) - C++/C#/CS 기초
객체지향(OOP - Object Oriented Programming)
📌 개념 정리
- 객체지향(OOP, Object-Oriented Programming)은 데이터와 행위를 객체 단위로 묶어서 설계하는 방법론.
- 주요 특징 (4대 특성)
1) 추상화 (Abstraction)
핵심 아이디어
- 복잡한 현실/구현 세부를 감추고 본질적인 공통 행위와 속성만 드러내는 것.
- C++에서는 주로 추상클래스와 순수가상함수로, C#에서는
abstract class
(또는 interface)로 표현.
예시
게임을 만드려고 한다. 여기서, 적과 주인공이 등장을 하고 서로 싸운다.
- 절차지향적 프로그래밍
- 각 적을 각각의 객체로 생성을 하고, 각각의 역할과 데이터, 작업을 작성한다.
- ex) enemy1 - 체력, 공력력, 방어력, 스킬, 등등…
- ex) enemy2 - 체력, 공력력, 방어력, 스킬, 등등…
- ex) hero - 체력, 공력력, 방어력, 스킬, 입력, UI연동 등등…
- OOP적 프로그래밍
- 공통된 요소를 하나로 묶은 추상 클래스를 생성하고, 이를 상속받은 각각의 자식 클래스를 만든다.
- ex) character class -> 체력, 공격력, 방어력, ID, 죽는 모션
- ex) enemy1: character class -> 스킬, 모션, sprite, (추가적으로 character class에 있는 것)
- ex) hero : character class -> 입력, UI연동, 스킬, 모션, sprite, (추가적으로 character class에 있는 것)
- 외부에서 호출할 때 단순하게 character class 를 호출하여 사용할 수 있다.
C++ 포인트
1
2
3
4
5
6
7
8
9
struct Shape { // [추상클래스](/posts/whatis-abstractclass/)
virtual ~Shape() = default;
virtual double Area() const = 0; // [순수가상함수](/posts/whatis-purevirtualfunction/)
};
struct Circle : Shape {
double r;
explicit Circle(double r) : r(r) {}
double Area() const override { return 3.14159 * r * r; }
};
C# 포인트
1
2
3
4
5
6
public abstract class Sensor { // [추상클래스](/posts/whatis-abstractclass/)
public abstract float Read(); // 추상 메서드 (= 순수 가상과 유사)
}
public class TempSensor : Sensor {
public override float Read() => 36.5f;
}
언제 쓰나 / 주의점
- “무엇을 할 수 있는가(계약)” 만 노출하고 “어떻게 하는가(구현)”는 감춘다.
- 추상화 계층이 과도하면 오히려 복잡도 ↑. 실사용 지점과 의미 있는 경계에서만 도입.
연결 개념: 추상클래스, 순수가상함수, 클래스, 상속, 다형성
2) 캡슐화 (Encapsulation)
핵심 아이디어
- 데이터와 행위를 하나의 클래스로 묶고, 접근 제어를 통해 내부 상태를 보호한다.
- 불변식(invariant)을 지키는 메서드만 외부에 공개 → 객체 일관성 유지.
C++ 포인트
-
private/protected/public
접근 지정자, 게터/세터 대신 의미 있는 동작 메서드 권장.1 2 3 4 5 6 7 8
class BankAccount { double balance_; // private -> 외부 직접 접근 불가 public: explicit BankAccount(double b) : balance_(b) {} void Deposit(double x) { if (x > 0) balance_ += x; } bool Withdraw(double x) { if (x <= balance_) { balance_ -= x; return true; } return false; } double Balance() const { return balance_; } };
C# 포인트
- 자동 속성 + 제한된 setter로 불변식 보존.
1 2 3 4 5 6 7 8
public class BankAccount { public decimal Balance { get; private set; } public void Deposit(decimal x) { if (x > 0) Balance += x; } public bool Withdraw(decimal x) { if (x <= Balance) { Balance -= x; return true; } return false; } }
언제 쓰나 / 주의점
- 외부에 상태 자체를 노출하지 말고, 의미 있는 행위만 제공.
- 캡슐화 약화 요인: public 필드 남발, 광범위한
friend
(C++), 무분별한 setter.
3) 상속 (Inheritance)
핵심 아이디어
C++ 포인트
-
public/protected/private
상속, 다중 상속 지원. - 다중 상속 시 다이아몬드상속문제 발생 가능 →
virtual
상속으로 해결.
1
2
3
4
struct A { virtual ~A() = default; };
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {}; // 다이아몬드 상속 문제 방지 (virtual 상속)
C# 포인트
- 단일 상속만 허용(클래스 기준). 다중 행위 확장은 인터페이스로 해결.
언제 쓰나 / 주의점
- “진짜 is-a인가?”를 먼저 검증. is-implemented-in-terms-of 라면 컴포지션이 더 적합.
- 상위 변경이 하위에 연쇄 영향(리스코프 치환 위반) 주의.
연결 개념: 다이아몬드상속문제, 다형성, 컴포지션, 클래스
4) 다형성 (Polymorphism)
핵심 아이디어
- 같은 메시지(인터페이스)에 여러 다른 구현이 응답.
- 정적 다형성(오버로딩/템플릿) + 동적 다형성(런타임 바인딩).
C++ 포인트 (동적)
-
virtual
함수 사용 시 객체에 가상함수vptr가 생기고, vtable을 통해 런타임 디스패치.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include <iostream> struct Base { void f() { std::cout << "Base::f\n"; } // 정적 바인딩 virtual void g() { std::cout << "Base::g\n"; } // 동적 바인딩 -> vtable }; struct Der : Base { void f() { std::cout << "Der::f\n"; } // 숨김(hiding) void g() override { std::cout << "Der::g\n"; } }; int main() { Base* p = new Der(); p->f(); // Base::f (정적 바인딩) p->g(); // Der::g (동적 바인딩, 가상 함수 vptr/vtable) delete p; }
C# 포인트
-
virtual/override
(동적 바인딩),sealed
(오버라이드 금지),new
(숨김) 등으로 제어.
1
2
class Base { public virtual void G() => Console.WriteLine("Base.G"); }
class Der : Base { public override void G() => Console.WriteLine("Der.G"); }
언제 쓰나 / 주의점
- 조건문 분기 대신 다형적 호출로 복잡도 감소.
- C++에선 소멸자도
virtual
고려(다형적 삭제 안전성). - 성능 민감 구간에선 정적 다형성(템플릿) 도 대안.
연결 개념: 가상함수vptr, vtable, 상속, 추상클래스
🔗 관련 페이지
🗺️ 개념 맵 (간단 다이어그램)
graph LR
OOP[객체지향](/posts/whatis-oop/) --> A[추상화]
OOP --> E[캡슐화]
OOP --> I[상속]
OOP --> P[다형성]
A --> AC[추상 클래스 / 순수 가상 함수]
P --> V[vptr / vtable]
I --> D[다이아몬드 상속 문제]
I --> C[컴포지션-대안]
This post is licensed under CC BY 4.0 by the author.