Struct, методы и интерфейсы в Go vs Java | Types - Language

Серия: Go для Java-разработчиков — разбираем struct, interface, receiver types и type embedding

В этой статье мы разберем, как в Go строится архитектура типов. Для Java-разработчика это особенно важно, так как Go не использует классы в привычном понимании, а типы и методы организованы иначе. Мы сравним подход Go ↔ Java, чтобы понять, как реализуются структуры, методы и интерфейсы.


Struct — базовая структура данных Go

Struct в Go — это аналог класса без методов. Он хранит данные, но поведение добавляется через методы.

Пример struct

// Go
type User struct {
    Name string
}

func main() {
    u := User{Name: "Alice"}
    fmt.Println(u.Name)
}

Java эквивалент:

// Java
class User {
    String name;
}

public class Main {
    public static void main(String[] args) {
        User u = new User();
        u.name = "Alice";
        System.out.println(u.name);
    }
}
Struct — просто контейнер данных. Методы добавляются отдельно. Не нужно наследовать или создавать классы, чтобы хранить поля.

Методы и receiver types

В Go метод привязывается к типу через receiver. Receiver может быть значением или указателем.

Пример метода на значении

// Go
type User struct {
    Name string
}

func (u User) Print() {
    fmt.Println(u.Name)
}

func main() {
    u := User{Name: "Alice"}
    u.Print()
}

Java эквивалент:

// Java
class User {
    String name;

    void print() {
        System.out.println(name);
    }
}

public class Main {
    public static void main(String[] args) {
        User u = new User();
        u.name = "Alice";
        u.print();
    }
}

Receiver type влияет на поведение:

  • Value receiver — метод работает с копией
  • Pointer receiver — метод может менять оригинальные данные

Pointer receiver пример

// Go
func (u *User) Rename(newName string) {
    u.Name = newName
}

func main() {
    u := User{Name: "Alice"}
    u.Rename("Bob")
    fmt.Println(u.Name) // Bob
}
Для Java-разработчика: Pointer receiver похож на передачу объекта по ссылке, Value receiver — как передача примитивов или копий объектов.

Interface — неявная реализация

В Go интерфейсы реализуются автоматически. Если тип имеет методы, соответствующие интерфейсу — он его реализует. Никаких implements не нужно.

Пример интерфейса

// Go
type Printer interface {
    Print()
}

type User struct {
    Name string
}

func (u User) Print() {
    fmt.Println(u.Name)
}

func main() {
    var p Printer = User{Name: "Alice"}
    p.Print()
}

Java эквивалент:

// Java
interface Printer {
    void print();
}

class User implements Printer {
    String name;

    public void print() {
        System.out.println(name);
    }
}

public class Main {
    public static void main(String[] args) {
        Printer p = new User();
        ((User)p).name = "Alice";
        p.print();
    }
}
Go делает систему интерфейсов очень гибкой. Вы можете реализовать интерфейс без явного объявления.

Type embedding — композиция вместо наследования

Go не использует наследование как в Java. Для повторного использования кода применяется embedding.

Пример embedding

// Go
type Person struct {
    Name string
}

func (p Person) PrintName() {
    fmt.Println(p.Name)
}

type Employee struct {
    Person // embedding
    Position string
}

func main() {
    e := Employee{Person: Person{Name: "Alice"}, Position: "Developer"}
    e.PrintName() // можно вызвать напрямую
}

Java эквивалент:

// Java
class Person {
    String name;

    void printName() {
        System.out.println(name);
    }
}

class Employee extends Person {
    String position;
}

public class Main {
    public static void main(String[] args) {
        Employee e = new Employee();
        e.name = "Alice";
        e.position = "Developer";
        e.printName();
    }
}
Embedding ≈ наследование, но это композиция. Методы встроенного типа доступны напрямую, но Employee и Person — разные типы.

Сравнение ключевых понятий Go ↔ Java

Концепция Go Java Комментарий
Класс / структура struct class Struct хранит данные; методы привязываются отдельно
Методы receiver (value / pointer) обычные методы класса Pointer receiver позволяет менять данные
Интерфейс неявно реализуется implements Go более гибкий, нет явного объявления
Наследование type embedding extends Go использует композицию вместо наследования

Практический вывод

Для Java-разработчика, переходящего на Go, важно помнить:

  • Struct = контейнер данных без поведения
  • Методы привязываются через receiver (value/pointer)
  • Интерфейсы реализуются автоматически
  • Embedding заменяет наследование, но это композиция
  • Типовая система Go проста, гибка и безопасна

Эти принципы позволяют строить архитектуру Go, понятную и удобную для крупных проектов, без лишнего усложнения, присущего классам Java.


🌐 in English
Всего лайков:0

Оставить комментарий

Мой канал в социальных сетях
Отправляя email, вы принимаете условия политики конфиденциальности

Полезные статьи:

Внутреннее устройство Garbage Collector: Go ↔ Java
В этой статье мы подробно разберём работу сборщика мусора (Garbage Collector, GC) в Go и Java, рассмотрим ключевые внутренние механизмы: concurrent mark & sweep, mutator vs collector, tricolor mar...
Асинхронность и реактивность в Java: CompletableFuture, Flow и Virtual Threads
В современном Java-разработке есть три основных подхода к асинхронности и параллельности: CompletableFuture — для одиночных асинхронных задач. Flow / Reactive Streams — для потоков данных с контролем...
История начинается не с академической теории, а с типичной production-проблемы. Представьте сервис: 48 CPU 300+ потоков нагрузка 200k операций в секунду много shared state Команда использует обы...

Новые статьи:

Конкурентность — это не про «запустить много потоков». Это про договорённости между ними. Представь кухню ресторана: — повара (потоки / горутины) — заказы (задачи) — и главный вопрос: как они коорди...
История начинается не с академической теории, а с типичной production-проблемы. Представьте сервис: 48 CPU 300+ потоков нагрузка 200k операций в секунду много shared state Команда использует обы...
Когда HashMap начинает убивать продакшн: инженерная история ConcurrentHashMap
Представьте обычный продакшн-сервис. 32 CPU сотни потоков кэш конфигурации / сессий / rate limits десятки тысяч операций в секунду И где-то внутри — обычный Map. Сначала всё выглядит безобидно. Map&...
Fullscreen image