Reputation: 39
I am working on the rewriting of an old Java project to Go.
I've already done some Go at work but I can't figure out how I can translate my OOP (with abstract classes, etc.) to Go philosophy.
In the idea, I have two types (soon 3) that have some common methods, but some others (well just 1 or 2 max) should have the same signatures but not the same bodies.
I know Go does not have some kind of inheritance. For now I have something like this:
type A struct {...}
func (a *A) M1 (){ stuff1 }
func (a *A) M2 (){ stuff2 }
func (a *A) SM (){ special stuff A }
then:
type B struct {...}
func (b *B) M1 (){ stuff1 }
func (b *B) M2 (){ stuff2 }
func (b *B) SM (){ special stuff B }
I don't know how Go manages this. In Java I did an abstract class then implemented it with my two concrete classes.
What I would like is not having to duplicate M1() and M2(), but being able to have a generic type to call these methods on, then just have to define SM() for both types.
Upvotes: 2
Views: 93
Reputation: 46413
There's a couple different ways to solve this - embedding isn't the only answer. If these methods want to access data from the types they're defined in in your pseudocode (e.g. A.M1
needs to access fields of A
), then embedding will not help you, because an embedded type has no knowledge of the type it's embedded in. You'll need to reconsider your design holistically and as a Go program, not by designing it as if it were a Java program and trying to make those concepts work in Go. As many have found, attempting OOP design in Go tends to yield a great deal of frustration and very little success.
On the other hand, if these methods do not need to access any fields, then why are they methods? These could just be pure functions, which would make them easier to use and easier to reason about, and would completely eliminate any concerns of embedding or faking inheritance.
Upvotes: -1
Reputation: 64657
You can embed a struct, so something like:
type Common struct {}
func (c *Common) M1() {
fmt.Println("M1")
}
func (c *Common) M2() {
fmt.Println("M2")
}
type A struct {
Common
}
func (a *A) SM() {
fmt.Println("A SM()")
}
type B struct {
Common
}
func (b *B) SM() {
fmt.Println("B SM()")
}
type Thing interface {
M1()
M2()
SM()
}
func main() {
var a Thing = &A{}
var b Thing = &B{}
a.M1()
b.M2()
a.SM()
b.SM()
}
https://play.golang.org/p/Q3mIH_W8X44
Upvotes: 3