与Go一起使用多态性

发布于 2025-01-25 11:11:08 字数 1797 浏览 1 评论 0原文

我正在尝试使用一些通用方法的基类,并创建另一个类,

package entity

import "fmt"

type Entity struct {
    Name      string
    Health    int
    DamagePts int
}

func NewEntity(name string, health int, damagePts int) Entity {
    entity := new(Entity)
    entity.Name = name
    entity.Health = health
    entity.DamagePts = damagePts
    return *entity
}

func (entity Entity) Attack(target *Entity) {
    target.TakeDamage(entity.DamagePts)
}

func (entity Entity) Defend(target *Entity) {
    target.TakeDamage(entity.DamagePts)
}

func (entity *Entity) TakeDamage(damage int) {
    entity.Health -= damage
    fmt.Println("Entity: ", entity.Name, " took ", damage, " damage")
    if entity.Health < 0 {
        entity.Health = 0
    }
}

func (entity *Entity) ShowHealth() int {
    return entity.Health
}

func (entity *Entity) Heal(health int) {
    entity.Health += health
    if entity.Health > 100 {
        entity.Health = 100
    }
}

func (entity Entity) IsDead() bool {
    return false
}

func (entity Entity) Speak() {
    fmt.Println("I am an entity")
}

该类别继承了基本方法的其他类 软件包怪物

import (
    e "magickombat/internal/pkg/Entity"
)

type EntityInterface interface {
    TakeDamage(damage int)
}

type Monster struct {
    EntityInterface
    e.Entity
    Level int
}

func New(name string, health int, damagePts int) Monster {
    monster := new(Monster)
    monster.Entity = e.NewEntity(name, health, damagePts)
    monster.Level = 1
    return *monster
}

func (monster Monster) Attack(target interface{}) {
    t := target.(e.Entity)
    t.TakeDamage(monster.DamagePts)
}

func Defend[T e.Entity](target T) {
    target.TakeDamage(45)
}

我尝试使用接口,但我有一个错误

内部/pkg/entity/monster/monster。

我在做什么错?

I'm trying to have a base class with some generic method and create an other class who inherit of the base's methods

package entity

import "fmt"

type Entity struct {
    Name      string
    Health    int
    DamagePts int
}

func NewEntity(name string, health int, damagePts int) Entity {
    entity := new(Entity)
    entity.Name = name
    entity.Health = health
    entity.DamagePts = damagePts
    return *entity
}

func (entity Entity) Attack(target *Entity) {
    target.TakeDamage(entity.DamagePts)
}

func (entity Entity) Defend(target *Entity) {
    target.TakeDamage(entity.DamagePts)
}

func (entity *Entity) TakeDamage(damage int) {
    entity.Health -= damage
    fmt.Println("Entity: ", entity.Name, " took ", damage, " damage")
    if entity.Health < 0 {
        entity.Health = 0
    }
}

func (entity *Entity) ShowHealth() int {
    return entity.Health
}

func (entity *Entity) Heal(health int) {
    entity.Health += health
    if entity.Health > 100 {
        entity.Health = 100
    }
}

func (entity Entity) IsDead() bool {
    return false
}

func (entity Entity) Speak() {
    fmt.Println("I am an entity")
}

The other class
package monster

import (
    e "magickombat/internal/pkg/Entity"
)

type EntityInterface interface {
    TakeDamage(damage int)
}

type Monster struct {
    EntityInterface
    e.Entity
    Level int
}

func New(name string, health int, damagePts int) Monster {
    monster := new(Monster)
    monster.Entity = e.NewEntity(name, health, damagePts)
    monster.Level = 1
    return *monster
}

func (monster Monster) Attack(target interface{}) {
    t := target.(e.Entity)
    t.TakeDamage(monster.DamagePts)
}

func Defend[T e.Entity](target T) {
    target.TakeDamage(45)
}

I try to use interfaces but I've an error

internal/pkg/Entity/Monster/Monster.go:30:9: target.TakeDamage undefined (type T has no field or method TakeDamage)

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱,才寂寞 2025-02-01 11:11:08

正如其他人指出的那样,存在多个问题。

内部/pkg/entity/monster/monster。

内部 类型约束应该是接口。尝试以下操作:

func Defend[T DamageTaker](target T) {
    target.TakeDamage(45)
}

type DamageTaker interface {
    TakeDamage(d int)
}

我正在尝试使用一些通用方法的基类,并创建一个继承基本方法的类

并不能真正提供通常的OOP继承。

但是,一个实现了与接口的多态性,请参见下面的示例。

package main

import "fmt"

type Talker interface {
        Talk(words string)
}

type Cat struct {
        name string
}

type Dog struct {
        name string
}

func (c *Cat) Talk(words string) {
        fmt.Printf("Cat " + c.name + " here: " + words + "\n")
}

func (d *Dog) Talk(words string) {
        fmt.Printf("Dog " + d.name + " here: " + words + "\n")
}

func main() {
        var t1, t2 Talker

        t1 = &Cat{"Kit"}
        t2 = &Dog{"Doug"}

        t1.Talk("meow")
        t2.Talk("woof")
}

输出:

Cat Kit here: meow
Dog Doug here: woof

As others pointed out, there are multiple issues.

internal/pkg/Entity/Monster/Monster.go:30:9: target.TakeDamage undefined (type T has no field or method TakeDamage)

Here the issue is you used struct Entity as type constraint, but type constraint should be an interface. Try this:

func Defend[T DamageTaker](target T) {
    target.TakeDamage(45)
}

type DamageTaker interface {
    TakeDamage(d int)
}

I'm trying to have a base class with some generic method and create an other class who inherit of the base's methods

Go doesn't really provide the usual OOP inheritance.

However one achieve polymorphism with interfaces, see example below.

Play it on playground.

package main

import "fmt"

type Talker interface {
        Talk(words string)
}

type Cat struct {
        name string
}

type Dog struct {
        name string
}

func (c *Cat) Talk(words string) {
        fmt.Printf("Cat " + c.name + " here: " + words + "\n")
}

func (d *Dog) Talk(words string) {
        fmt.Printf("Dog " + d.name + " here: " + words + "\n")
}

func main() {
        var t1, t2 Talker

        t1 = &Cat{"Kit"}
        t2 = &Dog{"Doug"}

        t1.Talk("meow")
        t2.Talk("woof")
}

Output:

Cat Kit here: meow
Dog Doug here: woof
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文