Formal model for defender method resolution

Neal Gafter neal at
Tue Feb 1 22:30:50 PST 2011

On Tue, Feb 1, 2011 at 9:48 PM, Brian Goetz <brian.goetz at> wrote:

>  I see your point: there is a unique, non-overridden concrete
>> implementation here, as in the previous example.
>> In both this and the previous example, any problem arises only in the
>> context of a particular concrete class.  Either the class has a unique
>> overrider for each abstract method it inherits, or it does not (and is
>> rejected).  Why should we should reject interfaces, which can't
>> generally be instantiated in isolation anyway?  I think the primary
>> reason (if there is one) is that there are defaults in the hierarchy
>> that can't be "used" by a class because of ambiguity, so the defaults
>> dont do the clients any good.  I think you're thinking that ought to
>> be an error we want to diagnose when the interface is compiled.  Is
>> that right?
> Right.  If any attempt to inherit from the interface would cause a failure,
> it seems only polite for the compiler to reject that interface.

So far so good.  But none of these examples prevent *any *attempt to inherit
from the interface, they only prevent inheriting from the interface without
overriding the method family in question.  That's no different from any
other interface method today, except for the fact that the intent of these
new defender methods is that they not demand to be implemented directly by
classes that implement them.

For the specific case of

   intf A { String m() default X.a }
   intf B { String m() default X.b }
   intf C extends A { String m() default none }
   intf D extends A, B, C { }

A class that implements D has a single, unique, non-overridden
implementation for the method family (B.m), and it is a suitable
implementation (i.e. the return type works) for the inherited abstract
method.  So there doesn't appear to be any problem with that class, and
therefore there should be no problem with these interfaces

The same situation can occur with classes today:

*class A<T> {
  public T m() { ... }
  public abstract String m();
class D extends A<String> {

In this case the inherited non-abstract m implements the inherited abstract
m.  It seems that we should allow the same thing for interfaces: a
(non-overridden) inherited concrete method should be capable of implementing
an inherited abstract method.

More information about the lambda-dev mailing list