• Post Reply Bookmark Topic Watch Topic
  • New Topic

Don't you guys feel that default and static methods in interfaces are hurting the basic OO concepts

 
Rafael Sampaio
Greenhorn
Posts: 7
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi you guys,
I believe, as I have also read, that the default and static methods in interfaces were created basically to overcome the problems of migrating code from older versions Java versions to new ones and adding features to largely used Interfaces like java.util.Collection, but I also have a very strong feeling that this transgresses the basic concepts of interfaces in OOD and also kind of eliminates the use of abstract classes.

Do you think that transgression is really worth in detriment of the new features?
Personally I preferred the solution given by MS on C# (extension methods) to this problems as it doesn't hurt the OO principles and also gives the old classes new features.

Please let me know what you guys think about it, and congratulations on the book. I really hope it becomes a great hit on java world.

Kindly,
Rafael G. Sampaio



PS.: I'd be really happy to be one of the fortunate winners of an autographed copy of the book.
 
Michael Swierczek
Ranch Hand
Posts: 125
1
Clojure Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't see this as a transgression, I think methods in abstract classes are a source of needless complexity.

Say for example that you have parent class ClassA and child classes ClassB, ClassC, and ClassD. You also have three sets of functionality that you need ClassB, ClassC, and ClassD to implement, say InterfaceA, InterfaceB, InterfaceC.

Option 1: Declare ClassA to implement InterfaceA, InterfaceB, InterfaceC. Copy-paste implementations of the interfaces into all three classes. Very bad.

Option 2: Declare ClassA to implement InterfaceA, InterfaceB, InterfaceC. Put the normal implementations of the interfaces into ClassA. Better than Option1, but ClassA can potentially grow huge and the interfaces can be only peripherally related to the primary role of ClassA, so you're tying together things that are better to keep separate.

Option 3: Use the Strategy Design Pattern and declare that ClassA has non-abstract getter and setter methods for InterfaceA, InterfaceB, and InterfaceC objects. Now you have to make sure your ClassB, ClassC, and ClassD object instances have their respective setInterfaceA, setInterfaceB, and setInterfaceC methods called properly before you do any real work with them, and that carries its own set of headaches (lots of manual code, or the use of some dependency injection tool). But aside from the six methods added for preparing interface objects, the remaining methods and instance variables in ClassA relate directly to its primary role. This keeps the code in ClassA smaller.

The payoff of Option 3 comes when you're reading the code (no colossal ClassA object source code to read, and it is far easier to keep track of which methods belong to which interface) and when you need some class that does not inherit from A to implement one of the interfaces.

In my own experience, when dealing with input and output I often encounter interfaces with multiple implementations. But otherwise, 90% of the time an interface in the code has one implementation so keeping the implementation separate just adds headaches.

Ruby 'traits' and Scala 'mixins' already work almost exactly like interfaces with default implementations.

.... despite this long comment, I still have a lot to learn about writing good software. It's still possible you're correct and I'm wrong for reasons I am missing. Please don't take any of this as coming from a 'guru'.
 
Claude Moore
Ranch Hand
Posts: 832
7
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Rafael,

