What does reabstraction mean?

Robert Field Robert.Field at oracle.com
Wed Dec 28 12:21:58 PST 2011


In a previous email on this, Brian stated what I think is an obviously 
correct and important test -- which is if the author of the 
implementation is aware what interfaces she is implementing.  In (2) 
below, the author of the implementation of K knows she is implementing I 
and J.  This is not true of C.m in (1).  I think it is important to 
distinguish implementation/abstract merges from abstract/abstract 
merges.  Because they pass the author awareness test, I see no reason 
for abstract/abstract to ever be a conflict.

Which means implementation/abstract merges are the important issues.  
Cases of this are:

  * class-concrete / interface-abstract
  * interface-default / interface-abstract
  * interface-default / interface-re-abstract
  * class-abstract / interface-default

The first is existing Java -- (1) below.  Which is legal and 
class-concrete wins.

If the "class wins" rule holds, then the last must also be legal with 
abstract winning.

For the remaining two (which in many models would be the same) there is 
a choice between three options:

 1. default wins
 2. abstract wins
 3. conflict

-Robert


On 12/28/11 7:32 AM, Brian Goetz wrote:
> There are several examples in Java today that work like the weak model,
> in addition to the generics example that Neal raised.  Both of the below
> examples give rise to the dreaded "Gun.draw / Shape.draw" problem
> without defenders.
>
> 1. After-the-fact implementation (similar to MarkT's example):
>
> interface I {
>     void m();
> }
>
> class C {
>     void m() { ... }
> }
>
> class D extends C implements I {
>     // C.m() now implements I.m()!
>     // Hope that's OK!
> }
>
> 2. Interface merging:
>
> interface I {
>     void m();
> }
>
> interface J {
>     void m();
> }
>
> interface K extends I, J {
>     // Now I.m() and J.m() are the same method!
>     // Hope that's OK!
> }
>
> I say these are analogues of the weak mechanism because the only place
> where weak/strong differs is what happens when you mix two otherwise
> unrelated types with the same member.
>
>
> On 12/28/2011 5:41 AM, Mark Thornton wrote:
>> On 27/12/11 14:23, Brian Goetz wrote:
>>> There have been some strong opinions stated here about the syntactic
>>> form used to denote reabstraction of a default method.  Let's take look
>>> at a somewhat deeper question: what *should* reabstraction mean in the
>>> context of an interface method?
>>>
>>> Concrete class methods can be reabstracted today:
>>>
>>> class A {
>>>         void m() { ... }
>>> }
>>>
>>> abstract class B extends A {
>>>         abstract void m();
>>> }
>>>
>>> class C extends B {
>>>         void m() { ... }
>>> }
>>>
>>> The motivation is simple: a subclass can impose semantics which it has
>>> reason to believe the superclass implementation cannot provide, so it
>>> wants to veto the existing implementation and force a new one to be
>>> provided.
>>>
>>> The current extension methods design calls for the ability to
>>> "reabstract" a default as well; the motivation is the same.  I'll use
>>> the more explicit "default none" to denote reabstraction here, for
>>> clarity.
>>>
>>> interface I {
>>>         void m() default { ... }
>>> }
>>>
>>> interface J extends I {
>>>         void m() default none;
>>> }
>>>
>>> But, with multiple inheritance, there are at least two realistic choices
>>> for what this means:
>>>
>>>      - Strong: reabstraction means "this class needs an implementation of
>>> m(), which must be provided by one of my subtypes."
>>>
>>>      - Weak: reabstraction means "this class needs an implementation of
>>> m(), but don't use the one(s) provided by my supertype(s)."
>>>
>>> In the single-inheritance case, both of these collapse to being the same
>>> thing, so analogies with existing class reabstraction offer us little
>>> guidance here.  (With multiple inheritance, we also have to resolve how
>>> they should interact with other declarations in the hierarchy that are
>>> not related by subtyping, such as those that arise from "C extends A, B"
>>> structures.)
>>>
>>>
>>> Ignoring the details of how they fit into the language feature as it
>>> currently stands, which of these interpretations seems more compelling,
>>> natural, or powerful for the purposes of building safe and useful libraries?
>>>
>>>
>>>
>> How does this case fit:
>>
>> interface I {
>>       int hashCode();
>>       boolean equals(Object a);
>> }
>>
>> class A implements I {
>>       // must implement equals and hashCode
>> }
>>
>> Mark Thornton
>>
>>



More information about the lambda-dev mailing list