[C#] 객체 지향 프로그래밍(OOP)

Gee·2025년 2월 21일

프로그래밍 방식은 크게 절차 지향 프로그래밍객체 지향 프로그래밍으로 나뉜다.

절차 지향 프로그래밍?

절차 지향 프로그래밍은 순서를 따른다.
학교에서 집까지 가는 길을 찾는 프로그램을 만든다고 생각해 보자.
절차 지향 방식으로 접근하면 먼저 학교에서 출발해야 한다는 절차를 정의하면서 시작하고, 그 다음에 길을 따라 가는 방법, 교통 수단을 선택하는 방법들을 차례로 명령으로 만들어 나간다.
순서대로 진행되는 절차(함수나 명령)들로 구성하며, 프로그램이 어떻게 실행되어야 하는지, 단계별로 무엇을 해야 하는지를 중시한다.

객체 지향 프로그래밍?

객체 지향 프로그래밍은 조금 더 현실 세계에 가까운 방식으로 프로그래밍하는 방식이다.
현실 세계에 많은 객체들이 있듯, OOP에서는 모든 것을 객체로 바라본다. 여기서 객체란 데이터(속성)와 그 데이터와 관련된 기능(메서드)을 하나로 묶은 것을 말한다.
마찬가지로 학교에서 집까지 가는 길을 찾는 프로그램을 만든다고 생각해 보자.
그럼 객체 지향 프로그래밍에서는 학교, , , 교통 수단 등을 각각의 객체로 정의한다. 이 객체들이 서로 상호작용하면서 최종 목적지인 집에 도착하는 방법을 찾도록 만드는 것이다.

절차 지향: 함수와 데이터가 따로 있음
객체 지향: 객체 안에 데이터와 함수가 함께 있음

객체 지향 프로그래밍!

C#에서는 객체 지향 프로그래밍 방식을 사용한다.
가장 큰 특징은 클래스를 사용해 함수(처리 부분)변수(데이터 부분)를 하나로 묶어 객체(인스턴스)로 만들어 사용한다는 점.
객체 지향 방식을 적용할 때는 프로그램이 해결해야 할 문제를 작은 부분들로 나누고, 각 부분을 객체를 만든다. 이 객체들은 서로 상호작용하면서 전체 프로그램을 동작하게 한다.
객체들은 각자의 데이터를 가지고 있으며, 다른 객체들과 메시지를 주고받으며 상호작용 할 수 있다.

객체(Object)

  • 단위, 개념(추상적)
  • 소프트웨어 세계에 구현할 대상
  • 클래스에 선언된 모양 그대로 생성된 실체

클래스(Class)

  • 문법. 코드상에만 존재하는 것
  • 클래스는 실체화가 되지 않음.
  • 객체를 만들어 내기 위한 설계도 혹은 틀
  • 연관되어 있는 변수와 메서드의 집합
  • 컵이 있다면 컵의 기능은 클래스에 있고 컵의 본질은 오브젝트라는 것

인스턴스(Instance)

  • 메모리에 할당된 객체/클래스. 현실세계 = 힙에 존재하는 것
  • 연관되어 있는 변수와 메서드의 집합
  • 객체를 소프트웨어에 실체화 하면 그것을 인스턴스라고 부른다.
  • 오브젝트가 메모리에 할당되면 인스턴스(객체)
  • 클래스를 인스턴스로 만들 때 new Class()를 쓴다.
클래스(Class): 설계도 (예: "컵"이라는 개념)
객체(Object): 클래스에 따라 만들어진 실체 (예: "내 책상 위에 있는 빨간 컵")
인스턴스(Instance): 객체가 메모리에 할당된 상태

캡슐화

객체에 필요한 속성과 기능을 클래스로 관리. 객체는 기능을 제공한다.
기능을 제공하기 위해 캡슐화를 진행한다.

캡슐화는 객체의 데이터(속성)와 메서드(기능)를 하나로 묶고, 외부에서 직접 접근하지 못하게 보호하는 개념.
private, protected 등의 접근 제한자를 사용해 캡슐화를 구현할 수 있다.

객체 지향 패러다임의 4가지 특징

클래스 간의 관계를 상속 관계, 의존 관계, 연관 관계, 실체화 관계로 나눈다.

  1. 캡슐화(Encapsulation): 데이터 보호, 외부에서 직접 접근 불가능
  2. 추상화(Abstraction): 중요한 정보만 노출하고 내부 구현 숨김
  3. 상속(Inheritance): 기존 클래스를 확장해서 새로운 클래스 생성
  4. 다형성(Polymorphism): 같은 인터페이스로 다양한 객체를 다룰 수 있음

결합도가 높은 클래스는 다른 클래스와 연관 관계가 끈끈해서 만일 하나의 클래스의 구조를 변경하게 됐을 때 그에 연관된 클래스들도 전부 변경해야 할 수도 있고, 객체 사용 코드도 변경해야 할 수도 있어서, 유지보수 측면에서 마이너스적인 요소로 작용한다.

응집도가 높은 모듈은 하나의 모듈 안에 함수나 데이터와 같은 구성 요소들이 하나의 기능을 구현하기 위해 필요한 것들만 배치되어 있고 긴밀하게 협력한다.

객체 지향 프로그래밍의 좋은 설계

  1. 결합도(의존도)를 낮추고 응집도를 높인다.
  2. 객체 내부의 상태를 캡슐화 하고 오직 메시지를 통해서만 상호작용한다.
  3. 단일 클래스 상속보단 다중 인터페이스 상속(인터페이스를 이용한 다중 구현)을 지향한다.

높은 결합도 (Bad)

class A
{
    B b = new B(); // A가 B에 강하게 의존함
}

낮은 결합도 (Good)

class A
{
    IB b; // 인터페이스를 사용하여 의존성을 줄임
    public A(IB b) { this.b = b; }
}

다형성: 오버라이딩, 인터페이스 활용

interface IAnimal
{
    void Speak();
}

class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("멍멍!");
    }
}

class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("야옹!");
    }
}

class Program
{
    static void MakeSound(IAnimal animal)
    {
        animal.Speak(); // 인터페이스를 활용한 다형성
    }

    static void Main()
    {
        IAnimal dog = new Dog();
        IAnimal cat = new Cat();
        MakeSound(dog); // 멍멍!
        MakeSound(cat); // 야옹!
    }
}

야옹

profile
...

0개의 댓글