본문 바로가기

Go

golang 상속 (상속아님)

Go 언어에서는 상속이라는 개념이 없지만 그걸 유사하게 구현할수 있는 방법은 임베딩이 있다.

하지만 임베딩을 한다고 해서 그건 상속과는 다르다.
상속은 내 표현으로 얘기하자면 직접연결이지만 고 언어에서 임베딩은 직접연결이 아니다.
하지만 겉으로 보기엔 직접연결을 하고 있는것처럼 보인다.

위와 같이 상속된 객체는 인스턴스 하나를 생성하지만
고랭에서 임베딩을 한다고 하면 임베디드 된 객체 하나와 임베딩한 객체가 각각 생성된다.
그러니 상속과 임베딩은 엄연히 다른 의미이지만 
위에서 얘기했듯이 Syntatic Sugar 로 인해 직접연결한 것처럼 보이고 그런식으로 사용된다.

 


한국 민속놀이중 하나인 스타크래프트로 예를 들어 보겠다.

저그의 유닛은 저글링과 히드라가 있다. (더 있는거 아는데 조용좀 해줄래?)
저글링과 히드라는 기본 유닛이지만 차이점이 하나 있다.
저글링은 진화를 할수 없지만 히드라는 럴커라는 놈으로 진화가 가능하다.

이 진화를 할수 있는 유닛을 임베딩으로 구현할수 있다.


코드를 보면서 이해해보자.

해처리와 저그 유닛에 해당하는 BasicCreature 구조체를 하나씩 만들었다.

BasicCreature 구조체에 Action 인터페이스에 해당하는 메서드를 구현해줬다.
저그 유닛은 기본적으로 움직이고 공격할수 있다고 가정한다.
Revolution() 은 진화인데 인터페이스에 담고 아무런 기능이 없다고 보면된다.

여기서 UpperCreature 는 BasicCreature 임베딩 한다.

우리는 이 임베딩한 구조체에 진화를 할수 있는 메서드를 구현한다.
위 Action 인터페이스에 대한 Revolution만 새로 정의해주면
Syntatic Sugar 로 UpperCreature 는 Action 인터페이스의 모든기능을 만족하고 진화를 할 수 있는 새로운 구조체가 된다.

히드라와 저글링을 초기화 할수 있는 메서드를 구현하고 이제 마지막 메인 함수를 실행시키면

해처리가 저글링과 히드라를 각각 생성한후 각각의 메서드를 사용해 보았다.
저글링한테 Revolution 메서드를 호출한다 해도 진화를 하지 못한다.
하지만 히드라는 메서드를 호출하면 진화를 할 수 있다.



아래에는 전체 코드다.
복사 붙여넣기만 해도 실행 가능하게 만들어놓았으니 마음대로 고쳐보고 Syntatic Sugar 와 Embedding 을 구현해보면 좋겠다.

package main

import "fmt"

type Hatchery struct {
}

type BasicCreature struct {
   Name string
}

type Action interface {
   Move()
   Attack()
   Revolution()
}

func (c *BasicCreature) Move() {
   fmt.Println(c.Name , "움직임")
}

func (c *BasicCreature) Attack() {
   fmt.Println(c.Name, "공격함")
}

func (c *BasicCreature) Revolution() {
}

type UpperCreature struct {
   BasicCreature
}

func (u *UpperCreature) Revolution() {
   fmt.Println(u.Name ,"진화중....")
   fmt.Println(u.Name ,"진화 완료")
}

func (h *Hatchery) NewCreature(name string) Action {

   basicUnit := &BasicCreature{}
   basicUnit.Name = name
   UpperUnit := &UpperCreature{}
   UpperUnit.Name = name

   switch name {
   case "저글링" :
      return basicUnit
   case "히드라" :
      return UpperUnit
   default :
      return nil
   }

}

func main() {
   hatchery := &Hatchery{}

   zergling := hatchery.NewCreature("저글링")

   zergling.Move()
   zergling.Attack()
   zergling.Revolution()

   fmt.Println("----------------")

   hydra := hatchery.NewCreature("히드라")

   hydra.Move()
   hydra.Attack()
   hydra.Revolution()

}