객체 지향 프로그래밍

저번주에 한내용.

  • 레퍼런스
  • 오버로딩 등등 기본적인
  • class
  • -> 객체지향 프로그래밍이 그래서 뭔데
    • 이론 내용

개체지향 프로그래밍의 필요성

절차지향 프로그래밍 C언어

절차지향 프로그래밍(procedural programming)은 프로그램을 “절차(함수)의 집합”으로 보고 순서대로 실행되는 명령들의 흐름으로 문제를 푸는 방식이다. 데이터와 연산을 분리하여 함수가 전역 데이터나 매개변수를 조작하는 형태가 일반적이다.

주요 특징

  • 함수(프로시저) 중심: 동작을 작은 절차로 쪼갬.
  • 명령의 순서(제어 흐름)가 중요: 위에서 아래로 실행.
  • 전역 상태와 데이터 공유가 빈번함.
  • 모듈화는 파일/라이브러리 단위로 이루어짐(언어 지원에 따라 한계 존재).

장점

  • 단순하고 직관적: 작은 프로그램이나 성능이 중요한 코드에 적합.
  • 언어/런타임 오버헤드가 적음(저수준 제어 용이).
  • 배우기 쉬움, 기존 C 기반 생태계와 호환성 우수.

단점

  • 데이터와 동작이 분리되어 코드·데이터의 응집도가 낮음.
  • 프로그램 규모가 커지면 전역 상태 관리와 유지보수가 어려움.
  • 재사용성과 확장성이 떨어질 수 있음.
  • 어떤 함수가 어떤 데이터를 사용하는지 파악하기 힘듦(복잡도 증가).

간단 예제 (C)

// 전역 데이터와 절차들
int health = 100;

void take_damage(int d) {
    health -= d;
}

void heal(int h) {
    health += h;
}

int main() {
    take_damage(30);
    heal(10);
    return 0;
}

언제 쓰나

  • 시스템 프로그래밍, 임베디드, 성능 중심 코드, 작은 유틸리티 등에 적합.
    대규모 소프트웨어에서는 절차적 접근의 한계를 보완하기 위해 데이터와 동작을 묶는 방법(구조체+함수의 네임스페이스화, 모듈화 등)이나 객체지향 접근으로 전환하는 경우가 많다.

C언어도 이렇게 풀어져있는 문법들을 제한조건을 달면서 쓰면, 사실 객체지향프로그래밍 처럼 할 수 있다.

Cpp java C# 객체지향언어 : 말그대로 객체를 지향, 얘도 사실 절차지향적으로 얼마든지 할 수 있음

지향이라는건 결국 약속같은 느낌

차이가 뭐냐. 문법적인 지원의 차이

C언어에는 class의 멤버함수라는게 일단 없음

그래서 이 객체지향이 뭔데? 가 오늘 할 내용

구조체의 한계

절차적 언어의 아쉬운 점

  1. 데이터의 비인간화
  2. 데이터가 많아지면 관리가 힘듬

구조체의 등장

  • 데이터를 그룹으로 묶어 새로운 데이터 형을 만드는 방법
  • 하나의 변수처럼 사용
struct Human //구조체의 선언
{
    int age;
    float height;
}

Human dave; //구조체 변수의선언
Human fioan

구조체의 한계

  1. 데이터와 동작이 분리되어 있음
  2. 어떤 구조체가 어떤 함수란 연관 있는지 찾기 복잡함.

보완 : 파일 단위로 분리

이제부터 구조체는 객체라고 보자.

객체 : human, animal 물체이름

human 구조체

얘의 내부 변수 (private으로 이 실제 변수는 가림) int name; int age; int 성별; int 주민등록번호; int country;

외부 호출은 함수로 하자. 변수 : state 함수 : 개체의 행동

Animal DoGrowling(); DoSleep();

행동. 동사.

struct { } 동작이 문법적으로 연관지을 수 없음

보다 근본적인 문제

실세계에서 사람은 어떻게 생각하고 행동할까?

  1. 누구에게 말하고 있는가? : 실세계에서 누군가에게 이 말을 함.
  2. 미용사가 아이의 모든 정보를 알아야 하나? : 필요한 정보만 공개

사람은 세상을 물체(object)의 집합으로 인지.

일반적인 이야기 : 모든 것을 물체로 보진 않음 object를 프로그래밍에서는 객체 또는 개체라 번역. 물체는 상태를 가질뿐만 아니라 동작도 할 수 있음.

상태와 동작

  • 프로그래밍에서 변수는 상태를 저장
  • 동작 : 함수
  • 개체란 상태(변수 데이터) 외에 동작(함수)까지 포함

모든것이 개체는 아니다.

그리고 보통은 메소드가 argument로 넘어온 값을 직접적으로 변경은 잘 안해요.

개체지향 프로그래밍

  • object oriented programming
  • 프로그래밍 패러다임 중 하나
  • 프로그램을 구성하는 기본 요소를 개체로 보려는 노력.
  • OOP에서 프로그램이란?
    • 상호작용하는 개체들의 집합
    • 절차적 프로그래밍은 실행할 명령어의 목록을 프로그램으로 봤음

