Warm-up

Make the compiler explain the diamond

5 minjunior16 yrs

One concept, guided. Near-impossible to fail.

What this teaches

  • Two unrelated defaults with the same signature are a compile error
  • Interface.super.method() is how you pick one, and you must pick
  • Java has multiple inheritance of behaviour, but never of state

Starter

Starter.javaOpen in playground
import java.util.*;

/**
 * WARM-UP — 5 minutes. One concept. Hard to fail.
 *
 * Two interfaces, both with a default summary(). One class implements both.
 *
 * TASKS
 *   1. Run it as shipped. Receipt implements one interface and works.
 *   2. Add `, Timestamped` to Receipt. Compile. Read the error — it names
 *      the rule precisely.
 *   3. Fix it by overriding summary() and delegating with
 *      Auditable.super.summary(). Then combine both, so the label carries
 *      the audit prefix AND the time.
 *   4. Uncomment ClassWins at the bottom. It compiles with no error and no
 *      warning. Predict its output, then run it.
 *   5. In a comment: step 2 is an error and step 4 is silent. Why the
 *      difference? One of them has a rule and the other has an ambiguity.
 */
public class Starter {

    interface Auditable {
        default String summary() { return "[audit] ORD-1"; }
    }

    interface Timestamped {
        default String summary() { return "at 09:00"; }
    }

    /** TASK 2: add `, Timestamped` here and compile. */
    static final class Receipt implements Auditable {
    }

    static class Document {
        public String summary() { return "from the class"; }
    }

    // TASK 4: uncomment. No error, no warning. What does it print?
    // static final class ClassWins extends Document implements Timestamped {
    // }

    public static void main(String[] args) {
        System.out.println("receipt   : " + new Receipt().summary());

        // System.out.println("classWins : " + new ClassWins().summary());

        // Question to answer in a comment before you move on:
        // Receipt inherits two implementations and Java refuses to choose.
        // ClassWins also inherits two and Java chooses silently. What is the
        // rule, and what compatibility promise does it protect?
    }
}

Run it locally:

cd exercises/java/oop/abstract-class-vs-interface/01-warmup
javac Starter.java -d /tmp/out && java -cp /tmp/out Starter

Done when

  • You read the 'inherits unrelated defaults' error before fixing it
  • The class compiles by delegating explicitly to one or both interfaces
  • A comment says why Java refuses to guess here but not in the class-vs-interface case

← Back to When do you choose an abstract class over an interface?