본문 바로가기

취미로 하는 게임코딩_gameCodingAsHobby/유니티unity로 게임 만들기

유니티19_C#_12_다형성

이번에는 객체 지향 언어에서 클래스라는 구조를 지지하는 다형성(Polymorphism)에 대해 알아본다.

 

poly는 many(많은)이라는 뜻이고, morph는 form, shape(모양)이라는 뜻이다.

그래서 다형성은 '많은 모양을 가짐'이라는 뜻이다.

 

생물학에서 다형성은 유전자의 변이를 나타내는 것과 같이 코딩에서 다형성은 클래스의 메서드가 형태는 같지만 다른 역할로 변이할 수 있다는 것을 말한다.

 

간단한 예로 앞 글 '상속'에서 보았듯이 base클래스(부모)에서 파생된 derived클래스(자식)가 여러 개 또는 다양한 형태로 만들어질 수 있다는 것이 바로 다형성이다.

 

메서드 오버라이드(override)

 

override는 '위에 + 올라타다'가 합쳐진 글자인데 기존 상태를 짓밟고 올라타서 다른 것으로 대체하다는 뜻이다.

 

코딩에서 메서드의 오버라이드는 파생(자식)클래스에서 부모클래스의 메서드를 우선하여(위에 올라타서) 다시 정의하는 것을 말한다. 하지만 완전히 무시할 수는 없고 접근제한자, 반환타입, 메서드명, 매개변수는 같아야 한다.

부모에서 물려 받았기 때문에 당연한 것이다.

 

즉, 메서드의 형태는 같고, 역할을 다시 정의하는 것이다.

 

이때 부모클래스의 메서드에는 virtual , 자식클래스의 메서드에는 override 키워드를 붙여야 한다.

 

*virtual : 사실상의

*override : 우선하는

 

부모클래스와 자식클래스에서 virtual과 override 메서드를 만든 예는 다음과 같다.

 

부모클래스(MainCharacter)의 메서드인 Talk( )는 문자열 'virtual Talk Method'를 출력하고

자식클래스(Hero)의 같은 메서드는 'override Talk Method'을 출력하는 코드이다.

 

확인하기 위해 객체를 만들어서 Talk메서드를 호출해보자.

 

 

7번줄에서 부모클래스 타입의 변수 starOne에 부모클래스의 기본생성자로 만든 객체를 저장한다.

8번줄에서 자식클래스 타입의 변수 ironMan에 자식클래스로 만든 객체를 저장한다.

9번줄에서 부모클래스 타입의 변수 starTwo에 자식클래스로 만든 객체를 저장한다. (부모가 자식을 품은 암시적 타입 변환)

 

각각의 객체에서 Talk메서드를 호출하면 어디에 있는 메서드를 호출하는 지 확인할 수 있다.

 

세번째와 같이 타입 변환된 경우는 부모클래스 타입의 변수에 저장되었지만 객체가 자식클래스로 만들었기 때문에 Talk메서드를 호출하면 자식클래스의 메서드를 호출한다. 이것은 override하여 부모클래스에 우선한 결과이다.

 

new 키워드

만약 부모클래스의 메서드를 다시 정의하는 차원이 아니라 (override 안함) 완전히 다른 메서드인데 메서드 이름만 같게 하려면 override 대신 new 키워드를 사용하면 된다.

 

위와 같이 수정하면 부모클래스의 Talk() 메서드와 자식클래스의 Talk()메서드는 이름만 같을 뿐 관계가 1도 없는 별개의 메서드로 취급한다. 

실행하면 아래와 같은 결과가 나온다.

 

첫번째, 두번째 메서드 호출은 같지만 세번째 타입 변환된 경우는 부모클래스 타입의 변수에 저장된 객체가 자식클래스로 만들었지만, Talk메서드를 호출하면 자식클래스의 Talk메서드를 호출하지 않고 부모클래스의 Talk메서드를 호출한다. 이것은 override가 아니라 완전히 다른 새로운 Talk메서드로 취급하여 부모클래스에 우선하지 않은 결과이다.

 

메서드 오브로드(overload)

overload는 '위에 + 짐을 싣다'는 뜻이 합쳐진 단어이다.

코딩에서 메서드 overload는 같은 클래스에서 이름은 같지만 매개변수가 다른 메서드를 만드는 것이다.

 

예를 들어 인수로 전달 받은 두 수를 더하여 반환하는 Plus 라는 메서드를 만든다고 해보자.

 

두 정수(int)를 인수로 받아서 플러스(더하기) 한 후 반환한다면 다음과 같은 메서드를 만들 수 있다.

 

int PlusInt(int a, int b)

{ return a + b; }

 

추가로 두 소수를 float 타입 인수로 받는 메서드와 double 타입 인수로 받는 메서드를 만든다면 다음과 같다.

 

float PlusFloat(float a, float b)

{ return a + b; }

 

double PlusDouble(double a, double b)

{ return a + b; }

 

위 세 메서드는 반환값과 매개변수 타입만 다르고 기능은 같다.

그런데 메서드 이름은 각기 다르므로 메서드를 호출해야 할 때 인수에 따라 다른 메서드를 호출해야 할 것이다.

이런 경우에 메서드 오버로드를 이용해서 메서드명을 통일해서 만들어 두면 인수 타입에 따라 자동으로 메서드를 호출하므로 편리하다.

 

메서드 오버로드를 사용해서 메서드를 만들고 인수를 전달하여 호출해서 확인한다.

 

메서드를 호출하면 전달한 인수의 타입에 따라서 자동으로 해당 메서드의 매개변수로 전달한다.

9번줄의 소수 전달은 double(더블)타입을 나타내며 (3.0D, 4.2D) 또는 (3.0d, 4.2d)로 입력해도 된다.

소수를 입력할 경우 숫자 끝에 타입의 첫글자를 입력하지 않으면 기본적으로 double타입으로 인식한다.

 

메서드 호출 결과는 위와 같다.

 

아래 그림에서 볼 수 있듯이 클래스의 생성자를 만들 때도 오버로드를 적용한 것임을 알 수 있다.

 

 

끝.

Wraven...