20240202_객체지향의 특징

2024. 2. 3. 17:04IT/TIL

오늘의 TIL은 어제에 이어진 내용으로 객체지향에 대한 내용이다.

 

객체지향이란

객체지향이란 아래에서 서술할 객체지향 프로그래밍보다는 좀 더 광범위한 개념으로,

데이터와 기능을 객체라는 단위로 조직화하는 것을 포함한 디자인 및 개발의 철학이다.

 

다시말해서 객체지향과 객체지향 프로그래밍은 엄밀히 말하면 조금의 차이가 있지만,

게임 개발의 영역에서는 두 단어가 거의 같은 의미로 사용된다고 할 수 있다.

 

 

객체지향 프로그래밍(Object-Oriented Programming, OOP)

객체지향 프로그래밍은 프로그래밍을 하는 과정에서 '객체'를 중심으로 프로그램을 설계 및 개발하는 것을 말한다.

 

다시 말해서 여러 독립적인 부품들을 조합해서 하나의 프로그래밍을 완성하는 방법을 말한다.

 

예를 들어서 자동차를 만든다고 했을 때, 자동차의 전체를 한 번에 만드는 것이 아닌

 

자동차를 구성하는 부품들(객체들)을 만든 후에 이들을 연결하여 자동차를 만드는 방법을 말한다.

 

객체지향 프로그래밍의 장점

OOP의 가장 큰 장점은 프로그램을 보다 유연하고 변경이 용이하게 만들 수 있다는 점이다.

 

자동차가 고장났을 때, 자동차를 교체하는 것이 아니라 고장난 부품을 교체하여 수리할 수 있는 것처럼

 

코드를 수정하는 경우에 코드의 변경을 최소화하고 유지보수하는데 유리하다.

 

더 나아가 코드의 재사용을 통해 반복적인 코드를 최소화하고, 코드를 최대한 간결하게 표현할 수 있다.

 

객체지향 프로그래밍의 핵심 원칙

1. 추상화(Abstration)

추상화란 객체의 공통적인 속성과 기능을 추출하여 정리하는 것을 의미한다.

 

자동차를 이어서 예로 들면 모든 자동차는 전진과 후진을 할 수 있는데

 

자동차 말고도 오토바이도 똑같이 전진과 후진을 할 수 있다.

 

이러한 경우에 자동차와 오토바이를 이동수단이라는 상위의 클래스로 묶을 수 있다.

 

이렇게 공통된 특징, 본질을 모아서 추출하는 것을 추상화라고 한다.

 

이는 설계(역할)와 구현을 분리하는 것인데,

 

인터페이스 등을 활용하여 어떤 객체가 가져야할 핵심적 기능을 규정하는 설계와

 

인터페이스를 상속받은 클래스에서 실제로 구현하는 구현 단계로 나눠서 관리할 수 있게 된다.

 

 

 

2. 상속성(inheritance)

상속성은 한 클래스가 다른 클래스의 속성과 메서드를 상속받아 사용할 수 있다는 원칙이다.

 

이 경우에 물려주는 클래스가 부모 클래스가 되고, 상속받는 클래스가 자식 클래스가 된다.

 

이 상속성으로 코드의 재사용성을 높이고, 유지보수를 용이하게 할 수 있다.

 

다시 말해서 중복되는 코드를 줄일 수 있으며, 하나의 코드를 사용하므로 오류를 줄일 수 있게 된다는 뜻이다.

 

이렇게 상속받은 코드는 overriding을 통해 재정의해서 사용할 수 있다.

 

사용 예시

더보기

게임에서 사용되는 상자를 만든다고 했을 때,

 

상자에 기본적인 기능은

 

1. 플레이어가 근처에 왔을 때, 상자를 열 수 있게 상호작용할 수 있어야되고,

 

2. 상호작용할 수 있을 때, 상자를 열 수 있어야 되고,

 

3. 상자를 열었을 때, 아이템을 획득하고, 이를 설명하는 텍스트를 띄우고 없애야되고,

 

4. 상자를 열지 않았을 때, 멀어지면 상호작용이 없어져야한다.

 

 

하지만 상자들의 종류가 많아지면 기능이 더 많아지게 되는데,

 

2번의 기능이 작동하지 않는 상자가 있을 수도 있고,

 

3번의 기능에서 상자를 열었을 때의 상황도 많이 달라질 수 있다.

 

예를 들면 아이템을 획득할 수 없는 상자도 있고, 획득할 수 있는 상자도 있고,

 

특수한 효과를 얻을 수 있는 상자도 있을 수 있다.

 

 

따라서 이를 하나의 스크립트에서 처리하려면 if문이 많아지는 현상이 발생하므로

 

이를 여러 스크립트로 나눠서 작성해야되는데 그렇게 된다면 중복되는 코드가 많아질 것이다.

 

이를 해결하기 위해서 기본적인 기능을 갖는 부모 클래스를 만든 후에

 

각자의 기능을 갖는 자식 클래스를 만들 수 있다.

 

 

예를 들면 아래의 코드와 같다.

 

// 부모 클래스

public class ChestBase : MonoBehaviour
{
    protected virtual void OpenChest()
    {
    	// 상자를 여는 기본 행동
    }
}

// 자식 클래스

public class ChestItem : ChestBase
{
    protected override void OpenChest()
    {
        base.OpenChest();

        if (_chestItem == ItemType.Gold)
        {
            ItemManager.Instance.AddItem(_chestItem, _chestItemID, 150);
        }
        else
        {
            ItemManager.Instance.AddItem(_chestItem, _chestItemID);
        }
    }
}

 

부모 클래스에서 상자를 여는 기본 행동을 정의한 후에

아이템의 타입에 따라서 얻을 수 있는 아이템을 다르게 정의할 수 있다.

 

 

 

3. 다형성(polymorphism)

다형성이란 같은 이름의 메서드가 다른 클래스에서는 다른 동작을 할 수 있도록 하는 특징이다.

 

오버로딩(매서드의 이름은 같지만 매개변수의 타입이나 개수가 다르게 만든 경우)과

 

오버라이딩(상속받은 매서드의 기능을 자식 클래스가 변경하는 경우)을 통해 구현된다.

 

예를 들어서 더하기를 하는 함수의 경우 아래와 같이 오버로딩을 사용하여 구현할 수 있는데,

 

public int Add(int a, int b)
{
    return a + b;
}

public int Add(int a, int b, int c)
{
    return a + b + c;
}

 

2개의 수를 더하는 함수와 3개의 수를 더하는 함수가 같은 이름으로 사용될 수 있다.

 

오버라이딩의 경우에는 위의 상속에서와 같은 코드이다.

 

부모 클래스의 OpenChest() 함수가 존재하고, 이를 상속받아 자식 클래스가 사용하는 경우

 

base.OpenChest()를 한 뒤에, 그 아래 필요한 추가 동작을 넣어서 구현하게 된다.

 

 

 

4. 캡슐화(Encapsulation)

캡슐화란 변수와 함수를 하나의 클래스로 묶어서 캡슐로 만들어서 외부에서 쉽게 접근하지 못하게 하는 것을 말한다.

 

예를 들어서 private, public, protected 등의 접근제어자를 사용하여

 

외부의 접근을 금지(private), 외부의 접근을 허용(public), 상속받은 접근만 허용(protected) 등으로

 

접근에 대한 제어를 가능하게 하는 것을 말한다.

 

 

 

오늘은 객체지향 프로그래밍에 대해 알아봤는데,

다음 TIL에서 객체지향 프로그래밍에서 빼놓을 수 없는 SOLID 원칙을 알아보고자 한다.