Fundamentals 6 min read

Java vs Go: Comparing Classes and Structs for State, Behavior, and Inheritance

This article compares Java classes with Go structs, covering how each language handles state and behavior, inheritance versus composition, and visibility rules, while providing concrete code examples to illustrate the practical differences for developers.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Java vs Go: Comparing Classes and Structs for State, Behavior, and Inheritance

State and Behavior Differences

In Java a class encapsulates both fields (state) and methods (behavior) together, whereas a Go struct represents only data; methods are defined separately using a receiver function.

public class Person {
    private String name;
    private int age;

    public void eat(String food) {
        System.out.println("eat " + food);
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}
type Person struct {
    Name string
    Age  int
}

func (p *Person) Eat(food string) {
    fmt.Println("eat", food)
}

Inheritance vs Composition

Java supports class inheritance, allowing a subclass to inherit fields and methods from a parent class. Go does not have class‑based inheritance; instead it encourages composition by embedding one struct inside another.

public class Student extends Person {
    public static void main(String[] args) {
        Student s = new Student();
        s.setName("Tom");
        s.setAge(20);
        System.out.println(s.getName() + ":" + s.getAge());
        s.eat("breakfast");
    }
}
type Student struct {
    *Person // anonymous field for composition
}

func main() {
    s := Student{&Person{Name: "Tom", Age: 20}}
    fmt.Println(s.Name, s.Age)
    s.Eat("breakfast")
}

Visibility and Access Control

Java uses explicit access modifiers ( public, private, protected) to control visibility of fields and methods. Go determines visibility solely by the case of the identifier: an uppercase first letter makes it exported (public) outside the package, while a lowercase name keeps it package‑private.

// Java examples
public void eat(String food) { ... }
private void eat(String food) { ... }
protected void eat(String food) { ... }
void eat(String food) { ... } // default (package‑private)
// Go examples
func (p *Person) Eat(food string) { ... }   // exported method
func (p *Person) eat(food string) { ... }   // unexported, package‑private

Key Differences Summary

Go abandons Java's class‑based inheritance, overload, and implementation concepts, favoring composition for code reuse. Methods in Go are distinct from functions: a method has a receiver, while a plain function does not. Go also introduces explicit pointers (using *) and requires passing a pointer to a struct when mutating its state, unlike Java where objects are always accessed via references.

Both languages pass values for primitive types, but Java passes object references by value, whereas Go requires explicit pointer handling to achieve similar behavior.

JavaGoOOPvisibilitystructClassInheritance
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.