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.


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

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

Практические паттерны и оптимизация в Go vs Java | Concurrency часть 3
← Часть 2 — Синхронизация и безопасность в Go В этой части мы рассмотрим практические паттерны параллельной обработки задач: worker pool, pipeline pattern и схемы сборки результатов. Эти паттерн...
Как удержать легаси-проект от смерти и подарить ему ещё 10 лет
Признаки легаси-проекта: как распознать старый корабль Легаси — это не просто старый код. Это живой организм, который пережил десятки изменений, смену команд, устаревшие технологии и множество временн...
Context, propagation и cancellation patterns в Go vs Java | Паттерны, идиомы и лучшие практики Go
← Связанные статьи: Часть 1 — Error handling и defer в Go (Параллельность и синхронизация) | Паттерны, идиомы и лучшие практики Go 1. Context и его роль В Go context.Context используется для пере...

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

Resource cleanup, rate‑limiting strategies, bounded vs unbounded channels - в Go vs Java | Паттерны, идиомы и лучшие практики Go
Продолжаем серию статей для разработчиков, которые хотят изучить Go на основе знаний Java, и наоборот. В этой статье мы обсудим три ключевые темы: Resource Cleanup (освобождение ресурсов), Rate-Limiti...
Разбираем: Rate‑limiter, non‑blocking operations, scheduler  Go vs Java | Concurrency часть 4
Эта статья посвящена пониманию принципов работы с конкурентностью и синхронизацией в Go и Java. Мы рассмотрим ключевые подходы, такие как rate‑limiter, неблокирующие операции и планирование задач, сра...
Разбираем: Trace, Profiling, Integration Testing, Code Coverage, Mocking, Deadlock Detection в Go vs Java | Testing, Debugging и Profiling
Серия: Go для Java-разработчиков — разбор trace, профилирования и тестирования В этой статье мы разберем инструменты и практики для тестирования, отладки и профилирования в Go. Для Java-разработчика ...
Fullscreen image