Ответ
В Go нет классического наследования, как в Java или C++. Вместо этого в Go используется принцип «композиция вместо наследования».
Повторное использование кода достигается через встраивание (embedding) структур, а полиморфизм — через интерфейсы.
Пример встраивания (композиции):
import "fmt"
type Animal struct {
Name string
}
func (a *Animal) Speak() {
fmt.Printf("%s издает звукn", a.Name)
}
type Dog struct {
Animal // Встраивание типа Animal. Поля и методы Animal "поднимаются" на уровень Dog.
Breed string
}
func main() {
d := Dog{
Animal: Animal{Name: "Рекс"},
Breed: "Овчарка",
}
d.Speak() // Вызывается метод Speak() из встроенной структуры Animal
fmt.Println(d.Name) // Поле Name также доступно напрямую
}
Ключевые моменты:
Встраивание — не наследование: Это синтаксический сахар для композиции.
Dog
имеетAnimal
, а не являетсяAnimal
. Это позволяет избежать хрупких иерархий наследования.Полиморфизм через интерфейсы: Полиморфизм в Go достигается неявно. Любая структура, реализующая все методы интерфейса, автоматически удовлетворяет этому интерфейсу. Это позволяет писать гибкий и слабосвязанный код.
// интерфейс, описывающий поведение
type Speaker interface {
Speak()
}
// функция принимает любой тип, удовлетворяющий интерфейсу Speaker
func MakeSound(s Speaker) {
s.Speak()
}