절차적 프로그래밍은 매우 객관적

  • 기계어는 위에서 아래로 차례대로 실행됨
  • 어셈블리 명령어는 거의 모든 경우 기계어로 1:1 치환가능
  • C 언어로 작성한 코드 한 줄은 보통 어셈블리 명령어 몇 개로 치환 가능
  • 함수 호출은 특정 메모리 위치로 jmp해서 순서대로 명령어를 실행하는 것
  • 그 명령어 실행 결과에 따라 레지스터 또는 메모리에 저장된 데이터가 변경

어떤 프로그램이라도 최종적으로는 절차적으로 돔

  • OOP는 기계처럼이 아니라 사람처럼 생각하자는 운동
  • 주관적
  • 사회와 기술이 발전함에 따라 사람들이 사고방식도 변함

oop는 주관적

  • 70+년 역사 동안 다양한 학설 및 의견이 등장하고 사라짐
  • object에 대한 정의조차 다양했음
  • 오늘날에도 어떤 자료를 보고 배웠냐에 따라 정의가 달라짐

다수가 따르는 OOP 개념이 있음

  • JAVA C# C++등 주류 OOP언어들이 교통정리를 끝냄
  • 많은 사람들이 따르고있음

OOP 토론 시 피해야 할 사람

올바른 OOP가 아니야!

  • 특정 소수설의 관점을 지지하는 사람
  • 역사적 가치가 있는 주장도 있음
  • 특수한 상황에서 올바른 방법이기도함.
  • 일반적으로 해가 되기 쉬움
  • 남들이 신경 안 쓰는 내용을 안다고 자신이 똑독한 사람은 아님
  • 진실을 전파하는 유일한 방법 : 장점을 최대한 객관적으로 보여준다.

순수 OOP 언어가 아니야!

  • 순수 OOP 정의는 존재하지 않음.
  • 모두가 동의하는 최소한의 특성은 있음
  • 순수 OOP를 주장하는 사람들의 흔한 패턴

모든 프로그램은 OOP로 만들어야 해!

  • OOPO가 절차적 프로그래밍을 완전히 대체할 거라는 주장도 있었음
    • 새로운 기법이 처음 등장할 때 많이 보이는 잘못된 주장
    • 요즘에는 다른 패러다임이 OOP를 완전히 대체할 거란 주장도 종종보임
  • 역사적으로 사실이 아님이 증명됨
  • OOP가 주류고 한동안 이어질것

~한 ~가 이리 말했으니 너는 틀려!

  • 그릇된 권위에 호소
  • 용어 처음 주창한 사람에 따르면~
  • ~책에 따르면
  • 제대로 된 실무자 또는 학자라면 ‘과학적 사고방식’을 따름

이 방법만 따르면 문제가 해결돼!

  • 훌륭한 프로그래머는 해결하려는 문제에 적절한 도구를 사용

믿고 거르자

OBJECT

  1. 개체란 서로 연관 있는 상태와 동작을 가지고 있다.(캡슐화)
  2. 사람들은 기본적으로 세상을 개체들의 모음으로 본다.

oop의 4대 특성

7대 개념

  1. encapsulation
  2. inheritance
  3. polymorphism
  4. abstraction
  5. association
  6. composition
  7. aggregation

캡슐화

  • 데이터와 그 데이터에 작용하는 메서드를 하나로 묶음
  • 정보 숨기기 개체 안에 있는 데이터를 외부로부터 보호

상속

진화

  • 이미 존재하는 개체를 기반으로 확장된 개체(클래스)를 만드는 방법
  • 확장된 개체
    • 기존의 개체에 속한 데이터와 동작을 모두 물려 받음
    • 여기에 다른 데이터나 동작을 추가할 수 있음
  • 코드의 중복을 막음
  • 사람에게는 점진적 학습이 가장 효율적
struct 객체

Human 
{
public:
    int name;
    int age;
    int country;
    bool isAdult;
}

Teacher a;

Teacher : Human
{
    virtual void DoSomething(){
        // 수업
    }
}

Student : Human
{
    virtual void DoSomething(){
        // 공부
    }
}


Teacher a;
a.DoSomething(); // 수업

Student a;
a.DoSomething(); // 공부

Human *b = &a;

b->DoSomething(); // virtual 이 붙어있으면 학생의 DoSomething을 호출함.

더 넓은관계고, 포함관계

다형성 <- 상속을 하는 가장 큰 이유.

같은 지시를 내렸는데 다른 종류의 개체가 동작을 달리하는 것.

  • 동일한 함수 시그내처 호출
  • 개체에 따라 달리 동작.

함수 구현이 실행될지는 실행 중에 결정됨 늦은 바인딩 late binding이라 함

일반적인 함수 호출은 이른 바인딩 early binding 컴파일중에 결정됨

