package main

import "fmt"

type A struct {
	My VirtA

	a int
}

func (me *A) f() int {
	// return me.m()+1000
	return me.My.m() + 1000
}

func (me *A) m() int {
	return me.a * me.a
}

type B struct {
	A
	b int
}

func (me *B) g() int {
	return me.My.m() + 2000
}

func (me *B) m() int {
	return me.a * me.a * me.a
}

type VirtA interface {
	f() int
	m() int
}

type VirtB interface {
	f() int
	g() int
	m() int
}

func main() {
	aa := &A{nil, 2}
	aa.My = aa

	bb := &B{A{nil, 2}, 3}
	bb.My = bb

	fmt.Printf("hello, world\n")
	fmt.Printf("aa.f %d\n", aa.f())
	fmt.Printf("aa.m %d\n", aa.m())

	fmt.Printf("bb.f %d\n", bb.f())
	fmt.Printf("bb.m %d\n", bb.m())

}
