В Go нет классического наследования как в объектно-ориентированных языках (C++, Java, C#). Вместо этого язык использует композицию и встраивание (embedding) как основные механизмы для повторного использования кода и построения иерархий типов.
type Person struct {
Name string
Age int
}
// Employee "наследует" Person через встраивание
type Employee struct {
Person // Встроенная структура
Company string
Salary float64
}
Особенности:
func (p Person) Greet() string {
return "Hello, " + p.Name
}
// Employee автоматически получает метод Greet
emp := Employee{Person{"Alice", 30}, "Google", 100000}
fmt.Println(emp.Greet()) // Hello, Alice
func (e Employee) Greet() string {
return "Hello, I'm " + e.Name + " from " + e.Company
}
// Теперь вызовется метод Employee, а не Person
fmt.Println(emp.Greet()) // Hello, I'm Alice from Google
Go использует интерфейсы для реализации полиморфизма:
type Speaker interface {
Speak() string
}
func (p Person) Speak() string {
return "I'm a person"
}
func (e Employee) Speak() string {
return "I'm an employee"
}
func Introduce(s Speaker) {
fmt.Println(s.Speak())
}
Характеристика | Классическое наследование | Go (композиция) |
---|---|---|
Связь типов | "is-a" | "has-a" |
Переопределение | Явное | Неявное |
Множественное наследование | Проблематично | Поддерживается через встраивание |
Доступ к полям | Напрямую | Через встроенный тип |
Иерархия | Жесткая | Гибкая |
package main
import "fmt"
type Animal struct {
Name string
}
func (a Animal) MakeSound() string {
return "Generic animal sound"
}
type Dog struct {
Animal // Встраивание
Breed string
}
func (d Dog) MakeSound() string {
return "Woof!"
}
func main() {
dog := Dog{
Animal: Animal{Name: "Rex"},
Breed: "Labrador",
}
fmt.Println(dog.Name) // Rex
fmt.Println(dog.MakeSound()) // Woof!
fmt.Println(dog.Animal.MakeSound()) // Generic animal sound
}