welcome to the Ranch (I see that's your first post).

In my humble opinion, I think that such modifications to Java language may both be categorized as "sintax sugar", needed to remove unnecessary complexity in some cases, and as necessary modification
to the language to support more expression powerness.

These are my two cents, anyway.

 
Rafael Sampaio
Greenhorn
Posts: 7
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Michael,
Thanks for your comment, and I'm also far from becoming a coding guru.
I stated that I see it as a transgression, because, as I've learned, an Interface is merely a contract between the interface provider and its implementors, a declaration of terms, not how the terms will be fulfilled by the parts. An interface can also be considered a stereotype (like Serializable). If you give some implementation to this interface it's no longer a disclaimer, its something all might (not must 'cause you can override) obey.

In your examples, if I understood them clearly, that's where the beauty of abstract classes comes into place... the abstract class does not necessarily have to implement all the interface methods. In fact it doesn't have to implement any at all. Therefore any concrete implementations in the hierarchy can provide the right implementation for those interfaces, not the base class. The abstract should have a base implementation to whatever is common to its descendants, and can also give default implementations to interface methods.

Lets try this:



This example above is how I usually do things. If the default implementation lies in the Interface, I would no longer need the abstract class, but the concept of interfaces being a contract or a stereotype is, therefore lost.

What I believe they did in JAVA8 was disrupting those concepts to ease the burden of adjusting the implementing classes of existing interfaces, to aggregate new functionality.

Very nicely put your option to use the Strategy Pattern, by the way.

Kindly,

Rafael Sampaio
 
Rafael Sampaio
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Claude,
Thanks, and I really feel welcome.

Sintax sugar... well this, IMHO, is far from being a sintax sugar... Lambda are more sintax sugar than this change in the Interface concept.

Definitely the language needed more power to ease the burdens imposed to developers, but I don't think that some concept's should have been overridden (lol) in order to provide those.

Kindly,
Rafael Sampaio

 
Stephan van Hulst
Bartender
Posts: 6583
84
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Personally, I think static methods in interfaces are GREAT and a long overdue feature. Static methods, by their nature, have nothing to do with OO, and therefore it shouldn't matter if you put them in a class or an interface. I find myself wanting to put them in interfaces more often than in classes, because interfaces provide a logical namespace for them to be in.

Example, instead of bundling useful methods that sort lists in a utility class called Collections, they could have been put in the List interface. This is a much more logical place to put them. If I want to sort a list, I'm not going to look for a class called Collections to do it.

Since static methods are also not inherited, they don't break backward compatibility if you add them to an existing interface.

Default methods however I'm wary of. I don't like them. Maybe my mistrust is misplaced, but I'm just going to sit and wait until the first problems surface.
 
Rafael Sampaio
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Stephan, thanks for your comment.

I humbly disagree with you, because static methods, are class methods and are implementation specific. Just to reuse your example... sorting a list, depends on its implementation, sorting an array is way different from sorting a binary tree, therefore how you do must be different.
The Lists, in my opinion, should be Sortable, therefore they should have that stereotype(extend a Sortable interface, with a sort method), and each raw structured type has a different and optimized way of doing it.

The utility class Collections, I think, is a generalized way of choosing the best sorting algorithm for a Iterable type independently of its contents, and a good solution because it avoids duplicate implementations of same sorting algorithms for each type of data.

Of course this is just an example of many others that may arise whether or not interfaces should have a static methods.

I see static methods as a cohesion matter addressed to stateless operations(no instance dependency applies). A "ClassUtility" class, for cohesion matters does operations on "Class" only and operations that doesn't depend on any state of an "Class" instance.

Kindly,

Rafael Sampaio
 
Claude Moore
Ranch Hand
Posts: 832
7
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Michael Swierczek wrote:
90% of the time an interface in the code has one implementation so keeping the implementation separate just adds headaches.


That's a practical rule of thumb I agree with... even if I "feel" that a neat separation between interfaces and their concrete implementation represents more a benefit that an unuseful overhead.
Adding default (static) methods seems to me a way to make interfaces a kind of superclasses, were default and basic functionality are given at no additional implementation cost. Sounds good, anyway.


Rafael Sampaio wrote:
... Lambda are more sintax sugar than this change in the Interface concept.


Forgive me Rafael if I disagree with you.. I think IMHO that lambdas are the *real* innovation of Java 8.

Of course, with previous version one was able to make the same things using anonymous classes: I think that there aren't things you can make only thanks to lambda exprs support...but lambda
exprs seems more than a smart replacement for anonymous classes: i think that they're very similar to function pointers. IMHO they may be a first step towards treating *functions*like first citizen
objects.



 
Rafael Sampaio
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Claude,
As I stated before, "Lambdas are more like syntax sugar", though, I do agree they are the major change in the language.
I, may be misunderstanding it, but I have that concept of syntax sugar... If you change a language(syntactically speaking) to do something with fewer lines of code, and its only pourpose is that, it is a syntax sugar (leaving aside, of course, the refactorings).

Kindly,
Rafael Sampaio
 
Stephan van Hulst
Bartender
Posts: 6583
84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rafael, Lists are not Sortable, because their elements may not have a natural order. That's why Collections has methods public static void <T extends Comparable<? super T>> sort(List<T> list) and public static void <T> sort(List<T> list, Comparator<? super T> c) which require either a list of elements that define a natural order, or a custom order. I agree however, that the latter of the two methods could have been an instance method on List, that just takes a Comparator argument.

The methods in Collections are not generalized for different Iterable types. The methods I mentioned before work specifically for Lists. Incidentally, Arrays has the same methods that work on arrays. So for me, the List interface would be a very nice spot to put the two aforementioned methods.

I would argue that static methods that primarily operate on an interface Foo should be declared in Foo, not in FooUtilities or Foos. The way they are implemented can be separate from the exact implementation class of Foo, just as how lists can be sorted regardless of whether they are LinkedLists or ArrayLists (because the sort() method just copies their contents to an array first and sorts that).

Like yours, all of this is just my humble opinion though
 
Rob Spoor
Sheriff
Posts: 20819
68
Chrome Eclipse IDE Java Windows
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I agree however, that the latter of the two methods could have been an instance method on List, that just takes a Comparator argument.

You mean List.sort(Comparator)?
 
Claude Moore
Ranch Hand
Posts: 832
7
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rafael Sampaio wrote:Hi Claude,
I, may be misunderstanding it, but I have that concept of syntax sugar... If you change a language(syntactically speaking) to do something with fewer lines of code, and its only pourpose is that, it is a syntax sugar (leaving aside, of course, the refactorings).


Your "definition" is legitimate, of course...... Just for sake of discussion... let's suppose that in JDK 1x we will able to write properties like those present in C# classes:



Would you considerate it syntax sugar or a new feature ?
 
Jaikiran Pai
Sheriff
Posts: 10447
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude Moore wrote: If you change a language(syntactically speaking) to do something with fewer lines of code, and its only pourpose is that, it is a syntax sugar (leaving aside, of course, the refactorings).


Your "definition" is legitimate, of course...... Just for sake of discussion... let's suppose that in JDK 1x we will able to write properties like those present in C# classes:



Would you considerate it syntax sugar or a new feature ?


I don't have knowledge of C#. Is that above program equivalent to having a public getter and setter method in Java? If that's the case, I think I would consider it syntactic sugar too since I don't see it adding any real value than saving a few keystrokes (which anyway are saved these days, given the IDEs already can generate stuff like this).
 
Campbell Ritchie
Marshal
Posts: 52549
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jaikiran Pai wrote: . . . Is that above program equivalent to having a public getter and setter method in Java? . . . IDEs already can generate stuff like this).
Yes.

When I tried some C# a few years ago, Visual Studio (VS) would add properties like that. They came in read‑only, write‑only and read‑and‑write versions. We were told to let VS do all the work, although it was quicker to write the entire property by hand.
 
Martin Vajsar
Sheriff
Posts: 3752
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rafael Sampaio wrote:I believe, as I have also read, that the default and static methods in interfaces were created basically to overcome the problems of migrating code from older versions Java versions to new ones and adding features to largely used Interfaces like java.util.Collection, but I also have a very strong feeling that this transgresses the basic concepts of interfaces in OOD and also kind of eliminates the use of abstract classes.

Default methods solve the problem with backward compatibility of any interface. While it certainly facilitates upgrades of existing interfaces in Java 8, it is also great help to anyone who's maintaining public libraries. (Prior to default methods, as soon as you've published an interface, you couldn't change the interface in any way without breaking the existing implementations. That's quite bothersome and, in my opinion, held back some important innovations.)

