See the recent thread:
GO type embedding questions
(sorry, don't know how to link to it off-hand).
The essence is that you give the object corresponding to the
base class in your example one or more function pointers
to the "overridable methods" you'd use in a template method.
Or you pass in an object (of a class) satisfying an interface
which has the methods you want.
Chris
--
Chris "allusive" Dollin
You look it up or search for it on the google groups page,
http://groups.google.com/group/golang-nuts/topics
type embedding thread:
http://groups.google.com/group/golang-nuts/browse_thread/thread/a2f5868f6d364063#
To answer the question you define an interface with prepare and run
methods and then define a struct that embeds that interface and has
all the other methods that use prepare and run, then you create
instances of that struct with a Command or Spawner as the embeddee.
type NodeImpl interface {
Prepare()
Run()
}
type Spawn struct {
//whatever, has Prepare, Run methods
}
func NewSpawn() *Spawn {...}
type Node struct {
NodeImpl
//etc
}
func NewSpawnNode() *Node {
return &Node{NewSpawn(), ...}
}
func (n *Node) DoSomeWork() {
//...
n.Prepare()
//....
n.Run()
//...
}
Then NewSpawnNode().DoSomeWork() calls the Prepare and Run methods of Spawn
The code in the first thread post contains no data whatsoever. And can
be written that way:
type Node interface {
Prepare()
Run()
}
func doSomeWork(n Node) {
// ...
n.Prepare()
// ...
n.Run()
// ...
}
type Command struct {}
func (Command) Prepare() {
// ...
}
func (Command) Run() {
// ...
}
type Spawner struct {}
func (Spawner) Prepare() {
// ...
}
func (Spawner) Run() {
// ...
}
That's a fair point, and I suppose I jumped to type embedding because
it seemed like there was an implied desire was to create an object
that had several methods that used the same Node over and over and,
wrapping it to create more complex functionality out of a small set of
methods, and the assumption that the posted code was a simplified
sketch of what the OP wanted and not the complete implementation. But
Node could just as easily be a regular member or a parameter to a
method or function. Depends on how it's being used and why.
You don't need a "base class". You need a type with some data and
some methods. The "children of Node class" can refer to an instance
of that type to get their common data & behaviour. They may embed
that instance, or not, as they see fit. The "children" can even use plain
ordinary functions for the "common behaviour".
You don't need func or the semicolons here
> type Command struct {
> Node
> }
You need to embed the Work interface in Node and not Node in Command
(also you'd have to embed *Node since that's what has the methods on
it) and once you do that you call work and prepare like any other
method of Node. It may seem backwards, coming from a traditional OO
background. There's good info in the Go spec on embedding. You should
also read Effective Go if you haven't yet.
> func (command *Command) prepare() {
> ...
> }
>
> func (command *Command) work() {
> ...
> }
I think you'll need to explain exactly what you're trying to do and
why because it's not entirely clear if we're just talking about
syntax.