Какие принципы ООП реализуются в Go и какими средствами?

Ответ

Хотя Go не является классическим объектно-ориентированным языком (в нём нет классов и наследования в привычном понимании), он поддерживает ключевые принципы ООП через свои уникальные механизмы.

Основной принцип, который реализуется при помощи структур (struct), — это инкапсуляция.

  1. Инкапсуляция — объединение данных (полей) и методов для работы с ними в одном типе. В Go это достигается с помощью структур и методов, привязанных к ним. Управление доступом реализуется через регистр имен: идентификаторы, начинающиеся с заглавной буквы (например, MyField), являются экспортируемыми (публичными), а с маленькой (например, myField) — неэкспортируемыми (приватными) и доступны только в пределах своего пакета.

    package user
    
    type User struct {
        name string // неэкспортируемое (приватное) поле
        Age  int    // экспортируемое (публичное) поле
    }
    
    // Метод-сеттер для доступа к приватному полю
    func (u *User) SetName(name string) {
        u.name = name // Логика валидации может быть здесь
    }
    
    // Метод-геттер
    func (u *User) GetName() string {
        return u.name
    }
  2. Композиция вместо наследования — Go поощряет использование композиции для повторного использования кода. Это достигается через встраивание (embedding) структур. Встроенная структура делегирует свои поля и методы родительской, что похоже на наследование, но является более гибким механизмом.

    type Employee struct {
        User     // Встроенная структура User
        Position string
    }
    
    func main() {
        emp := Employee{Position: "Developer"}
        emp.SetName("Alice") // Доступ к методу встроенной структуры
        emp.Age = 30         // Доступ к полю встроенной структуры
        fmt.Println(emp.GetName()) // "Alice"
    }

Таким образом, Go реализует инкапсуляцию и полиморфизм (через интерфейсы), но вместо наследования использует композицию.