Главное отличие — неявная (implicit) реализация. В Go не нужно объявлять что тип реализует интерфейс:
// Определяем интерфейс
type Stringer interface {
String() string
}
// Тип реализует его автоматически, если имеет метод String()
type User struct { Name string }
func (u User) String() string { return u.Name }
// User is a Stringer — без implements!
В Java/C#: class User implements Stringer — явная привязка.
Преимущества подхода Go:
- Интерфейс можно определить в пакете-потребителе (dependency inversion)
- Ретроактивная реализация — сторонний тип может удовлетворять вашему интерфейсу
- Маленькие интерфейсы (1-2 метода) — стандартная практика: io.Reader, io.Writer, fmt.Stringer