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.
Галерея
Полезные статьи:
Новые статьи: