What does reabstraction mean?

Brian Goetz brian.goetz at oracle.com
Wed Dec 28 07:32:15 PST 2011


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