[C#과 유니티, 실전 게임으로 제대로 시작하기]섹션3-2. 스터디
상속 : 부모 클래스의 멤버를 자식 클래스가 물려받는 것이다.
-> 클래스명 뒤에 콜론(:)을 붙인 후 상속할 클래스 이름을 입력한다.
상위클래스 / 하위클래스
베이스(base) 클래스 / 파생(derived) 클래스
부모(parent) 클래스 / 자식(child) 클래스
로 각각 불린다.
** 자식 클래스는 여러 부모 클래스를 가질 수 없다. 반면, 부모 클래스는 여러 자식 클래스를 가질 수 있다.
스크립트1>
class Human{
public string name;
public float height;
public int age;
public string Name{
get{
return name;}
set{
name = value;}
public float Height{
get{
return height;}
set{
height = value;}
public int Age{
get{
return age;}
set{
age = value;}
public Human(){}
public Human(string _name, float _height, int _age){
name = _name;
height = _height;
age = _age;
}
public void Eat(){
Debug.Log("eat!");
}
public void Walk(){
Debug.Log("Walk!");
}
public void Sleep(){
Debug.Log("Sleep!");
}
}
스크립트2>
void Start(){
Adult Jane = new Adult();
Jane.Age = 20;
Jane.Eat();
}
class Adult : Human{
}
-> Jane의 age는 20으로 설정되고, eat!값이 콘솔에 출력된다.
if> 매개변수를 필요로하는 생성자에 접근하려면 어떻게 해야할까?
void Start(){
Adult Jane = new Adult("Jane", 165, 20); // 오류가 난다.
//기본 생성자인 class Human은 따로 명시하지 않아도 생성할 수 있지만, 따로 만든 생성자를 사용하려면 class Adult에 명시해야한다.
Jane.Age = 20;
Jane.Eat();
}
class Adult : Human{
}
->해결방법
void Start(){
Adult Jane = new Adult("Jane", 165, 20);
Jane.Age = 20;
Jane.Eat();
}
class Adult : Human{
public Human(string _name, float _height, int _age){
Name = _name;
Height = _height;
Age = _age;
}
}
protected : 자식 클래스에게만 멤버를 공개하는 접근제한자
this/base
this : 현재 객체를 가리키는 키워드
base : 부모 클래스를 가리키는 키워드
클래스에서의 형변환
ex>
일반적인 타입 : Human
특수한 타입 : Adult, Baby
ex>
void Start(){
Adult jinsoo = new Adult();
Human Jinsoo = jinsoo; //암시적 형변환
Human lina = new Human();
Adult Lina = (Adult)lina; //콘솔창에 오류가 뜬다.
// Adult class에는 Human 클래스가 상속해준 것을 가지고 있지만, Human class에는 포함되지 않는 멤버들이 있다.
//명시적 형변환이 가능한 방법
Human lina = new Adult();
Adult Lina = (Adult)lina;
}
as : 에러를 발생시키지 않고 형변환을 시도한다.
is : 형변환이 가능한지 체크한다.
as 사용법>
void Start(){
Human lina = new Human();
Adult Lina = lina as Adult; // Human 타입의 변수 lina를 Adult 타입으로 형변환을 하겠다는 의미이다.
if(Lina == null){
Debug.Log("실패"); //lina라는 객체는 Human 타입 객체를 담고있기 때문에 일반적인 타입은 특수한 타입으로 형변환이 될 수 없다.
}
else
Debug.Log("성공");
}
-> 실패 값이 콘솔창에 출력된다.
void Start(){
Human jina = new Adult(); //jina는 특수한 타입인 Adult를 객체로 갖고 있기 때문에 Adult로 형변환이 가능하다.
Adult Lina = jina as Adult;
if(Lina == null){
Debug.Log("실패");
}
else
Debug.Log("성공");
}
-> 성공 값이 콘솔창에 출력된다.
is 사용법>
void Start(){
Human human = new Human();
Human adult = new Adult();
Debug.Log(human is Human); // is 뒤에 나오는 값이 class의 이름이다. human이 Human 타입의 객체인지 알아본다.
// True 값이 콘솔창에 출력된다.
Debug.Log(adult is Human); // adult 타입의 객체는 Human 타입으로 암시적 형변환이 가능하다.
// True 값이 콘솔창에 출력된다.
Debug.Log(human is Adult); // False 값이 콘솔창에 출력된다.
Debug.Log(adult is Adult); // True 값이 콘솔창에 출력된다.
}
void Start(){
Human human = new Human();
Human adult = new Adult();
if (human is Adult){
Adult newAdult = (Adult)human;
}
}
메서드 오버라이드(Override)
메서드 오버라이드의 기본 구조
- 부모클래스의 메서드
접근제한자 virtual 반환타입 메서드_이름(매개변수){}- 자식클래스의 메서드
접든제한자 override 반환타입 메서드_이름(매개변수){}
class Human{
string name; //필드
float height;
int age;
public void Eat(){
Debug.Log("eat!");
}
public virtual void Walk(){ //virtual 작성한다.
Debug.Log("Walk!");
}
public void Sleep(){
Debug.Log("Sleep!");
}
}
class Baby : Human
{
public override void Walk //override를 작성한다.
Debug.Log("Crawl!);
}
void Start(){
Baby jun = new Baby();
jin.Walk();
}
-> Crawl 값이 콘솔창에 나온다.
class Human{
string name; //필드
float height;
int age;
public void Eat(){
Debug.Log("eat!");
}
public virtual void Walk(){ //virtual 작성한다.
Debug.Log("Walk!");
}
public void Sleep(){
Debug.Log("Sleep!");
}
}
class Baby : Human
{
public override void Walk //override를 작성한다.
Debug.Log("Crawl!);
}
void Start(){
Human person1 = new Human();
Human person2 = new Baby();
Baby person3 = new Baby();
person1.Walk(); // person1에 Huamn 타입이 담겨있다.
person2.Walk(); // person2에 Baby 타입이 담겨있다.
person3.Walk(); // person3에 Baby 타입이 담겨있다.
}
-> Walk!
-> Crawl!
-> Crawl! 값이 콘솔창에 출력된다.
class Human{
string name; //필드
float height;
int age;
public void Eat(){
Debug.Log("eat!");
}
public virtual void Walk(){
Debug.Log("Walk!");
}
public void Sleep(){
Debug.Log("Sleep!");
}
}
class Baby : Human
{
public new void Walk // override대신 new 키워드를 작성한다.
Debug.Log("Crawl!);
}
void Start(){
Human person1 = new Human();
Human person2 = new Baby();
Baby person3 = new Baby();
person1.Walk(); // person1에 Huamn 타입이 담겨있다.
person2.Walk(); // person2에 Baby 타입이 담겨있다.
person3.Walk(); // person3에 Baby 타입이 담겨있다.
}
-> Walk!
-> Walk!
-> Crawl! 값이 콘솔창에 출력된다.
new : 메서드를 재정의하는 것이 아닌 식별자만 가지고 완전히 다른 메서드를 정의하기 위해 사용된다.
메서드 오버로드란?
메서드의 식별자는 같지만 매개변수가 다른 여러 메서드를 정의하는 것이다.
void Start(){
Debug.Log(Add(1,2)); // 3값이 콘솔창에 출력된다.
Debug.Log(AddFloat(1.1f,2.2f)); // 3.3값이 콘솔창에 출력된다.
Debug.Log(AddDoblue(1.1d,2.2d)); // 3.3값이 콘솔창에 출력된다.
}
int Add(int a, int b){
return a+b;
}
float AddFloat(float a, float b){
return a+b;
}
double AddDouble(double a, double b){
return a+b;
}
식별자를 생성할 때 번거로움이 생긴다.
void Start(){
Debug.Log(Add(1,2)); // 3값이 콘솔창에 출력된다.
Debug.Log(Add(1.1f,2.2f)); // 3.3값이 콘솔창에 출력된다.
Debug.Log(Add(1.1d,2.2d)); // 3.3값이 콘솔창에 출력된다.
}
int Add(int a, int b){
return a+b;
}
float Add(float a, float b){
return a+b;
}
double Add(double a, double b){
return a+b;
}
->번거로움을 해결할 수 있다.