Class Inheritance: Go v.s. C++

  • It is true that Go does not support class and class hierarchy, but its embedding mechanism can support code reusing as class inheritance in C++.  The details about embedding in Go is introduced in Effective Go.  Here I just list a side-by-side comparison of multiple inheritance in C++ and a similar thing implemented using struct embedding of Go.

The C++ version runs first:

#include <iostream>
#include <string>

class EditBox {
 public:
 std::string GetInput() { return "Input in edit box."; }
 void Display() { std::cout << "I am an edit box.\n"; }
};

class ListBox {
 public:
 std::string GetListFocus() { return "The focus in the list."; }
 void Display() { std::cout << "I am a list box.\n"; }
};

class ComboBox : public EditBox, public ListBox {
 public:
 void Display() { EditBox::Display(); ListBox::Display(); }
};

int main() {
 ComboBox* c = new ComboBox;
 c->Display();
 std::cout << c->GetInput() << "\n" << c->GetListFocus() << "\n";
 return 0;
}

Then, the Go version:

package main

import (
 "fmt"
)

type EditBox struct {}
func (e *EditBox) GetInput() string { return "Input in edit box." }
func (e *EditBox) Display() { fmt.Printf("I am an edit box.\n") }

type ListBox struct {}
func (l *ListBox) GetListFocus() string { return "The focus in the list." }
func (l *ListBox) Display() { fmt.Printf("I am a list box.\n") }

type ComboBox struct {
 *EditBox
 *ListBox
}
func (c *ComboBox) Display() { c.EditBox.Display(); c.ListBox.Display() }

func main() {
 c := new(ComboBox)
 c.Display()
 fmt.Printf("%s\n%s\n", c.GetInput(), c.GetListFocus())
}

You see, the resolving of conflicted name is supported by both C++’s multiple inheritance (line 18 of the first example) and Go’s struct embedding (line 19 of the second example).

Few more words on Go’s embedding mechanism from Effective Go: there are two kinds of embeddings in Go: through interface and through struct. Above example shows the latter case. The syntax of interface embedding is

type ComboBox interface {
  EditBox
  ListBox
}

and the syntax of struct embedding is

type ComboBox struct {
  *EditBox
  *ListBox
}

The difference is: there are no * in interface embedding, but they are there in struct embedding.