futurelabunseen / B-JeonganLee

UNSEEN 2nd Term Learning and Project Repo.
5 stars 0 forks source link

7강: 언리얼 C++ 설계 I - 인터페이스 #33

Closed fkdl0048 closed 6 months ago

fkdl0048 commented 6 months ago

7강: 언리얼 C++ 설계 I - 인터페이스

언리얼 C++ 인터페이스

인터페이스란 객체가 반드시 구현해야 할 행동을 지정하는데 활용되는 타입으로 다형성의 구현의존성이 분리된 설계에 유용하게 활용된다.

데이터가 아닌 행동으로 책임에 초점을 맞춘다.

언리얼 엔진에서 게임 콘텐츠를 구성하는 오브젝트의 설계 예시로 월드에 배치되는 모든 오브젝트 중 움직이는 오브젝트에 대해 반드시 움직이게 하고 싶다면INavAgentInterface를 상속받아 구현한다. (Pawn)

예제를 위한 클래스 다이어그램

수업에 참여하는 사람과 참여하지 않는 사람을 구분하여 이를 인터페이스를 통해 구현해보자.

언리얼 C++ 인터페이스 특징

언리얼 C++ 인터페이스는 생성하면 두 개의 클래스가 생성된다. U로 시작하는 타입 클래스로 타입의 정보를 제공하는 역할과 I로 시작하는 인터페이스 클래스로 실절적인 설계 및 구현을 담당한다.

U타입 클래스 정보는 런타임에서 인터페이스의 구현 여부를 파악하는 용도로 사용되고, 실제로 U타입에서 작업할 일은 없다. 인터페이스에 관련된 구성 및 구현은 I인터페이스 클래스에서 진행된다.

언리얼 C++은 다른 객체지향 언어와 달리 인터페이스에도 구현이 가능하다.

C#만 써서 과연 인터페이스에도 구현을 하는 것이 좋은가? 라는 생각이 든다. 구현이 들어가는 순간 추상클래스로 전락하고 자율성이 떨어지는 것이 아닌가?

#include "MyGameInstance.h"

#include "Staff.h"
#include "Student.h"
#include "Teacher.h"

UMyGameInstance::UMyGameInstance()
{
 SchoolName = TEXT("기본 학교");
}

void UMyGameInstance::Init()
{
 Super::Init();

 UE_LOG(LogTemp, Log, TEXT("======================"));
 TArray<Uperson*> Persons = {NewObject<UStudent>(), NewObject<UTeacher>(), NewObject<UStaff>()};
 for(const auto Person : Persons)
 {
  UE_LOG(LogTemp, Log, TEXT("구성원 이름: %s"), *Person->GetName());
 }
 UE_LOG(LogTemp, Log, TEXT("======================"));

 for(const auto Person : Persons)
 {
  ILessonInterface* LessonInterface = Cast<ILessonInterface>(Person);
  if(LessonInterface)
  {
   LessonInterface->DoLessson();
  }
 }
 UE_LOG(LogTemp, Log, TEXT("======================"));
}
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "LessonInterface.generated.h"

// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class ULessonInterface : public UInterface
{
 GENERATED_BODY()
};

/**
 * 
 */
class UNREALINTERFACE_API ILessonInterface
{
 GENERATED_BODY()

 // Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
 virtual  void DoLessson() = 0;
 // or
 //virtual void DoLessson() { UE_LOG(LogTemp, Warning, TEXT("수업에 입장합니다.")); }
};
#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "person.generated.h"

UCLASS()
class UNREALINTERFACE_API Uperson : public UObject
{
 GENERATED_BODY()

public:
 Uperson();

 FORCEINLINE FString& GetName () {return Name;}
 FORCEINLINE void SetName (const FString& NewName) {Name = NewName;}
protected:
 UPROPERTY()
 FString Name;
};
#pragma once

#include "CoreMinimal.h"
#include "LessonInterface.h"
#include "person.h"
#include "Student.generated.h"

UCLASS()
class UNREALINTERFACE_API UStudent : public Uperson, public ILessonInterface
{
 GENERATED_BODY()

public:
 UStudent();

 virtual void DoLessson() override;
};
#include "Student.h"

UStudent::UStudent()
{
 Name = TEXT("이학생");
}

void UStudent::DoLessson()
{
 UE_LOG(LogTemp, Log, TEXT("%s님은 공부합니다."), *Name);
}

정리

Tips