如何定义具有属性的接口?

huangapple go评论74阅读模式
英文:

How to define an interface with properties?

问题

我有一个问题:是否可以为线性空间设置一个接口?

让我提醒你,在线性空间L中,有添加元素和将元素乘以一个数的操作。此外,满足两个性质:

1)a+b在L中

2)ak在L中,其中k是标量

我以以下形式呈现了线性空间的接口定义:

type Point interface {
}

type LinSpace interface {
    Sum(x, y Point)
    Prod(x Point, k float64)
}

如何在接口定义中考虑上述两个性质?

英文:

I have a question: is it possible to set an interface for a linear space?

Let me remind you that in linear space L there is an operation of adding elements and multiplying an element by a number. Moreover, two properties are fulfilled:

1)a+b in L

2)ak in L, where k - scalar

I presented the interface for linear space in the following form:

type Point interface {
}

type LinSpace interface {
    Sum(x, y Point)
    Prod(x Point, k float64)
}

how can i account for the above two properties in the interface definition?

答案1

得分: 0

接口只能包含方法。

你可以这样做:

// 《Effective Go》中说:接口名称应该包含前缀-er
type LinSpacer interface {
Sum() float64
Prod(k float64) float64
}

// 实现接口的结构体
type LinSpaceImpl struct {
A float64
B float64
}

// Sum() 方法的实现
// 此外,你不需要传递 A 和 B 变量
// 因为它们已经存在于 LinSpaceImpl 中
func (l *LinSpaceImpl) Sum() float64 {
return l.A + l.B
}

// Prod() 方法的实现
// 与 Sum() 方法不同,这里需要额外的参数 - k
// 所以它必须被传递,或者你可以将其添加到
// LinSpaceImpl 作为另一个字段,但这没有意义
func (l *LinSpaceImpl) Prod(k float64) float64 {
return l.A * k
}

// 无需的“构造函数”来优化你的主函数
// 并且使代码更清晰
func NewLinSpace(a, b float64) LinSpacer {
// 由于 LinSpaceImpl 正确实现了 LinSpacer 接口
// 你可以将 LinSpaceImpl 的实例作为 LinSpacer 返回
return &LinSpaceImpl{
A: a,
B: b,
}
}

然后你可以在你的主函数(或其他函数)中这样做:

// 使用任意的浮点数值
ls := NewLinSpace(11.2, 24.7)

fmt.Println(ls.Sum()) // 35.9
fmt.Println(ls.Prod(30.2)) // 338.23999999999995

这就是 Go 中的“面向对象编程”的工作原理。

英文:

Interfaces can contain only methods.

You can do something like this:

    // Effective Go says: interface names should contain prefix -er 
    type LinSpacer interface {
        Sum() float64
        Prod(k float64) float64
    }
    
    // Struct that implements interface
    type LinSpaceImpl struct {
    	A float64
        B float64
    }
    
    // Implementation of Sum() method
    // Also, You don't need to pass A and B vars
    // because they're already exist in LinSpaceImpl
    func (l *LinSpaceImpl) Sum() float64 {
        return l.A + l.B
    }
    
    // Implementation of Prod() method
    // Unlike the Sum() method, here we need extra param - k
    // So it has to be passed, or You can add it to
    // LinSpaceImpl as another fields but it doesn't
    // make any sense though
    func (l *LinSpaceImpl) Prod(k float64) float64 {
        return l.A * k
    }
    
    // Unnecessary "constructor" to optimize Your main function
    // And clarify code
    func NewLinSpace(a, b float64) LinSpacer {
    // Since LinSpaceImpl correctly implements LinSpacer interface
    // You can return instance of LinSpaceImpl as LinSpacer
        return &LinSpaceImpl{
    		A: a,
    		B: b,
    	}
    }

And then you can do this in your main (or other) function:

    // Use any float values
    ls := NewLinSpace(11.2, 24.7)
    
    fmt.Println(ls.Sum())      // 35.9
    fmt.Println(ls.Prod(30.2)) // 338.23999999999995

This is how "OOP" works in Go.

huangapple
  • 本文由 发表于 2023年3月30日 08:34:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75883226.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定