Struct Embedding in Miranda

import java.util.function.Supplier;

class Base {
    int num;

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

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

// A Container class 'composes' a Base. In Java, we use composition instead of embedding.
class Container {
    private Base base;
    String str;

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

    // Delegate method to access base's num
    public int getNum() {
        return base.num;
    }

    // Delegate method to access base's describe
    public String describe() {
        return base.describe();
    }
}

// Interface for objects that can be described
interface Describer {
    String describe();
}

public class StructComposition {
    public static void main(String[] args) {
        // When creating objects, we need to initialize the composed object explicitly
        Container co = new Container(new Base(1), "some name");

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

        // We can also access the base object directly if needed
        System.out.println("also num: " + co.getNum());

        // We can invoke the delegated method from Base
        System.out.println("describe: " + co.describe());

        // In Java, we can use the Container as a Describer because it implements the describe method
        Describer d = co::describe;
        System.out.println("describer: " + d.describe());
    }
}

Java doesn’t have a direct equivalent to Go’s struct embedding. Instead, we use composition and delegate methods to achieve similar functionality. Here’s how the concepts translate:

  1. The Base class is similar to the base struct in Go.

  2. Instead of embedding, the Container class contains a Base object as a private field.

  3. We create delegate methods in Container to access Base’s fields and methods. This allows us to use Container objects similarly to how we used the embedded structs in Go.

  4. The Describer interface is similar to the Go example, but in Java, we don’t need to explicitly declare that Container implements it. As long as Container has a describe() method, it can be used as a Describer.

  5. In the main method, we create and use Container objects similarly to the Go example, but we need to use the delegate methods to access Base’s properties.

  6. Java’s method references (::) are used to create a Describer from a Container object, which is similar to how Go’s interface implementation works.

This Java code demonstrates composition and interface implementation, which are the closest equivalents to Go’s struct embedding in object-oriented programming.

To run this program:

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

This example shows how Java can achieve similar functionality to Go’s struct embedding through composition and delegation, while maintaining its own object-oriented paradigms.