As for breaking the OOD principle - even for default methods, you need to look at the contract, not the implementation. Default method can be overridden by a child, so there are obviously no guarantees that it will work the same in all implementations. People might be tempted to look at and rely on the behavior of the default method, but that's not a new concern - there are lots of people relying on implementation specific details of many existing classes even prior to Java 8.

It's true that interfaces with default methods could be probably abused in many different ways (they might be used to emulate multiple inheritance known from other languages, for example). However, I don't think they force you to violate OO principles. There are already infinitely many ways of getting the OO design wrong, I don't think the default interface methods increase these possibilities significantly.

Abstract classes will continue to thrive, in my opinion. They provide much more than just default implementations, such as class variables and private or final methods. However, an abstract class that has a bunch of abstract methods and only a handful of short, non-final method implementations might be better off becoming an interface in Java 8.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:When I tried some C# a few years ago, Visual Studio (VS) would add properties like that. They came in read‑only, write‑only and read‑and‑write versions. We were told to let VS do all the work, although it was quicker to write the entire property by hand.


It's even quicker nowadays, if all you want is a simple property like that with no additional logic. You can use an automatic property (which is just syntactic sugar). As of C#3 you'd write:

(and yes, I'd still let VS do half the work ).
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Martin Vajsar wrote:It's true that interfaces with default methods could be probably abused in many different ways (they might be used to emulate multiple inheritance known from other languages, for example).


I really should investigate this myself...but are default methods implemented in a way that gets round the "diamond problem"? I'd assume they are. What happens if you implement two interfaces that both have a default implementation for a method of the same signature?
 
Stephan van Hulst
Bartender
Posts: 6583
84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:You mean List.sort(Comparator)?


 
Martin Vajsar
Sheriff
Posts: 3752
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matthew Brown wrote:What happens if you implement two interfaces that both have a default implementation for a method of the same signature?

Turns out they did it right:

Java Deep wrote:The things start to get complicated when a concrete class implements more than one (say two) interfaces and the interfaces implement the same default method. Which default method will the class inherit? The answer is none. In such a case the class has to implement the method itself (directly or by inheritance from a higher class).

This is also true when only one of the interfaces implement the default method and the other one only declares it as abstract. Java 8 tries to be disciplined and avoid “implicit” things. If the methods are declared in more than one interfaces then no default implementation is inherited, you get a compile time error.


Source.

Edit: I was too quick in my judgement. The rest of the article reveals it is a mess anyway.
 
Rafael Sampaio
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude Moore wrote:
If you change a language(syntactically speaking) to do something with fewer lines of code, and its only pourpose is that, it is a syntax sugar (leaving aside, of course, the refactorings).


Your "definition" is legitimate, of course...... Just for sake of discussion... let's suppose that in JDK 1x we will able to write properties like those present in C# classes:

view plainprint?
Note: Text content in the code blocks is automatically word-wrapped
class Alfa {
private int _age = 0;

public int Age
{
get{ return _age; }
set{ _age = value; }
}


}


Would you considerate it syntax sugar or a new feature ?


Hello, there Claude, sorry for a late answer....

If this is the language default way for implementing getters and setters then the answer is no, as there's no other formal ways to do that.

If this is another simplified way of doing the same thing with more lines of code then... Yes, I do consider this a syntax sugar, because you don't have to write the full code for accessing the properties.

If this new syntax could also be used as it can in C#, it will compile into formal methods, and its calls. so an use like this:

whould turn into something like that:


Our colleage Mathew Brown showed a C# example of sugar
Matthew Brown wrote:
It's even quicker nowadays, if all you want is a simple property like that with no additional logic. You can use an automatic property (which is just syntactic sugar). As of C#3 you'd write:
view plainprint?
Note: Text content in the code blocks is automatically word-wrapped
class Alfa {
public int Age { get; set; }
}

(and yes, I'd still let VS do half the work ).


No need to write the method body as its only purpose is to directly access the property.

Just another comment... Note how that it is not hurting the open-close principle of OO, as the property is still hidden behind accessing methods.

kindly,

Rafael Sampaio
 
Jaikiran Pai
Sheriff
Posts: 10447
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Martin Vajsar wrote:

Edit: I was too quick in my judgement. The rest of the article reveals it is a mess anyway.

Last time I read about this from a Java 8 book, there's a specific semantic the compiler follows for such cases, something along the lines of "nearest first". I just cant remember the details now. One of these days I have to start writing some Java 8 code
 
Claude Moore
Ranch Hand
Posts: 832
7
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rafael Sampaio wrote:
.....


Hi Rafael,

in a nutshell, you'd define syntax sugar all modifications apported to a language useful to make same things with fewer lines of code. That may be a convincing argumentation: what it's not
a syntax sugar is something that modifies semantically the programming language.

I wonder if such a definition would not be too restrictive: the only example I can find in Java is, for example, introduction of annotations (there were no another way to add metadata
to a class, a method and so on).
Can you help me to find another example ?

Sorry if I bother you - and other readers of this topic - but this dissection of what may be or not considerated a mere syntactical sugar it's intriguing....





 
Rafael Sampaio
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude Moore wrote:...


Hello again, Claude...
Sorry again for the delay. (I need to stop apologizing and start answering this things promptly... lol )

You might be right about my definition of syntax sugar being too restrictive.

I've read that there are some folks that think that the introduction of Generics was a syntax sugar... I can't totally disagree with them, as I believe the lambdas are somehow a form or syntax sugar, because based on my concept(maybe a wrong one) it did ease things for us... like no more casting when accessing Collection objects. That said, the part that was not the only thing it brought to the language, it also brought a stronger typed language, where you really declare what are your intentions with whatever you are going o use instead of using Objects.

Lambdas, IMHO, are like the Generics, they are some sort of syntax sugar but not simply that as it introduces Functional Types, to the language.

I do have to agree with you... that it's quite rough to enumerate things that were added to the Language that cannot be considered syntax sugar at all.

Annotations, yes, new stuff.

Maybe NIO/NIO.2 can be considered new stuff as it is new API, for doing almost the same things as IO, but entirely redone from scratch, I believe.

Thanks again for your valuable opinion.

Kindly,

Rafael Sampaio


 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Generics are not syntactic sugar. They give compile-time type checking which was not available before. I would agree that lambda's could be considered syntactic sugar because they don't provide anything that was not available before through other methods. Functional Interfaces were available before, they just weren't given the name because there was no language construct that depended on an Interface with a single method.

However I think lambda's might change the way that people program. They remove a small barrier to functional-coding (the verbosity of instantiating anonymous methods), and the Streams API in collections provides a glimpse of what is possible with that sort of functional style. I guess it all depends on how many developers embrace that style.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!