Struct, methods and interfaces in Go vs Java | Types - Language
Series: Go for Java Developers — exploring struct, interface, receiver types and type embedding
In this article, we will examine how types architecture is built in Go. For a Java developer, this is especially important, as Go does not use classes in the conventional sense, and types and methods are organized differently. We will compare the Go ↔ Java approach to understand how structures, methods, and interfaces are implemented.
Struct — basic data structure in Go
Struct in Go is an analogue of a class without methods. It stores data, but behavior is added through methods.
Example of struct
// Go
type User struct {
Name string
}
func main() {
u := User{Name: "Alice"}
fmt.Println(u.Name)
}
Java equivalent:
// 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 is just a container for data. Methods are added separately. No need to inherit or create classes to store fields.
Methods and receiver types
In Go a method is bound to a type via receiver. Receiver can be a value or a pointer.
Example of a method with a value
// Go
type User struct {
Name string
}
func (u User) Print() {
fmt.Println(u.Name)
}
func main() {
u := User{Name: "Alice"}
u.Print()
}
Java equivalent:
// 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 affects behavior:
- Value receiver — the method works with a copy
- Pointer receiver — the method can change the original data
Pointer receiver example
// Go
func (u *User) Rename(newName string) {
u.Name = newName
}
func main() {
u := User{Name: "Alice"}
u.Rename("Bob")
fmt.Println(u.Name) // Bob
}
For Java developers: Pointer receiver is similar to passing an object by reference, Value receiver — like passing primitives or copies of objects.
Interface — implicit implementation
In Go, interfaces are implemented automatically. If a type has methods that match the interface — it implements it. No implements is needed.
Example of an interface
// 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 equivalent:
// 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 makes the interface system very flexible. You can implement an interface without explicit declaration.
Type embedding — composition instead of inheritance
Go does not use inheritance like in Java. For code reuse, embedding is used.
Example of 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() // can be called directly
}
Java equivalent:
// 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 ≈ inheritance, but it is composition. Methods of the embedded type are accessible directly, but Employee and Person are different types.
Comparison of Key Concepts Go ↔ Java
| Concept | Go | Java | Comment |
|---|---|---|---|
| Class / struct | struct | class | Struct holds data; methods are bound separately |
| Methods | receiver (value / pointer) | regular class methods | Pointer receiver allows modifying data |
| Interface | implicitly implemented | implements | Go is more flexible, no explicit declaration |
| Inheritance | type embedding | extends | Go uses composition instead of inheritance |
Practical Output
For a Java developer transitioning to Go, it is important to remember:
- Struct = data container without behavior
- Methods are bound through receiver (value/pointer)
- Interfaces are implemented automatically
- Embedding replaces inheritance, but this is composition
- The Go type system is simple, flexible, and safe
These principles allow building Go architecture that is understandable and convenient for large projects, without the unnecessary complexity inherent to Java classes.
Оставить комментарий
Useful Articles:
New Articles: