Formal model for defender method resolution

David Holmes David.Holmes at
Tue Feb 1 22:57:10 PST 2011

Neal Gafter said the following on 02/02/11 16:30:
> 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

I have to disagree with you there. The semantics for A.m, B.m and C.m 
are potentially different, so what semantics does D.m provide ? We have 
no idea looking at what has been written. Of course this can happen 
today without defenders, but we assume that an implementor of D can 
somehow make sense of this strange situation. But with defenders in play 
it doesn't make sense to me for this situation to be ignored by the 
compiler because the compiler can see there are two conflicting 
defenders at play here: X.b from B and <none> from C. From D's 
perspective B and C have equal weighting, so it is ambiguous what 
defender D.m should have. Hence the programmer should be forced to 
explicitly resolve that ambiguity in my view. Why do you consider B's 
defender to be more relevant to D than C's?

> 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.

Is this is an example we should strive to emulate? It seems an extreme 
quirk of generics. Is there a realistic use-case for this?

David Holmes

More information about the lambda-dev mailing list