Unity Chapter 7-2. C# 프로그래밍 [중급] (2/2) : 상속
카테고리: Unity Lesson 1
태그: C Sharp Unity Game Engine
인프런에 있는 이제민님의 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리한 필기입니다. 😀
🌜 [레트로의 유니티 C# 게임 프로그래밍 에센스] 강의 들으러 가기!
Chapter 7. C# 프로그래밍 : 중급 (2/2)
🔔 상속
상속이란?
베이스가 되는 클래스(부모)를 가져와서 그 위에 나만의 클래스를
확장해서 만드는 것.
- A 클래스를 B, C, D 클래스가 상속 받는다면 B, C, D는 A의 기능들을 공통적으로 가지고 있게 된다.
- 어떤 공통적인 기능들은 부모클래스로 추상화해놓고 이를 여러 자식 클래스에서 상속받아 자신 만의 기능들을 추가로 덧붙이는 방식
상속과 다형성의 장점
- 코드를 재활용 할 수 있다.
- 구조를 간결하게 할 수 있다.
부모클래스 상속받는 방법 & MonoBehaviour
-
클래스 이름 뒤에
:콜론과 함께 파생할 부모클래스의 이름을 써주면 된다. -
MonoBehaviour는- 유니티에서 C# 스크립트를 만들 때 기본으로 붙는 부모클래스
- 이
MonoBehaviour이 가지고 있는 기능들을 기반으로 하여 본인만의 기능들을 쌓아올린다.
- 이
- 모든 컴포넌트들이 기본으로 가지는 기능들을 담고 있다.
- 오브젝트에 붙을 수 있다던지 유니티 엔진과 메세지를 주고 받는다던지 (ex. void Update, Start함수) 등등 모든 유니티의 컴포넌트들이 가지는 기본 기능
- c# 스크립트는
MonoBehaviour를 상속 받아야지만MonoBehaviour의 편의 기능들을 가질 수 있다.- 예를 들면 스크립트를 컴포넌트로서 오브젝트에 붙일 수 있고 유니티 엔진과 메세지 기반의 상호작용을 할 수 있는 등등
- 유니티에서 C# 스크립트를 만들 때 기본으로 붙는 부모클래스
📜Animal.h
📜 class Animal : 동물이 가지는 기초적이고 공통적인 데이터와 기능들이 들어가야 한다. ex) name, weight, age, 몸무게와 나이가 늘어나면 속도가 줄어드는 기능 등등
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Animal
{
public string name;
public float weight;
public int age;
public void Print()
{
Debug.Log(name + "| 몸무게: " + weight + "| 나이 " + age);
}
public float GetSpeed()
{
float speed = 100f / (weight * age);
return speed;
}
}
public class Dog : Animal
{
public void Hunt()
{
float speed = GetSpeed(); // 사용가능
Debug.Log(speed + " 의 속도로 달려가서 사냥했다.");
weight = weight + 10f;
Debug.Log("사냥 후 몸무게가 늘어 " + weight + "몸무게가 되었다.");
}
}
// 샌드박스 디자인패턴 : 미리 필요한 기능들은 미리 부모클래스에 싹다 모아놓고 자식클래스에서 마구잡이로 그것들을 조합해서 자신만의 기능을 만드는 것
public class Cat: Animal
{
public void Stealth()
{
Debug.Log("숨었다");
}
}
MonoBehaviour는 상속받지 않게 : MonoBehaviour 은 지워주었다.- 이제 📜Animal.h 는 다른 오브젝트에 붙일 수 없고 우리가 사용해 온 그 Update(), Start(), OnTriggerEnter() 같은 이벤트 함수들을 사용할 수 없게 된다.
- class Animal
- Animal의 데이터(멤버변수)
- name
- weight
- age
- Animal의 기능(멤버함수)
- public void Print()
- Animal 객체의 데이터(멤버변수)들을 출력해준다.
- public float GetSpeed()
- 속도를 리턴
- 몸무게와 나이가 늘어날 수록 속도는 줄어든다.
- public void Print()
- Animal의 데이터(멤버변수)
- class Dog
- Animal 클래스를 상속받는다.
- Animal의 데이터와 기능들을 모두 그대로 물려 받아 사용할 수 있다.
- Animal로부터 물려 받은 데이터와 기능들과 함께 Dog 만이 가지는 기능을 확장할 수 있다.
- Dog의 데이터(멤버변수)
- name (Animal로부터 물려받음)
- weight (Animal로부터 물려받음)
- age (Animal로부터 물려받음)
- Dog의 기능(멤버함수)
- public void Print()
- (Animal로부터 물려받음)
- public float GetSpeed()
- (Animal로부터 물려받음)
- 🖐 public void Hunt()
- Dog만이 가지는 기능이다.
- 사냥 기능 : 속도를 출력하고 몸무게를 늘리고 출력함
- Animal 로부터 물려받은 GetSpeed()와 weight을 사용할 수 있다.
- public void Print()
- Animal 클래스를 상속받는다.
- class Cat
- Animal 클래스를 상속받는다.
- Animal의 데이터와 기능들을 모두 그대로 물려 받아 사용할 수 있다.
- Animal로부터 물려 받은 데이터와 기능들과 함께 Cat 만이 가지는 기능을 확장할 수 있다.
- Cat의 데이터(멤버변수)
- name (Animal로부터 물려받음)
- weight (Animal로부터 물려받음)
- age (Animal로부터 물려받음)
- Cat의 기능(멤버함수)
- public void Print()
- (Animal로부터 물려받음)
- public float GetSpeed()
- (Animal로부터 물려받음)
- 🖐 public void Stealth()
- Cat만이 가지는 기능이다.
- 숨는 기능
- public void Print()
- Animal 클래스를 상속받는다.
📜Test.h
- 빈 오브젝트에 📜Test.h를 붙이고 유니티에서 실행해보자
- 📜Animal.h 는 현재
MonoBehaviour를 상속받지 않아 다른 오브젝트에 붙일 수 없음
- 📜Animal.h 는 현재
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Update()
{
Cat nate = new Cat(); // 고양이 객체
nate.name = "Nate";
nate.weight = 1.5f;
nate.age = 3;
Dog jack = new Dog(); // 강아지 객체
jack.name = "Jack";
jack.weight = 5f;
jack.age = 2;
nate.Stealth();
nate.Print(); // 부모인 Animal로부터 물려받은 기능
jack.Hunt();
jack.Print(); // 부모인 Animal로부터 물려받은 기능
}
}
cf. 샌드박스 디자인 패턴
샌드박스 : 필요한 기능들은 미리 부모클래스에 싹다 모아놓고 자식클래스에서 마구잡이로 그것들을 조합해서 자신만의 기능을 만드는 디자인 패턴
접근 지정자 public, private, protected
public이 붙은 멤버 변수와 멤버 함수는 자식이든 외부에서든 접근이 가능하다.private이 붙은 멤버 변수와 멤버 함수는 외부는 물론이고 자식 클래스에서도 접근이 불가능하다.- 상속시 자식에게 물려주기 싫은 멤버들은
private으로 하는 것이 좋다.
- 상속시 자식에게 물려주기 싫은 멤버들은
protected가 붙은 멤버 변수와 멤버 함수는 외부에서는 접근이 불가능하지만 자식 클래스 내에서는 접근이 가능하다.- 상속시 자식이 접근할 수 있게 그대로 물려주고 싶긴 하지만 외부에선 접근 못하게 하고 싶은 멤버들은
protected으로 하는 것이 좋다. - 외부에서 접근을 못하게 한다는 것은 객체로 접근하는 것도 포함이다.
- 부모클래스의 멤버 함수인 A()는
- 잘 물려주어 자식 클래스 내에서는 물려받은 멤버 함수로서 접근, 사용이 가능하지만
- 부모 클래스로 부모타입 객체를 생성하여 객체를 통해 접근하려 할 때는 접근이 불가능하다.
public class Parent { protected int A() // Parent 클래스의 A() 멤버 함수는 protected 이다. { return 1; } } public class Child : Parent { public void B() { A(); // 자식인 Child에서 상속되었는데 protected이므로 접근 및 사용 가능. Parent p; p.A(); // 에러! ⚡ 다만 외부에서는 사용 불가능. } } - 부모클래스의 멤버 함수인 A()는
- 상속시 자식이 접근할 수 있게 그대로 물려주고 싶긴 하지만 외부에선 접근 못하게 하고 싶은 멤버들은
접근 지정자를 사용하는 이유
코드를 바깥에서 봤을 때 적절히 숨겨놓으면 간결해지기 때문. 성능과는 거리가 멀고 단지 인간적인 개념에서 사용한다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글남기기