Struct Embedding in Logo

Java supports composition of classes to express a more seamless combination of types. While Java doesn’t have direct struct embedding like Go, we can achieve similar functionality using composition and delegation.

import java.util.function.Supplier;

class Base {
    private int num;

    public Base(int num) {
        this.num = num;
    }

    public String describe() {
        return String.format("base with num=%d", num);
    }

    public int getNum() {
        return num;
    }
}

class Container {
    private Base base;
    private String str;

    public Container(int num, String str) {
        this.base = new Base(num);
        this.str = str;
    }

    // Delegating method
    public String describe() {
        return base.describe();
    }

    public int getNum() {
        return base.getNum();
    }

    public String getStr() {
        return str;
    }
}

public class StructComposition {
    public static void main(String[] args) {
        Container co = new Container(1, "some name");

        // We can access the base's fields through getter methods
        System.out.printf("co={num: %d, str: %s}%n", co.getNum(), co.getStr());

        // We can also access the base's methods directly on co
        System.out.println("describe: " + co.describe());

        // In Java, we use interfaces to achieve a similar effect to Go's interface implementation through embedding
        Supplier<String> describer = co::describe;
        System.out.println("describer: " + describer.get());
    }
}

When creating objects in Java, we initialize the composed class explicitly in the constructor.

We can access the base’s fields through getter methods on co, e.g., co.getNum().

Since Container composes Base, we can delegate the methods of Base to become methods of Container. Here we invoke a method that was delegated from Base directly on co.

In Java, we use interfaces to achieve a similar effect to Go’s interface implementation through embedding. Here we see that a Container can be used as a Supplier<String> because it has a describe() method that returns a String.

To run the program:

$ javac StructComposition.java
$ java StructComposition
co={num: 1, str: some name}
describe: base with num=1
describer: base with num=1

This example demonstrates how Java can use composition and delegation to achieve functionality similar to Go’s struct embedding. While the syntax and approach are different, the core concept of combining types to create more complex structures remains the same.