# What a type can do, against what two types share

The logger has two destination contracts, each one method: `Appender.write(String)` and
`Formatter.format(LogRecord)`. Say you want a running line count on both the console
destination and the in-memory one. The move you already know is a base class holding the
counter, so make `Appender` an abstract class with a `written` field. Two subclasses, one
field, nothing duplicated.

Two things break. `Demo.java` registers its destinations as lambdas, and a lambda needs an
interface:

```
error: incompatible types: Appender is not a functional interface
        Appender console = line -> System.out.println(line);
```

Then the JSON destination arrives, supplying both its own sink and its own format, so it has
to be an `Appender` and a `Formatter` at once:

```
error: '{' expected
final class JsonDestination extends CountingAppender, Formatter {
                                                    ^
```

The caret is on the comma. There is one `extends`, and the counter spent it. No virtual bases,
no virtual inheritance, no base-constructor ordering along two paths — the grammar refused
before any of that could come up.

So the contracts are interfaces, and the counter lives in one abstract class that implements
one of them. `JsonDestination implements Appender, Formatter`, every lambda compiles, and
`CountingAppender` exists only because it owns a field.

The version you can run in ten seconds: name what the two implementations share. A field
means an abstract class. Code with no field means a `default` method or a static helper.
Nothing at all still means an interface, because the contract is all that is left to write.
The corpus has 87 interfaces and 6 abstract classes, five of the six being exception bases.
