인터페이스(Interface)란?
- 인터페이스란 객체가 반드시 구현해야 할 행동을 지정하는데 활용하는 타입
- 다영형의 구현, 의존성이 분리된 설계에 유용하게 활용
언리얼 C++ 인터페이스의 특징
- 인터페이스를 생성하면 두 개의 클래스가 생성됨
- U로 시작하는 타입 클래스
- I로 시작하는 인터페이스 클래스
- 객체를 설계할 때 I 인터페이스 클래스를 사용
- U타입 클래스 정보는 런타임에서 인터페이스 구현 여부를 파악하는 용도
- 실제로 U타입 클래스에서 작업할 일은 없다.
- 인터페이스에 관련된 구성 및 구현은 I 인터페이스 클래스에서 진행
- C++인터페이스의 특징
- 추상 타입으로만 선언할 수 있는 Java, C#과 달리 언리얼은 인터페이스에서도 구현이 가능
언리얼 C++인터페이스를 사용하면, 클래스가 수행해야 할 의무를 명시적으로 지정할 수 있어 좋은 객체 설계를 만드는데 도움을 줄 수 있다.
코드로 확인해 보자
LessonInterface.h
#pragma once
#include "CoreMinimal.h"
#inlcude "UObject/Interface.h"
#include "LessonInterface.generated.h"
UINTERFACE(MinimalAPI)
class ULessonInterface : public UInterface
{
GENERATED_BODY();
// U타입 클래스는 런타임에서 인터페이스 구현 여부를 파악하는 용도
// 실제 구현은 I타입 인터페이스 클래스에서 진행
}
class UNREALINTERFACE_API ILessonInterface
{
GENERATED_BODY();
public:
virtual void DoLesson()
{
UE_LOG(LogTemp, Display, TEXT("수업에 입장합니다."));
// *언리얼 인터페이스는 추상 타입이 아니여서 메소드 구현 가능
}
}
Student.h
#include "LessonInterface.h"
#include "Student.generated.h"
UCLASS()
class UNREALINTERFACE_API UStudent : public UPerson, public ILessonInterface
{
GENERATED_BODY();
public:
UStudent();
virtual void DoLesson() override;
};
Student.cpp
#include "Student.h"
UStudent::UStudent()
{
Name = TEXT("손학생");
}
void UStudent::DoLesson()
{
ILessonInterface::DoLesson();
// 기본적으로 UStudent의 부모는 UPerson으로 되어 있어서 Super 클래스로 호출 불가능
UE_LOG(LogTemp, Display, TEXT("%s님은 공부합니다."), *Naem);
}
MyGameInstance.cpp
#include"MyGameInstance.h"
#include"Student.h"
UMyGameInstance::UMyGameInstance()
{
SchoolName = TEXT("손사장 학교");
}
void UMyGameInstance::Init()
{
Super::Init();
TArray<UPerson*> Persons = { NewObject<UStudent>(), NewObject<UTeacher>(), NewObject<UStaff>() };
for (const auto Person : Persons)
{
ILessonInterface* LessonInterface = Cast<ILessonInterface>(Person);
// 클래스를 찾아와서 변환에 성공하면 해당 클래스는 ILessonInterface를 상속 받은 클래스
if (LessonInterface)
{
UE_LOG(LogTemp, Display, TEXT("%s님은 수업에 참여할 수 있습니다."), *Person->GetName());
LessonInterface->DoLesson();
}
else
{
UE_LOG(LogTemp, Display, TEXT("%s님은 수업에 참여할 수 없습니다."), *Person->GetName());
}
}
}