Go 는 상속이 없다. 대신 포함하는 것으로 상속의 효과를 누릴 수 있다. 여러개를 포함하면 다중상속과 같이 작동한다.
상속의 복잡도를 줄이기 위한 방편인것 같은데 뭔가 좀 어수선하고 마음에 안드는 부분이기도 하다.
어쨌든… 아래 예제는 상속과 다형성에 관해 정리해 본 예제이다.
[code]
package main
import “fmt”
type IAnimal interface {
GetName() string
Execute()
}
type Animal struct {
Name string
Age string
Email string
}
func (self *Animal) PrintName() {
fmt.Printf(“이름: %s\n”, self.Name)
}
func (self *Animal) GetName() string {
return self.Name
}
func (self *Animal) Execute() {
fmt.Println(“행동한다”)
}
func (self *Animal) Eat() {
fmt.Println(“먹는다”)
}
/***********
Dog
***********/
// Dog 구조체
type Dog struct {
// 포함을 하면 상속과 같이 사용할 수 있다
// 여러개를 넣어 다중상속 같이 사용할 수도 있다.
Animal
}
// Execute Override
func (d *Dog) Execute() {
fmt.Println(“빨리 달린다”)
}
// Bark 자신만의 Method
func (d *Dog) Bark() {
fmt.Println(“짖는다”)
}
/***********
Eagle
***********/
// Eagle 구조체
type Eagle struct {
Animal
}
// Execute Override
func (e *Eagle) Execute() {
fmt.Println(“훨훨 난다”)
}
// Legs 자신만의 Method
func (e *Eagle) Legs() {
fmt.Println(“다리가 두개다”)
}
// go 는 생성자가 없기 때문에 Factory를 만든다
func MakeEagle() *Eagle {
return &Eagle{
Animal{
“독수리”,
},
}
}
/***********
다형성 테스트를 위한 함수
***********/
// Explain IAnimal
func Explain(ani IAnimal) {
str := “이 동물의 이름은 %s(이)다.\n”
fmt.Printf(str, ani.GetName())
}
func main() {
// Dog 테스트
dog := &Dog{
Animal{
Name: “강아지”, // 필드 지정 대입 방식
},
}
dog.PrintName()
dog.Eat()
dog.Execute()
dog.Bark()
fmt.Println(“”)
// Eagle 테스트
// eagle := &Eagle{
// Animal{“독수리”}, // 필드 순서에 의한 대입 방식
// }
eagle := MakeEagle() // 팩토리에 의한 생성
eagle.PrintName()
eagle.Eat()
eagle.Execute()
eagle.Legs()
fmt.Println(“”)
// 다형성 테스트
animals := []IAnimal{}
animals = append(animals, dog)
animals = append(animals, eagle)
for _, ani := range animals {
Explain(ani)
}
}
[/code]
※ 결과
[code]
이름: 강아지
먹는다
빨리 달린다
짖는다
이름: 독수리
먹는다
훨훨 난다
다리가 두개다
이 동물의 이름은 강아지(이)다.
이 동물의 이름은 독수리(이)다.
[/code]