Study/유니티

C# 인터페이스, 추상클래스, 상속

Privacy TT 2020. 3. 18. 17:38

추상클래스

 

 = abstract

 

 

추상함수를 포함하려면 클래스자체가 abstract Class로 선언이 되어야함.

 

abstract void _name(); 식으로 구성되고, 본문은 정의할 수 없다.

 

인터페이스와는 다르게 필드 변수도 선언 가능하고 사용하는것도 상관없음

 

해당 클래스를 상속받았을 때 사용하는 방법은 override void _name() { 내용 }

이렇게 override키워드를 사용하는것.

 

 

 

유일한 단점은 다중상속이 안된다는점 - (참고 죽음의 다이아몬드 문제)

 

그래서 사용하는것이 아래의 인터페이스

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

인터페이스

 

 = interface

 

인터페이스자체가 추상화의 형태임, abstract의 집합체라고 볼 수도 있는데, 모두가 값이없고 추상화 형태이기때문에 다중상속이 가능함(사실 상속은 아니지만 형태가 상속 옆에 붙기때문에 상속으로 보는듯)

 

I가 붙은 것들이 거진 인터페이스이고 해당 인터페이스에서 정의해놓은 함수와 변수를 무조건 써야함 (값지정)

 

추상클래스처럼 필드변수는 선언할 수 없기때문에 함수, 속성, 인덱서, 이벤트만을 선언 가능.

 

다만 저런 속성 앞에 따로 public이라던지 그런 키워드는 안넣어줘도 되는듯.

 

 

속성시스템 같은걸 구현할 때 사용하면 아주 좋을 것 같은 기능

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

상속클래스 

 

A클래스 = 오리지날 : MonoBehaviour

B클래스 = 타겟클래스 : A

 

게임오브젝트에 B클래스만 넣고 쓸경우 B클래스에서 런타임 동작함수를 사용한다면, A클래스에 동작함수를 작성해놨어도 무시하고 B클래스의 함수만을 실행함 (Awake, Start, Update)

 

따라서 초기화를 A클래스에서 자체적으로 할 경우, B클래스에선 Awake를 쓰면 안됨. 다른 함수도 마찬가지

 

반대로 OnTriggerEnter같은 함수를 A클래스에 구현했다 하더라도, B클래스에서 그걸 구현하지않았다면 어떠한 객체가 B클래스만 가지고 있다 하더라도 부딪힐경우에 A클래스에 있는 OnTriggerEnter가 발동됨.

 

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

virtual 과 override 키워드

 

상속클래스에서 사용하는거고 기존에 부모가 가진 함수가 있을 때 그 함수를 virtual 키워드로 선언했으면

그 부모를 상속받은 자식클래스에서 override로 덮어씌울수가 있음.

 

만약 일반 부모클래스에서 public void Move(); 라는 함수가있고

자식에서 public void Move(); 라는 함수를 비슷한 기능이지만 살짝 다르게 사용하고 싶을 때는 public new void Move();  이런식으로 사용해서 아예 부모의 Move를 덮어버릴 수 있지만 그렇게되면 부모.Move()를 사용하는게 아니라 자식.Move()를 사용할 때만 new로 덮어씌운 애가 호출된다.

 

그래서 virtual과 override키워드를 사용하게되는데 부모에서 virtual void Move()를 선언하고 자식이 override void Move()를 했을 때, 부모.Move()를 호출하더라도 해당 오브젝트가 부모와 자식속성을 둘다 가진 객체일경우 override한 버전의 자식 Move()가 호출이 된다. (런타임에서 컴파일러가 알아서 체크함)

 

 

 

 

 

번외 - 오버로딩과 오버라이딩의 차이점

오버로딩 = 함수이름의 재사용 (매개변수를 바꿔서)

오버라이딩 = 다형성을 이용한 virtual, override키워드를 사용해서 덮어씌우는것

 

번외 2 override 앞에 sealed라고 봉인 조건을 넣을 수 있는데 그렇게 될 경우 해당 override를 제외하고 다른곳에선 추가적으로 오버라이드를 더 할 수 없음.