다형성의 혜택을 받으려면 상속 관계가 필요

  • 부모 개체에서 함수 시그내처를 선언
  • 자식 개체에서 그 함수를 다르게 구현

-실용적인 용도: 다른 종류의 개체를 편하게 저장 및 처리 가능 bird cat dog 등을 animal 배열에 저장

struct animal{};
struct bird : public animal {
};

animal *a = new bird();
  • subtype 다형성 다형성은 99%이것을 지칭

다른 다형성

  1. 애드혹ad-hoc 다형성
    • 함수 오버로딩, 연산자 오버로딩
    • 함수명은 같은데 매개변수 목록이 다름
  2. 매개변수 다형성
    • C#과 java의 제네릭
    • C++의 템플릿

허나 둘 다 일반적으로 다형성이라고 안 부름 OOP하고도 상관없음

데이터 추상화

  • 수학 : 일반화란 의미(반의어 : 구체화)
  • OOP : 개체 속에 있는 실제 데이터나 함수 구현 방법에 종속되지 않겠단 뜻

  • 데이터 추상화 : 개체 사용 시 그 안에 정확히 어떤 데이터가 있는지 알 필요 없음, 개체 안에 잇는 데이터에 직접 접근 불가
    • 캡슐화는 데이터 추상화를 이루는 방법 중 하나
  • 추상화
    • 다형성을 통한 추상화
    • 추상 클래스(abstract class)나 인터페이스(interface)를 사용하는 추상화

컴포지션

부품

집합과의 차이 : 부품 그 자체로는 존재 의의가 없음 조립품이 소멸할때 부품도 같이 소멸

class 로봇
{
    팔 <- 요소 하나하나를 컴포지션이라고 함.
    다리
    몸통
    머리
}

oop에서 클래스

새로운 개체를 만들 때 사용하는 명세서 개체는 반드시 클래스로부터 만들어야 함

  • 속성(상태)
  • 동작
  • 등
#include <string>

enum class Sex { MALE, FEMALE };

class Human {
    std::string name;
    int age;
    Sex sex;
public:
    void walk() {
        age += 1;
    }
    void eat() {
        age -= 1;
    }
};

접근 제어자 public

멤버 함수 변수 앞에 외부에서 클래스 내부에 담긴 상태/동작에 접근하는 것을 허용

  • 여기서 외부는 다른 네임스페이스 또는 다른 번들(파일)

namespace character {
    class Human {
        int age; // 기본 접근지정자는 private
    public:
        Human() = default;
    };
}

using namespace character;

void SpawnNPC() {
    Human npc;
    npc.age = 20; // compile error: 'age'는 private 멤버
}

상태를 칭하는 용어

  • 멤버 변수(member variable)
  • 필드(field)
  • 속성(attribute)
  • 등

동작을 칭하는 용어

  • 멤버 함수(member function)
  • 메서드(method)
  • 메시지(message)

개체 만들기

Human adam;            // 스택에 생성
Human* ptr = new Human(); // 힙에 생성 (나중에 delete ptr 필요)

adam을 개체라 지칭

객체 vs 개체

  • OOP에서 물체 생명체를 지칭 : 개체라고 번역하는게 더 나은 방법

객체 : class의 name, 하나의 class인 변수를 의미하기도함.

인스턴스(instance) = 개체 = 객체 “후자만을 의미함” 인스턴스화(instantiation): 클래스로부터 개체 하나를 만드는 행위

개체 생성시 멤버 데이터를 0에 준하는 값으로 초기화 해줌 참조형은 null로 0이 아닌 다른 값으로 초기화하고 싶다면 선언문에 대입 가능

class Human {
    std::string name = "Human";
    int age;
    Sex sex;

    Human(){
        age = 20
        sex = Sex::MALE
    }
    Human(int a){
        name = "human";
        sex = Sex::MALE
    }
};

Human a; a.age == 20 // true

  • .을 통해 멤버에 접근 * ->를 사용.

생성자

//Human.h
class Human {
    const std::string name;
    int age;
    Sex sex;

public:
    Human(const std::string& name, int age, Sex sex);
};

 Human::Human(const std::string& name, int age, Sex sex)
        : name("name"), age(age), sex(sex) {
            
        }

// 사용
Human adam("adam", 20, Sex::MALE);
  • 반환형 없음(void아님)
  • 개체 생성 시에 자동으로 호출되는 특수한 함수
  • 함수명 클래스명과 동일(타입과 동일한 생성자)

코드 중복을 피하는 법

  • 매개변수 수가 적은 생성자에서 매개변수 수가 많은 생성자를 호출
class Human {
    std::string name;
    int age;
    Sex sex;

public:
    Human() = default;
    //virtual = 0
};

Human a;

매개변수를 받지 않는 생성자가 있어야 컴파일가능.

기본 생성자(default constructor)

  • 프로그래머가 생성자를 제공하면 기본 생성자는 생기지 않음
  • 필요하면 Human() = default; 또는 명시적으로 정의해야 함

results matching ""

    No results matching ""