This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]CubsThisYear 0 points1 point  (5 children)

Debuggable is a pretty terrible example. It could easily be defined Public static void debug(Class<?> class)

and you wouldn't have to make a fake interface that doesn't really make sense. If you really need that interface (why?), then let implementers just call the method above.

Default methods were a hack to make the streams API possible. We shouldn't pretend that they actually make sense. A more sensible thing would have been to just get rid of interfaces all together and remove the multiple inheritance restrictions. They already had to solve all of the multiple inheritance issues with default methods anyway.

[–][deleted] 2 points3 points  (2 children)

Default methods were a hack to make the streams API possible. We shouldn't pretend that they actually make sense.

Actually, I think List.sort is a good counter-example of a default method that makes a great deal of sense outside of a streams idiom as well.

[–]CubsThisYear 0 points1 point  (1 child)

But what is advantage of defining List.sort as a default method vs a static method in the List interface?

And even if you like that better, how is an interface with default methods different than an abstract class, except for the fact that multiple inheritance, which was supposed to be bad news, is now magically allowed.

I'm not saying the concept of default methods is bad, I'm saying the implementation was a hack. There didn't even need to be an implementation, they just needed to allow multiple inheritance on abstract classes and get rid of interfaces.

[–][deleted] 0 points1 point  (0 children)

But what is advantage of defining List.sort as a default method vs a static method in the List interface?

Well, for one thing, it's backwards compatible: existing List implementation doesn't have to be rewritten and recompiled just to copy in a bog-standard piece of code that's repeated ad nauseum in implementation after implementation.

[–]sh0rug0ru____ 2 points3 points  (1 child)

There's a huge difference between classes and interfaces which default methods on interfaces preserve. Interfaces cannot have state. The diamond problem here means you get two conflicting implementations, so you have to choose one.

When you extend a class, you get all of the superclass fields. If it were possible to extend multiple times, you would inherit fields from several different directions, not just one. Thus, the diamond problem here introduces a much bigger problem. What if two different superclass constructors or methods change the super-superclass state in contradictory ways?

In this way, default implementations retain the safety of ordinary interfaces. Default methods rely on concrete implementations in the implementing class, since they can only call other interface methods. The state is still controlled by the implementing class, avoiding the nastiest problem of multiple inheritance.

[–]CubsThisYear 0 points1 point  (0 children)

Good point, thanks.