Formal model for defender method resolution
David Holmes
David.Holmes at oracle.com
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