2

Could someone point me out the reason why default interface methods cannot define behavior/implementation for other interface methods implemented by a certain class, please?

interface Transformable {
    int quarter();
    BigDecimal value();
}

interface Quarterly {

    int getQuarter();

    void setQuarter(int quarter);

    // Method that I would expect to be used to define Transformable method behavior
    default int quarter() {
        return getQuarter();
    }
}

// expects quarter() implementation
static class SomethingQuarterly implements Quarterly, Transformable {

    private int quarter;
    private BigDecimal value;

    @Override
    public int getQuarter() {
        return quarter;
    }

    @Override
    public void setQuarter(int quarter) {
        this.quarter = quarter;
    }

    @Override
    public BigDecimal value() {
        return value;
    }
}
0

2 Answers 2

4

The problem is that if Transformable::quarter were to change to a default method, which should be a backwards compatible change from the interface's perspective, it would cause the diamond problem. Which of the two defaults would get chosen?

The compiler doesn't know, of course, and so the safest thing is to make the person writing the implementation resolve the problem even though the problem doesn't exist yet. By making the implementer resolve the ambiguity, Transformable::quarter can change to a default method in the future without breaking SomethingQuarterly.

If the two methods are conceptually related and Quarterly should override Transformable, you should make Quarterly extend that interface.

interface Quarterly extends Transformable {
    //...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Ok @Michael, I think you clarified it when you pointed out the backward compatibility. A possible Transformable::quarter default later implementation would break the 'clients'.
1

To make it work, your Quarterly interface has to inherit from the Transformable interface. Thus, do the following modification:

interface Quarterly extends Transformable {

    int getQuarter();

    void setQuarter(int quarter);

    // Method that I would expect to be used to define Transformable method behavior
    default int quarter() {
        return getQuarter();
    }
}

After this, your SomethingQuarterly class can implement just the Quarterly interface.

1 Comment

As @Michael stated, it is only a solution in case you have a conceptual relation between interfaces. That's not the case. Thanks anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.