Unity 기본11 - class 상속, is, as 연산자

1. 상속

 

이미 만들어진 class의 특징을 모두 이어받은 상태에서, 새로운 기능을 추가한다

 

비슷한 기능을 가진 다른 객체를 만들어야하는데, 조금 다르다는 이유로 완전히 새로 만들어 쓴다면 좋지 않다

 

이미 만든 코드와 비슷한 코드를 또 만들 필요 없이 가능한 재활용하면서 쉽게 기능을 바꾸거나 추가 할 수 있는 것

 

코드의 재활용

 

코드의 재사용성

 

최근 개발 패러다임은 상속이 그렇게 가치있다고 보지는 않는다.. 그런가?

 

이전에 만든 Character class는 이름, 체력의 속성과 Hit, Heal, isAlive, Eat 의 method를 가진다

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Character
{
    string names;
    int hp;

    public Character(string characterName, int initialHP)
    {
        names = characterName;
        hp = initialHP;

    }

    public void Hit(int damage)
    {
        hp -= damage;
    }

    public void Heal(int heal)
    {
        hp += heal;
    }

    public bool isAlive()
    {
        return hp > 0;
    }

    public void Eat(Food food)
    {
        if (isAlive())
        {
            hp += food.hp;
        }
    }
}

 

 

 

이 class를 상속받아 새로운 기능이 추가된 class를 만든다

 

project - scripts 폴더에서 Wizard.cs 라는 새로운 스크립트 파일 생성

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wizard
{
}

 

 

이번엔 public class Wizard : Character이라고 쓴다

 

이렇게 하면 Character이라는 class를 상속받아 Wizard라는 class를 만든다

 

Character이라는 class가 가지고 있는 특성을 모두 이어받는다

 

 

원래는 스크립트 파일을 만들면 public class Wizard : MonoBehavior이라고 써져있는데,

 

이는 Wizard가 Unity가 미리 만든 MonoBehavior라는 class를 상속받았다는 뜻이다.

 

MonoBehavior은 Unity에서 객체를 사용할 때 필요한 다양한 기능들을 담고 있는 걸 만들어 뒀다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wizard : Character
{
}

 

 

상속시키는 Character을 부모, 상속받는 Wizard를 자식이라고 한다

 

이제 Wizard는 Character가 가지고 있는 모든 속성, method를 가진 채로 새로운 속성, method를 추가할 수 있다

 

일단 Wizard에 빨간줄이 그어져있는데, "잠재적 수정 사항 표시"를 눌러보면 visual studio가 알아서 고쳐주는데

 

 

 

그러면 Character가 가지고 있는 생성자와 비슷한 형태로 Wizard의 생성자를 만들어주는데

 

원래 Character의 생성자를 상속받아 Wizard의 생성자를 만든 것이다.

 

 

 

2. 기본 생성자

 

class의 경우 생성자가 없으면 기본 생성자라고 해서, 매개변수도 없고 내용도 없는 생성자를 만들어준다

 

다음과 같은 Character은 생성자가 없다

 

public class Character
{
    string names;
    int hp;

    public void Hit(int damage)
    {
        hp -= damage;
    }

    public void Heal(int heal)
    {
        hp += heal;
    }

    public bool isAlive()
    {
        return hp > 0;
    }

    public void Eat(Food food)
    {
        if (isAlive())
        {
            hp += food.hp;
        }
    }
}

 

 

그러면 내부적으로 

 

public Character() { }을 가지고 있는 것과 마찬가지다

 

 

 

 

parameter가 있는 생성자를 가지고 있다면, 내부적으로 기본 생성자를 만들지 않는다

 

 

 

 

애초에 Character의 생성자가 없다면, 자식 Wizard는 자동으로 만들어진 Character의 기본 생성자를 가져와 쓰게 된다

 

 

 

그런데 부모 Character에 parameter가 있는 생성자가 있으면, 기본 생성자를 만들지 않다보니 Wizard에는 에러가 난다

 

 

 

class가 가지고 있는 생성자는 여러개일 수 있다.

 

Character에 기본 생성자, parameter가 있는 생성자가 있을 때

 

 

 

 

이러면 Wizard는 Character의 기본 생성자를 상속받아, 에러가 나지 않는다

 

 

 

 

3. this

 

마법을 쓰는 캐릭터라는 의미에서, mp라는 속성 추가하고, 마법을 사용하는 method 추가

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wizard : Character
{

    int mp;

    public void UseMagic()
    {
        if (mp >= 5)
        {
            mp -= 5;
            Debug.Log("하아압!");
        }
    }
}

 

 

여기에 마나를 더하는 method

 

mp를 받아 원래 가지고 있는 mp에 더해줄건데, parameter의 mp와 속성의 mp가 이름이 같다

 

속성의 mp에 접근하고 싶으면 this.mp

 

그냥 mp라고 쓰면 parameter의 mp가 된다

 

this.은 파이썬의 self랑 비슷

 

 

 

 

4. Wizard class 사용

 

마나 20을 더해주고 마법을 사용해보기

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HelloWorld : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

        Wizard daehyuck = new Wizard();

        daehyuck.AddMP(20);

        daehyuck.UseMagic();


    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

 

 

 

Character의 method를 상속받으므로 다음과 같이 Character의 method Hit, Eat 등을 사용할 수 있음을 보여줌

 

 

 

 

5. is

 

Wizard가 Character을 상속받았으므로, Character 타입의 instance에 Wizard instance를 저장할 수 있다

 

 

 

 

새로 만든 raiden은 Character인가? Wizard인가? is 연산자를 이용해 다음과 같이 표현할 수 있다

 

 

 

 

둘 다 True인데?

 

raiden은 Character이기도 하고 Wizard이기도 하다.

 

 

 

 

6. as

 

반대로 Wizard ayaka에 Character raiden을 저장한다하면..

 

에러가 난다

 

raiden이 Character이기도 하고 Wizard이기도 해서 명확하지 않아서 에러가 난다

 

 

 

 

 

타입 캐스팅으로 Wizard라는 걸 명확하게 변환해준다

 

 

 

 

혹은 다음과 같이 as 연산자를 이용해 형변환할 수 있다

 

 

 

 

 

단순히 ()으로 타입캐스팅 하는 것과 as로 형변환하는 것은 무슨 차이가 있는가?

 

Character인 ayaka를 만들고, Wizard인 chiori에 Character ayaka를 Wizard로 형변환해서 넣어보면?

 

 

 

 

형변환이 불가능한 경우, ()으로 타입캐스팅하면 에러가 나고(명시적 형변환 불가능)

 

 

 

as로 형변환해서 넣는다면?

 

 

 

 

에러는 나지 않고 Null을 반환한다

 

 

 

 

as로 하면 코드가 에러나지 않고 전부 실행은 된다는거

TAGS.

Comments