Game Development, 게임개발/개발

Polymorphism, 다형성 [Unity]

게임이 더 좋아 2021. 3. 26. 23:23
반응형
728x170

 

OOP의 큰 특징 중 하나인 다형성에 대해 알아보려고 한다.

상속에 그치지 않고 다양하게 활용될 수 있는 것은 얘 때문이다.

 

알아보자


 

상속의 의미를 안다면 바로 예를 들어서 보자

 

사실 다형성은 한가지의 클래스가 여러 자식클래스를 가질 때 거기서 의미가 생긴다.

예를 들어 

자동차 밑에는 버스, 택시, 트럭이 있는 것처럼

바퀴가 공통적으로 가지고 있고 다른 것도 공통적으로 가지고 있을 것이다.

그렇다면 굳이 버스, 택시. 트럭에 공통된 부분을 3번이나 쓰는 대신

부모클래스인 자동차에 넣어 효율을 추구하고자 함이다.

 

다시 말해서

상속은 받되 부모클래스에서 받은 내용은 공통적으로 가지고

때론 필요에 따라 부모에게 받은 것들도 오버라이딩을 통해 활용하자.

 

 

부모 클래스를 만들어보자

using UnityEngine;
using System.Collections;

public class Fruit 
{
    public Fruit()
    {
        Debug.Log("1st Fruit Constructor Called");
    }

    public void Chop()
    {
        Debug.Log("The fruit has been chopped.");        
    }

    public void SayHello()
    {
        Debug.Log("Hello, I am a fruit.");
    }
}

 

여기에는 생성자 하나와

2가지 메서드가 있다.

 

자식클래스를 만들어보자

using UnityEngine;
using System.Collections;

public class Apple : Fruit  // 부모클래스에게 상속받는다.
{
    public Apple()
    {
        Debug.Log("1st Apple Constructor Called");
    }

    // 사과에게는 부모에게서 받은  메서드 2개를 자신만의 방식으로 가진다.
    //과일의 메서드를 호출했을 때랑, 애플의 메서드를 호출했을 때랑
    //서로 다른 것을 알 수 있다.
    
    //"new" 키워드를 쓰면 유니티가 보내는 warning을 막으면서도 오버라이딩 되는 것을 막을 수 있다.
    //즉, 부모클래스 메서드랑 이름만 같지 나는 다른 메서드로 쓰겠다는 의미다.
    
    public new void Chop()
    {
        Debug.Log("The apple has been chopped.");        
    }

    public new void SayHello()
    {
        Debug.Log("Hello, I am an apple.");
    }
}

 

 

부모와 자식간의 관계를 알기 위해 사용해보자.

 

using UnityEngine;
using System.Collections;

public class FruitSalad : MonoBehaviour
{
    void Start () 
    {
        // "myFruit" 의 타입은 "Fruit"이지만 할당된 것은 "Apple"이다.
        //하지만 어쨌든 작동은 되는데 이것이 바로 다향성 때문이다.
		//사과는 어쨌든 과일클래스의 자식클래스다.
		// While the Apple reference is stored
        //in a Fruit variable, it can only be used like a Fruit
        Fruit myFruit = new Apple();

        myFruit.SayHello();
        myFruit.Chop();

        //아래와 같이 표현하는 것은 다운캐스팅, downcasting이라고 한다.
        // "Fruit" 타입이지만, "Apple"을 참조한다
        // 때문에, "Apple" 변수로 다시 바꿀 수 있다.
        //그렇게 되면 전엔 "Fruit"처럼 쓰였다고 해도 "Apple"을 다루는 것처럼 쓸 수 있다.
        
        Apple myApple = (Apple)myFruit;

        myApple.SayHello();
        myApple.Chop();    
    }
}

 

++다운캐스팅이란 부모 타입에서 자식 타입으로 바뀌는 것을 의미

++업이면 당연히 반대겠지.

 

**부모 타입의 변수로 자식 클래스의 객체를 참조할 수 있다. 이런 경우는 정말 흔하고 이렇게 쓴다.

사실 부모 타입으로 형변환이 되었더라도 원래 인스턴스는 Apple타입이면 

Apple 클래스의 2가지 메서드가 호출되어야 한다. 

-> 처음엔 나도 이렇게 생각했다.

 

하지만.. 실제로는 Fruit 타입의 메서드가 호출되었다.

 

 

그래서 다형성을 구현하려면 부모클래스에서 공통적인 부분에는 "virtual"이라는 키워드를 사용하고

자식클래스에서는 "override"라는 키워드를 사용하여 각 기능을 구현한다.

 

**말그대로 부모클래스 중 내가 필요한 것을 덮어씌워 자식클래스의 방식대로 실행시키겠다는 의미다.

 

반대로 부모클래스의 기능도 유지하며 자식 클래스마다 필요한 기능을 추가시키는 것도 가능하다. 

바로 "base"라는 키워드이다.

 

 

++base는 부모클래스를 참조한다는 뜻이라고 알아두면 되겠다.base.Method()를 하면 부모클래스를 불러오겠단 소리다.

 

 


참고링크

 

learn.unity.com/tutorial/polymorphism?uv=2019.3&projectId=5c88f2c1edbc2a001f873ea5#5c89267cedbc2a0d28f48487

반응형
그리드형