Cyclic definition of overriding

Dan Smith daniel.smith at oracle.com
Tue Jun 9 20:15:02 UTC 2015


> On Jun 9, 2015, at 9:00 AM, Konstantin <konstantin.barzilovich at oracle.com> wrote:
> 
> I consider this simple case:
> 
> interface Test1  {
>    int foo(); // m1
> }
> 
> interface Test2{
>    int foo(); // m2
> }
> class Test implements Test1, Test2{
> }
> 
> I try to understand if m1 is inherited by Test. I follow jls-8.4.8-200.
> All subassertions are true except jls-8.4.8-200-E. To decide if it is true or not we need to turn to overriding definition jls-8.4.8.1-200.

Specifically:

"There exists no method m' that is a member of the direct superclass or a direct superinterface, D', of C (m distinct from m', D distinct from D'), such that m' from D' overrides the declaration of the method m."

We've bound our variables as follows:
C=Test
D=Test1
m=m1
m'=m2
D'=Test2

The question we are asking: does m2 override m1 from Test2?

> More detailed, I want to be sure that m2 isn't m'. That's why I need to know if m2 overrides m1.
> And new subassertion jls-8.4.8.1-200-D says about inheriting.
> "8.4.8.1 C does not inherit mI."
> So we get a circle.

Note the question above: we want to know if m2 overrides m1 from Test2.  Test2 is an interface, so 8.4.8.1 doesn't apply.  Instead, we want 9.4.1.1.

"An instance method m1, declared in or inherited by an interface I, overrides from I another instance method, m2, declared in interface J, iff both of the following are true:"

The bindings here are tricky, because we happen to have a name clash:
m1=m2
I=Test2
m2=m1
J=Test1

Is m2 "declared in or inherited by" Test2?  Trivially, yes.
Is m1 declared in Test1?  Yes.

Then we encounter the first bullet: is Test2 a subinterface of Test1?  Nope.  We're done.

> On Jun 9, 2015, at 1:34 PM, Alex Buckley <alex.buckley at oracle.com> wrote:
> 
> That said, jls-8.4.8.1-200 says "An instance method mC declared in or inherited by class C, 'overrides from C' another method mI declared in an interface I, iff all of the following are true:" -- so you have to know that foo() is already inherited by class Test (say from Test1) in order to check if Test.foo() overrides Test2.foo(). As you say, we're still trying to figure if foo() is inherited from Test1. This all seems disturbingly tricky for such a simple scenario. Dan, any comments?

The fact that inheritance depends on overriding is due to how default methods work: you don't inherit a default method if it has already been overridden.  But note the "already" -- there's some induction going on here, building up the members of all supertypes before we attempt to decide the members of a subtype.  The rules for subtypes depend only on what we already know about supertypes.

—Dan


More information about the compiler-dev mailing list