Unity/기능

[Unity] 제네릭(Generic) 을 통한 상속

turbulence93 2025. 5. 8. 20:30

1. 개념 정리

C#의 제네릭(Generic) 은 데이터 형식에 의존하지 않고 클래스나 메서드를 설계할 수 있게 해주는 기능이다.
제네릭을 통해 상속을 받으면 상속 받은 클래스에서 제네릭 값을 명시하여 설계할 수 있다.

같은 부모로부터 다른 값을 정의하는 자식 클래스를 만들수 있다.

 

2. 기본 구조 예시

// 제네릭 부모 클래스
public class BaseSkill<T>
{
    public string SkillName { get; set; }

    public virtual void Execute(T target)
    {
        Console.WriteLine($"{SkillName} executed on {target}");
    }
}

// 제네릭을 상속받은 자식 클래스1
public class FireBall : BaseSkill<Enemy>
{
    public override void Execute(Enemy target)
    {
        Console.WriteLine($"FireBall hits {target.Name} with flames!");
    }
}

//제네릭을 상속받은 자식 클래스2
public class Howling : BaseSkill<Player>
{
    public override void Execute(Player target)
    {
        Console.WriteLine($"Howling strikes fear into {target.Name}!");
    }
}

이런식으로 같은 부모에게 상속을 받아도 각자 다른 타입을 정의해 Player Skill과 Enemy Skill을 만들 수 있다.

 

3. 제약 조건 활용

제네릭 클래스의 타입에 제약 조건을 추가하여 안정성을 더 확보할 수 있다.
특정 조건을 만족해야 제네릭 타입으로 등록이 되게 하는것이다.

 

where 키워드를 사용해 제네릭 타입에 제약을 추가한다.

//공격을 받을수 있음을 명시하는 인터페이스
public interface IDamageable
{
    void TakeDamage(int amount);
}

public class DamageHandler<T> where T : IDamageable
{
    public void ApplyDamage(T target, int damage)
    {
        target.TakeDamage(damage);
    }
}

이 코드는 IDamageable 인터페이스를 구현해 공격을 받을 수 있는 객체만을 target으로 받는 제약 조건을 걸었다.
target이 Player든 Enemy든 Wall이든 IDamageable 인터페이스를 상속받는 개체라면 target으로 받을수 있음을 명시힌다.

 

이처럼 제약 조건을 통해 명확한 타입을 입력받아 코드를 보호할 수 있다.

 

4. 특징 정리

특징 설명
재사용성 중복 코드를 줄이고 공통 로직을 부모에 정의
타입 안전성 제약 조건을 활용한 명확한 타입 입력
다형성 같은 메서드 (Execute)로도 각기 다른 동작 수행 가능

 

개인적인 궁금증

처음에 제네릭을 보았을때 원하는 타입으로 알아서 형변환이 되는건가 싶어서 var와 같은 건가? 생각했다.

 

사용할 변수의 형식에 var를 사용하면 입력받은 데이터 형식에 맞춰 자동으로 형식을 정의하는데,

제네릭도 이와 비슷한 역할인줄 알았다.

 

얼핏 봤을때 비슷해 보였는데 직접 제네릭을 사용해보니 차이점이 명확해졌다.


제네릭은 상속받는 자식 클래스에서 타입을 명확하게 명시를 해주어야한다.

그렇게 제네릭은 내가 직접 타입을 명시하여 구조를 설계하는 것이다.

 

반면 var는 입력받는 데이터 형식이 정해져 있기 때문에 사실상 고정된 타입이다.
var는 입력받은 데이터의 타입을 간편하게 추론할 수 있게 도와주는 역할이라고 정리할 수 있곘다.

 

겉으로는 유사해 보였는데 직접 사용해보니, 의도화 역할이 완전히 다름을 알수 있었다!