On multiple inheritence in Java, I'd like to add some thoughts to my post of the other week.
Firstly, I no longer like the old syntax for method definitions. This looks much sexier to me now:
public class A { public void foo() {} } public class B { public void foo() {} } // variation one: 'extends' where 'throws' goes public class AB extends A, B { public void foo() extends A { return A.super.foo(); } public void foo() extends B { return B.super.foo(); } } // variation two: almost explicit public class AB2 extends A, B { public void foo() extends A { return super.foo(); } public void foo() extends B { return super.foo(); } } // variation three: implied public class AB3 extends A, B { public void foo() { // Overrides both A.foo() and B.foo() return super.foo(); // ..* } } // variation four: misc. public class AB4 extends A, B { public void blah(int n) { A.super.foo(); B.super.foo(); } }
This way AB3
can define a single behaviour for any call, irrespective of polymorphism.. although off-hand I can't think of a reason why you'd want to do so.
* note: I'm not sure what the behaviour of AB3.foo()
will be. It could either:
A.super.foo()
as the first parent in the extends
list, orsuper
method that best matches the reference's apparent type; for example: B myB = new AB3(); myB.foo();
would call B.super.foo()
because myAB
is being treated as a B
.The second point would have to have a fallback behaviour in this situation: AB3 myAB3 = new AB3(); myAB3.foo();
because neither parent class matches the apparent type better. And we're still left with the common interface problem.
One other thing about the new syntax I'm not entirely sure of is whether these:
// variation three from the original post: public class AB5 extends A, B { public void foo() { // only extends A, as B is explicitly // extended below.. return super.foo(); } public void foo() extends B { return super.foo(); } } // .. and by extension: public class AB6 extends A, B { public void foo() { // only extends B, as A is explicitly // extended below.. return super.foo(); } public void foo() extends A { return super.foo(); } } // my least sure variation: public class AB7 extends A, B { public void foo() { // extends the first parent (A) return super.foo(); } public void foo() { // extends the second parent (B) return super.foo(); } }
..should be valid, warnings, or errors. Intuitively, I think AB5
should be fine, AB6
should be a warning that "the default overriding method does not override the default superclass" or something, and AB7
should be a "method already defined" error (maybe one that can be turned into a warning via javac
parameters.)
That reminds me, there's a third thing Java should have:
3. A javac
parameter for turning the "unreachable code" error into a warning. God I hate that stupid error! Why is: return;foo();
bad, but: if(true)return;foo();
good?! WTF!?!
When the parameter is flagged, the compiler should just drop unreachable statements. It's still valid, damnit!
See Also: Things Java Should Have
... Matty /<