Java 8 Default Methods and Multiple Inheritance

As most of you are probably aware ‘default interface methods’ was one of the new features introduced in Java 8. The stated purpose of such a feature seems to be to allow extending existing interfaces without breaking backward compatibility.

However since its now part of the core language I’ve been thinking that such a feature could potentially be pretty useful for other use cases such as implementing a clean and lightweight entity component systems (such as those described by Adam Martin).

You could for example have code like the following:

public class Ship implements Logic, Render, Collision {
...
}

You would just implement the interfaces/components each class/entity would need. You then only need to override a few default methods as needed and the bulk of code can be contained in the interfaces/components. Using Java’s ‘instanceof’ you can easily tell which class implements which types of interfaces/components.

As far as I can tell, this type of usage would potentially allows faster, smaller, cleaner and more flexible code for these types of use cases. However many articles recommend against such usage and consider it an abuse of the feature.

Not really found any detailed discussion on the topic, so wanted to get some opinions on such usage or if others have been using default methods in a similar way?

This seems a bit fishy to me, because it seems to violate the principle of favoring composition over inheritance.

Specifically, why can’t Logic, Render, and Collision be members of your Ship class? What benefit do you get by inheriting from them instead?

An interface still can have no kind of member state, so using them as traits is not as straight forward as you might think.

Adding something to an interface, whether its a normal or a default method, is a design choice. A choice you’ll have trouble taking back later. In that sense, I agree with the view that default methods is a workaround for safely extending legacy APIs and that’s how I intend to use them.

For new systems, for fresh design choices, I have moved away from Java to other JVM languages that support more powerful features. Kotlin and Xtend for example support extension methods, which have the same benefits as default methods, but without polluting the interface. They have their own scope and their own visibility level. You can even define them locally inside another method. So, if you’re thinking about designing a system around default methods, what you really want is extension methods. C# had them for a long time, but we can now have them on the JVM. Kotlin also has extension properties, which are fantastic for writing cleaner code. My favourite example would be:

public val Int.b: Byte get() = (this and 0xFF).toByte()

which is great for graphics when dealing with unsigned bytes, e.g. you can write [icode]byteBuffer.put(255.b);[/icode]. Will become even more useful when we get value types in the JVM.

Eh, you could specify getter functions in the interface and use them in place of state variables. I still don’t think it’s a great approach, but not because it’s overly complicated.

This also makes me wonder what happens if two interfaces define the same default function…?

You’ll get a compilation error and are required to implement the method. You can then explicitely delegate to the default implementation you want to use.

Edit: Sometimes I think I am invisible… :persecutioncomplex:
VVV

The implementation of the two interfaces has to have it’s own implementation of that method. You can still delegate the call to one of the interfaces by A.super.foo() or B.super.foo() or whatever, I guess you get the idea :wink:

[quote=“Spasi,post:4,topic:50995”]
Extension methods allow

oi.func(param);

Where in classic Java you would have had to do:

func(oi, param);

The only benefit is arguably IDE code completion. IMO, this value doesn’t justify a new feature. default implementations are arguably better because implementations can override behavior

I prefer Haskell’s approach where there are no instance methods/functions. You write functions that take parameters, but there is no special “this” parameter. Haskell’s analog to interfaces is called “type classes” and they support default function implementations that can be overridden.

[quote=“gene9,post:8,topic:50995”]
You can “override” extension methods in subclasses. Assuming both of these are available in the current scope:

fun <T: CharSequence> T.foo() { ... }
fun String.foo() { ... }

doing a [icode]“text”.foo()[/icode] invokes the second implementation, the extension method on the most specific type.

Point taken. Each approach seems like it could substitute for the other. Neither seem absolutely necessary.

Extension methods have more confusion potential (where did that method come from), but no worse than Scala’s implicits.

Came across this article, which describes a possible implementation for Mixins and how to workaround this limitation.

Interfaces can’t have variables. So what? They can have getter/setter methods which are almost the same thing. That is basically like Scala traits.

Well you can be evil and give them state with a little concurrent data structures.

BTW: Method handles…many interesting things here. More than default methods IMHO.

yea, i’m looking forward to it too. hope it’s not just “sugar”.

Method handles? No it’s link time dispatch code generation. Simple thing is define a functional interface with the method signature and make a handle…call…win.

yeah, scala allows you to extend one class, but as many traits(better interfaces) as you need, normally. being able to be a child of multiple classes that can have state…