Interface Embedding

// A ReadWriter can do what a Reader does and what a Writer does.
type ReadWriter interface {
    Reader
    Writer
}

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

Only interfaces can be embedded within interfaces.

Struct Embedding

Explicit Embedding

It doesn’t satisfy the ReadWriter’s Embedded Interface, unless ReadWriter write methods itself.

type ReadWriter struct {
    reader *bufio.Reader
    writer *bufio.Writer
}

func (rw *ReadWriter) Read(p []byte) (int, error) {
    return rw.reader.Read(p)
}

func (rw *ReadWriter) Write(p []byte) (int, error) {
    return rw.writer.Write(p)
}

Use it when:

Anonymous Embedding

It can satisfy the ReadWriter’s Embedded Interface, methods from bufio.Reader and bufio.Writer are promoted to ReadWriter, includes their fields and methods.

It’s not inheritance — it’s still composition.

type ReadWriter struct {
    *bufio.Reader // implements Reader
    *bufio.Writer // implements Writer
}

Use it when:

Names Conflict (Outer vs Embedded Type)

If both the outer and embedded type define the same field or method name, the outer one wins.

type A struct {
    Name string
}

type B struct {
    Name string  // same name as in A
    A            // embedding
}

// b.Name refers to B's field, not A's