[Go] 7장 구조체와 인터페이스

1. 구조체 정의

Go에서 구조체는 사용자 정의 데이터 타입으로, 여러 개의 필드를 가질 수 있습니다. 예를 들어 Animal 이라는 구조체를 정의해 보겠습니다.

package main

import "fmt"

type Animal struct {
	Name string 
	Age int 
}

2. 인터페이스 정의

인터페이스는 특정 메서드를 가진 타입을 정의하며, 예를 들어 Speak 라는 메서드를 가진 Speaker 인터페이스를 만들어보겠습니다.

// interface 정의
type Speaker interface {
	Speak() string
}

3. 사용자 정의 데이터 타입

구조체가 인터페이스를 구현하도록 설정하고 Dog와 Cat이라는 두 개의 구조체를 만들어 보겠습니다.

// 사용자 정의 데이터 타입
type Dog struct {
	Animal
}

type Cat struct {
	Animal
}

 

이제 각 구조체에 대한 Speak 메서드를 구현합니다.

// Speak 메서드 구현
func (a Dog) Speak() string {
	return "Woof!"
}

func (a Cat) Speak() string {
	return "Meow!"
}

4. 다형성 구현

이제 Speak 인터페이스를 사용해 다형성을 구현하고, 다양한 동물들이 동일한 인테페이스를 구현하므로, 이를 통해서 서로 다른 타입을 동일한 방식으로 처리할 수 있습니다.

func main() {
	dog := Dog{Animal{"Buddy", 3}}
	cat := Cat{Animal{"Whiskers", 2}}

	makeSound(dog) // result: Woof!
	makeSound(cat) // result: Meow!
}

5. 전체 코드 예시

package main

import "fmt"

// Animal 구조체 정의
type Animal struct {
	Name string 
	Age int 
}

// interface 정의
type Speaker interface {
	Speak() string
}

// 사용자 정의 데이터 타입
type Dog struct {
	Animal
}

type Cat struct {
	Animal
}

// Speak 메서드 구현
func (a Dog) Speak() string {
	return "Woof!"
}

func (a Cat) Speak() string {
	return "Meow!"
}

func makeSound(s Speaker) {
	fmt.Println(s.Speak())
}

func main() {
	dog := Dog{Animal{"Buddy", 3}}
	cat := Cat{Animal{"Whiskers", 2}}

	makeSound(dog) // result: Woof!
	makeSound(cat) // result: Meow!
}

6. 젤다 게임 만들기

package main

import (
	"fmt"
	"math/rand"
	"time"
)

type Character struct {
	Name    string
	Health  int
	Attack  int
	Defense int
}

func (c *Character) AttackEnemy(enemy *Character) {
	damage := c.Attack - enemy.Defense
	if damage < 0 {
		damage = 0
	}
	enemy.Health -= damage
	fmt.Printf("%s가 %s에게 %d의 피해를 주었습니다!\n", c.Name, enemy.Name, damage)
}

func (c *Character) Defend() {
	c.Defense += 5
	fmt.Printf("%s가 방어 자세를 취했습니다! 방어력이 %d로 증가했습니다.\n", c.Name, c.Defense)
}

func (c *Character) Escape() bool {
	success := rand.Intn(2) // 50% 확률로 도망망
	if success == 0 {
		fmt.Printf("%s가 도망쳤습니다!\n", c.Name)
		return true
	} 
	fmt.Printf("%s가 도망치는 데 실패했습니다!\n", c.Name)
	return false
}

func (c *Character) isAlive() bool {
	return c.Health > 0
}

func (c *Character) ShowHealth() {
	fmt.Printf("%s의 현재 체력: %d\n", c.Name, c.Health)
}

func main() {
     rand.Seed(time.Now().UnixNano()) // 랜덤 시드 초기화


	link := Character{Name: "Link", Health: 100, Attack: 20, Defense: 5}
	ganondorf := Character{Name: "Ganondorf", Health: 120, Attack: 25, Defense: 10}

	for link.isAlive() && ganondorf.isAlive() {
		fmt.Println("\n 선택")
		fmt.Println("1: 공격")
		fmt.Println("2: 방어")
		fmt.Println("3: 도망가기")

		var choice int 
		fmt.Scan(&choice)

		switch choice {
		case 1:
			link.AttackEnemy(&ganondorf)
		case 2:
			link.Defend()
		case 3:
			if link.Escape() {
				fmt.Println("전투에서 도망쳤습니다.")
				return
			}
		default:
			fmt.Println("잘못된 선택입니다. 다시 선택하세요.")
			continue
		}
		// 공격후 현재 체력 출력 
		link.ShowHealth()
		ganondorf.ShowHealth()


		if !ganondorf.isAlive() {
			fmt.Printf("%s가 쓰러졌습니다!\n",ganondorf.Name)
			break
		}
		ganondorf.AttackEnemy(&link)
		if !link.isAlive() {
			fmt.Printf("%s가 쓰러졌습니다.", link.Name)
			break
		}

	}
}

 

 

GitHub - Koras02/Go-Bloging: https://thinky.tistory.com/category/Back-End/Go

https://thinky.tistory.com/category/Back-End/Go. Contribute to Koras02/Go-Bloging development by creating an account on GitHub.

github.com

 

LIST

'Back-End > Go' 카테고리의 다른 글

[Go] Go 라이브러리를 사용해 HTML 띄우기  (0) 2025.03.06
[Go] 8장(완) 고루틴과 채널  (1) 2025.03.04
[Go] 6장 맵  (0) 2025.03.03
[GO] 5장 배열과 슬라이스  (0) 2025.02.28
[Go] 4장 함수(Function)  (0) 2025.02.26