package main

import "fmt"

// Speaker adalah kontrak perilaku: satu method set tanpa implementasi.
type Speaker interface {
	Speak() string
}

// Kucing mengimplementasikan Speaker lewat method Speak-nya.
type Kucing struct {
	Nama string
}

func (k Kucing) Speak() string {
	return k.Nama + ": meong"
}

// Robot juga mengimplementasikan Speaker dengan perilaku berbeda.
type Robot struct {
	ID int
}

func (r Robot) Speak() string {
	return fmt.Sprintf("robot-%d: bleep bloop", r.ID)
}

// perkenalkan menerima interface, bukan tipe konkret.
func perkenalkan(s Speaker) {
	fmt.Println(s.Speak())
}

func main() {
	var s Speaker // nilai interface: pasangan (dynamic type, dynamic value)

	s = Kucing{Nama: "Oyen"}
	fmt.Printf("dynamic type: %T\n", s)
	perkenalkan(s)

	s = Robot{ID: 7}
	fmt.Printf("dynamic type: %T\n", s)
	perkenalkan(s)
}
