Java 8 introduced default and static methods on interfaces. So now you can have concrete implementations in your interface whether using default or static methods.
The reason Java claimed to add these two new kind of methods is "ensure binary compatibility with code written for older versions of those interfaces".
My question:
Why to distort the interface original concept that suppose to be
fully abstract in order to support existing architectural problems?
What is the difference between using an abstract class and the new version of the interface other than the ability of a class to extend multiple interfaces?
The reason java claimed to add these 2 new kind of methods is "ensure binary compatibility with code written for older versions of those interfaces".
This applies only to default methods (not static methods) and omits some context. From Goetz, State of the Lambda:
The purpose of default methods ... is to enable interfaces to be evolved in a compatible manner after their initial publication.
The main goal is to allow interface evolution, that is, the addition of new methods. If a new method is added to an interface, existing classes that implement the interface would be missing an implementation, which would be incompatible. To be compatible, an implementation has to come from somewhere, so it is provided by default methods.
Why to distort the interface original concept that suppose to be fully abstract in order to support existing architectural problems?
The main intent of a Java interface is to specify a contract that any class can implement without having to alter its position in the class hierarchy. It's true that, prior to Java 8, interfaces were purely abstract. However, this is not an essential property of interfaces. Even when default methods are included, an interface at its heart still specifies a contract upon the implementing class. The implementing class can override default methods, so the class is still in complete control of its implementation. (Note also that default methods cannot be final.)
What is the difference between using an abstract class and the new version of the interface other than the ability of a class to extend multiple interfaces?
The ability of a class to extend multiple interfaces is closely related to another difference between interfaces and abstract classes, namely that interfaces cannot contain state. This is the primary difficulty with allowing multiple inheritance: if a superclass were to appear multiple times in the ancestry of a class, would that superclass' state appear just once or several times? (This is the so-called "diamond problem.")
Another difference is that abstract classes can define methods and fields to be shared with subclasses, but not with callers, by using protected and package-private access levels. Interfaces can have only public methods.
(In Java 9, support for private methods has been added. This is useful for implementation sharing among default or static methods of an interface.)
Finally, static methods in interfaces don't affect class inheritance, nor are they part of the interface's contract. They are merely a way of organizing utility methods in more convenient fashion. For example, a common use of static methods in an interface is for static factory methods. If static methods weren't allowed in interfaces, static factory methods would have to be put on a companion class. Allowing static methods in interfaces lets such methods be grouped with the interface itself, when doing so is appropriate.
The problem is, that you can never extend an Interface with a new method without breaking compatibility. Existing classes would not implement the method and therefore not run with the new version of code which use this method.
This was a major problem for the Java Class Library itself as it cannot add often asked for methods in basic interfaces (like Collections). This was the main driver for implementing default methods for interfaces.
The difference between this new method and using an abstract class (which is a quite good pattern for this problem in some cases) is, that you cannot inherit from multiple abstract classes. But you can easily implement multiple interfaces.
The static methods in interfaces are less clear, I think they are here to help you implement the default methods (if two default methods have same code, they both can call to a static method).
Related
As Java 9 is going to allow us to define private and private static methods too in interfaces, what would be the remaining difference in interface and class?
Moreover, is Java moving towards multiple inheritance slowly?
Private interface methods in Java 9 behave exactly like other private methods: They must have a body (even in abstract classes) and can neither be called nor overridden by subclasses. As such they do not really interact with inheritance. Talking of which (and particularly multiple inheritance), there are (at least?) three kinds of it:
Inheritance of types means that one type can be another type, e.g. String is an Object. Java allowed multiple inheritance of types from day one (via interfaces).
Inheritance of behavior means that one type can inherit the behavior of another type. Before Java 8, only classes could implement methods, so there was only single inheritance of this kind. With Java 8 came default methods, which allowed interfaces to implement methods, thus giving Java multiple inheritance of behavior.
Inheritance of state means that a type inherits another type's internal state (i.e. fields). As it stands (Java 9 and everything currently proposed for future Java versions), only classes can have state, so there is only single inheritance of this kind.
As you can see private interface methods do not add anything here.
Regarding your question of how interfaces and classes compare, there are two main differences: multiple inheritance and state. Interfaces support the former, classes can have the latter. Since state is kind-of important in typical OOP, classes will remain relevant. š
If there were a way for an interface to force an implementation to have a particular non-public field or straight-out define one itself, the game would change and interfaces could compete with classes.
Private methods are not inherited by subclasses, so this feature doesn't affect implementation classes. I believe the private methods in interfaces allow us to share code between default methods.
Java interfaces still cannot have non-static members. That's a big difference and not multiple inheritance IMO.
Java 9 interfaces still cannot contain fields and constructors. This makes a huge difference between classes and interfaces, so Java 9 is far from multiple inheritance.
Java Interface in version 9 have private methods but static private. The feature has been introduced to allow modular methods. One function should work with one responsibility instead of using lengthy default methods. It has nothing to do with multiple Inheritance. The more private static methods, the more you will be able to write the clean and reusable code. Anyways, static methods whether public or protected can not be overridden.
Although its an old question let me give my input on it as well :)
abstract class: Inside abstract class we can declare instance
variables, which are required to the child class
Interface: Inside interface every variables is always public static
and final we cannot declare instance variables
abstract class: Abstract class can talk about state of object
Interface: Interface can never talk about state of object
abstract class: Inside Abstract class we can declare constructors
Interface: Inside interface we cannot declare constructors as purpose of
constructors is to initialize instance variables. So what
is the need of constructor there if we cannot have instance
variables in interfaces.
abstract class: Inside abstract class we can declare instance and static blocks
Interface: Interfaces cannot have instance and static blocks.
abstract class: Abstract class cannot refer lambda expression
Interfaces: Interfaces with single abstract method can refer lambda expression
abstract class: Inside abstract class we can override OBJECT CLASS methods
Interfaces: We cannot override OBJECT CLASS methods inside interfaces.
I will end on the note that:
Default method concepts/static method concepts in interface came just to save implementation classes but not to provide meaningful useful implementation. Default methods/static methods are kind of dummy implementation, "if you want you can use them or you can override them (in case of default methods) in implementation class" Thus saving us from implementing new methods in implementation classes whenever new methods in interfaces are added. Therefore interfaces can never be equal to abstract classes.
While going through spring security modules I came across this piece of code inside the Principal Interface class. My understanding is that Interfaces do not implement anything concrete.
What is the reason for the below piece of code inside an Interface ?
public interface Principal {
//other method definitions
public default boolean implies(Subject subject) {
if (subject == null)
return false;
return subject.getPrincipals().contains(this);
}
}
Those are called default methods; and were introduced with Java8.
Quoting the Oracle tutorial:
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.
Meaning: starting with java8, we actually can add behavior into interfaces. The idea is to make it easier to enhance existing interfaces - not to provide a "generic" mixin/trait concept to Java.
In other words: according to the people behind Java, the main reason for default was the need to enhance a lot of existing collection interfaces to support the new stream paradigm.
It is also worth pointing out that Java8 interfaces also allow for static methods:
In addition to default methods, you can define static methods in interfaces. (A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.)
This is a default method for an interface, available since Java 8.
It's a feature that allows developers to add new methods to an interface without breaking the existing implementations of these. It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method.
Refactoring an existing interface from a framework or even from the
JDK is complicated. Modify one interface breaks all classes that
extends the interface which means that adding any new method could
break millions of lines of code. Therefore, default methods have
introduced as a mechanism to extending interfaces in a backward
compatible way.
Another potential usage would be to just call other methods from the interface like in a forEach option where you get a list parameter and call another method that accepts just one element.
My personal opinion is that default methods should be used as less as possible and to not contain any business logic. It's mainly made for keeping old interfaces (10+ years old) retro-compatible.
More details: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
https://dzone.com/articles/interface-default-methods-java
Does Java have plan that default method substitute for Abstract Class?
I could not find a real case to use default method instead of Abstract?
There are no such plans, which you can derive from comparing the already documented intentions, which differ from the implications of such a plan:
Stuart Marks writes:
The main goal is to allow interface evolution, that is, the addition of new methods. If a new method is added to an interface, existing classes that implement the interface would be missing an implementation, which would be incompatible. To be compatible, an implementation has to come from somewhere, so it is provided by default methods.
ā¦
The main intent of a Java interface is to specify a contract that any class can implement without having to alter its position in the class hierarchy. It's true that, prior to Java 8, interfaces were purely abstract. However, this is not an essential property of interfaces. Even when default methods are included, an interface at its heart still specifies a contract upon the implementing class. The implementing class can override default methods, so the class is still in complete control of its implementation. (Note also that default methods cannot be final.)
and Brian Goetz writes:
The proximate reason for adding default methods to interfaces was to support interface evolution, ā¦
Here are some use cases that are well within the design goals:
Interface evolution. Here, we are adding a new method to an existing interface, which has a sensible default implementation in terms of existing methods on that interface. An example would be adding the forEach method to Collection, where the default implementation is written in terms of the iterator() method.
"Optional" methods. Here, the designer of an interface is saying "Implementors need not implement this method if they are willing to live with the limitations in functionality that entails". For example, Iterator.remove was given a default which throws UnsupportedOperationException; since the vast majority of implementations of Iterator have this behavior anyway, the default makes this method essentially optional. (If the behavior from AbstractCollection were expressed as defaults on Collection, we might do the same for the mutative methods.)
Convenience methods. These are methods that are strictly for convenience, again generally implemented in terms of non-default methods on the class. The logger() method in your first example is a reasonable illustration of this.
Combinators. These are compositional methods that instantiate new instances of the interface based on the current instance. For example, the methods Predicate.and() or Comparator.thenComparing() are examples of combinators.
Note that these do not target the primary domain of abstract classes, like providing a skeleton implementation. Besides the technical differences, abstract classes are semantically different as they bear design decisions about how to implement the functionality, which interfaces, even with default methods, should not. E.g. a well-known example is the List interface, for which two fundamentally different abstract classes exist, AbstractList and AbstractSequentialList and the choice of subclasses either or implementing List entirely different should not be foreclosed by the interface. So the List interface defines the contract and can never be a substitute for an abstract class, which provides a particular base implementation.
Other answers, and links to additional materials, have already adequately covered the technical differences between interfaces and abstract classes. What hasn't been covered well is why to use one over the other.
Consider two different ways to use a class or interface in Java: as a caller or as a subclasser. A caller has an object reference and can call public methods and access public fields via that reference. A subclasser can also access, call, and override protected members of the superclass. Classes can have protected members, but interfaces cannot.
A common question seems to be, now that we have default methods, why do we need abstract classes? A default method is part of what the interface presents to callers. A protected method on a class is not available to callers; it is only available to subclassers. Thus, if you want to share implementation with subclassers, then use a class (or abstract class) and define protected members and fields.
The protected mechanism allows a class to communicate with subclassers, distinct from the way it communicates with callers.
But the OP asks the opposite question: why would one use default methods in preference to abstract classes? In the situation where you actually have a choice (i.e., your abstraction doesn't require state, or protected methods, or any of the things that abstract classes have that interfaces do not), interfaces with default methods are far less constraining than abstract classes. You can only inherit from one class; you can inherit from many interfaces. So interfaces with default methods can behave like stateless traits or mixins, allowing you to inherit behavior from multiple interfaces.
Given that interfaces and abstract classes are used for different purposes, there is no plan to remove or replace anything.
Default methods can't substitute abstract classes, as abstract classes can (and often do) have fields. Interfaces can only contain behaviour and not state, which is unlikely to change in the future as multiple inheritance of state in Java is seen (rightly or wrongly) as evil.
They can also have final methods, which is another thing you can't mimic with default methods.
If anything, interfaces with default methods resemble traits rather than abstract classes, but the match isn't perfect. Using interfaces as traits is something that has to be done very carefully and knowing the limitations they come with. (Such as any implementing class can override a default method, potentially ruining the trait.)
More on this here.
One of the reasons why default methods in interfaces were introduced was to allow adding new methods to the JDK interfaces.
Without this feature once a class has been compiled with a specific version of an interface no new methods can be added to this interface. With the default methods in interfaces feature interfaces can be changed.
Class Adapters uptil now have been considered not possible in java.Previous question regarding the same also says so.
But, Java 8 now supports default methods in Interfaces and multiple interfaces can be implemented by a class.
So, a class inheriting from multiple interfaces with multiple default methods can make one interface's default methods act as an adapter and make a call to the other interface's (adaptee's) default method.
So, now is the statement Java 8 supports Class Adapters correct?
As far as I understood, the Class Adapter Pattern is about creating a class which extends multiple types so that it inherits at least one implementation and at least one interface not formerly directly implemented by the implementation to enable using the existing implementation via the interface.
This has been possible in Java, with the restriction that the Adapter can only inherit one implementation (class) but inherit multiple interfaces (Compare with this answer). This limitation hasnāt changed in any way. You still can only inherit from one class.
It is correct that interfaces can now have default methods, but this doesnāt change the abstract nature of an interface and doesnāt make them eligible for conceptually bearing an implementation.
Even if an interface contains only default methods (no abstract methods), you still canāt instantiate it without creating a new class which implements the interface. Such a strange interface could only exist for primarily supporting the creation of Adapter classes which would then not be an example of the Class Adapter Pattern anymore, as that pattern is about combining formerly unrelated types, not types which were primarily designed for being combined.
In other words, in practice, when you encounter multiple implementation classes that you wish to combine in one Adapter, you will still face multiple classes which you canāt combine via inheritance and the existence of the default method feature wonāt change that.
So the bottom line is, before JavaĀ 8, this pattern could only be used with restrictions, and these restrictions still apply with JavaĀ 8. If you want to view these restriction as āItās not possibleā, then it is still not possibleā¦
This question already has answers here:
When to use an interface instead of an abstract class and vice versa?
(26 answers)
Closed 5 years ago.
In Java, you can create an abstract class that contains only abstract methods. On the other hand, you can create an interface that declares the same methods. That being the case, can you use abstract classes instead of interfaces?
Not always:
a class can extend only one class
a class can implement more than one interface
Sun docs make a more detailed comparison:
Abstract Classes versus Interfaces
Unlike interfaces, abstract classes can contain fields that are not static and final, and they can contain implemented methods. Such abstract classes are similar to interfaces, except that they provide a partial implementation, leaving it to subclasses to complete the implementation. If an abstract class contains only abstract method declarations, it should be declared as an interface instead.
Multiple interfaces can be implemented by classes anywhere in the class hierarchy, whether or not they are related to one another in any way. Think of Comparable or Cloneable, for example.
By comparison, abstract classes are most commonly subclassed to share pieces of implementation. A single abstract class is subclassed by similar classes that have a lot in common (the implemented parts of the abstract class), but also have some differences (the abstract methods).
In some cases you can use an abstract class instead of interface. However, it is hardly ever a good idea to do so. In general you should use the rule:
Interfaces specify behaviour.
Abstract classes specify implementation.
The other "problem" with using abstract classes is that you can then no longer implement mixins, that is you can implement multiple interfaces, however you can only extend one abstract class.
One point missing from the answers here is the idea of who will be implementing the interface.
If your component wants to return instances of abstract types to its callers, where the concrete types are defined internally and hidden from callers, use an interface. Conversely, if your component consumes or accepts instances of abstract types that its callers must implement, abstract classes are usually a better choice.
Anticipating evolution and maintaining binary compatibility tips the scales here. With an abstract class, you can add methods and, if you provide a base implementation, existing implementations of the abstract class will continue to work fine. With an interface, adding a method breaks binary compatibility, for no existing implementation could possibly continue to compile properly without changing to define the new method.
The Apache Cactus project has a good discussion on how to resolve these obligations.
To answer your question, yes you could use an abstract class (providing no implementation) instead of an interface but I'd consider this bad practice:
You've used up your "one-shot" at inheritance (without gaining any benefit).
You cannot inherit from multiple abstract classes but you can implement multiple interfaces.
I would advocate the use of abstract classes more in situations where you wish to provide a partial implementation of a class, possibly delegating some behavior to concrete subclass implementations.
A class in java can inherit from multiple interfaces, but only from one abstract class.
An interface cannot define any code, in an abstract class, you can define code (i.e. default behaviour of methods)
Abstract classes and interfaces are complementary.
For instance when creating an API you will want to present interfaces to the client, so that you may always completely change the implementation whereas he does not have to change its code and the user does not rely on implementation when building using your API but just on methods contracts.
Then you will have abstract classes partly implementing these interfaces, in order to
share some common code, which might be used in all (or almost all) implementations for interface, which is obvious
provide default behaviour which could be overridden in 'real' implementations, for instance a toString() method using interfaces methods to create a textual representation of the implementation
preserve implementations compatibility after interface changes, for instance when you add a new method in your interface, you also add a default implementation in the abstract class so that implementations (for instance those made by the user) extending the abstract class still work without changes
Interfaces are much cleaner and light weight. Abstract classes make you dependent on it heavily as you cannot extend any other classes.
Have a look at the interesting article "Why extends is evil" to get an idea about the differences between interface implementation and class inheritance (beside the obvious multi- single restrictions)
Abstract classes are the partial implementation of Abstraction while Interfaces are the fully implementation of Abstraction.Means in Abstract classes we can put methods declaration as well as method body.
We can't create an object of Abstract classes(association) and reuse the class by inheritence(not by association).
By default in interfaces all declared variables are static final and All methods are public.
For Example: In JDK there are only few abstract classes and HttpServlet is one of them which is used in Servlet.So we can't create object of HttpServlet and it can be used only by inheritence.
Main use of interface is when you create the reference of interface and call the method of particular class that's resolved at runtime. So it's always better idea to create reference of interface to call the method.
Interfaces can only hold abstract method, also interfaces can implement multiple interfaces to any class. But an abstract hold abstract and non abstract methods, and abstract methods cannot extend to more then one class.