package main

import "fmt"

// PemberiSalam hanya mendefinisikan kontrak, bukan implementasi.
type PemberiSalam interface {
	Salam() string
}

// Pelanggan dan Kurir tidak menyebut PemberiSalam pada deklarasinya.
type Pelanggan struct {
	Nama string
}

func (p Pelanggan) Salam() string {
	return "Halo, " + p.Nama + "!"
}

type Kurir struct {
	Kode string
}

func (k Kurir) Salam() string {
	return "Paket milik kurir " + k.Kode + " siap diambil."
}

// Cek kompilasi: kedua tipe wajib memenuhi PemberiSalam, jika tidak build gagal.
var _ PemberiSalam = Pelanggan{}
var _ PemberiSalam = Kurir{}

// sapaSemua bekerja untuk semua tipe yang punya method Salam.
func sapaSemua(daftar []PemberiSalam) {
	for _, s := range daftar {
		fmt.Println(s.Salam())
	}
}

func main() {
	daftar := []PemberiSalam{
		Pelanggan{Nama: "Budi"},
		Kurir{Kode: "K-07"},
	}
	sapaSemua(daftar)
}
