Java 8 Interface vs Abstract Class - java

I went through this question:
Interface with default methods vs Abstract class in Java 8
The following part is not clear to me:
The constraint on the default method is that it can be implemented
only in the terms of calls to other interface methods, with no
reference to a particular implementation's state. So the main use case
is higher-level and convenience methods.
I tried creating objects of a concrete class (implementation) inside default method and invoked its instance method, it is working fine. i.e, I don't need to use Interface type as reference to the object.
Then what is meant by the quoted paragraph.

That sentence means that a default method is implemented inside an interface, so it doesn't have any access to a real state of an object but just to what the interface itself exposes, since an interface can't declare instance variables.
For example:
abstract class Foo {
int result;
int getResult() { return result; }
}
This can't be done in an interface because you can't have any member variable. The only thing you can do is to combine multiple interface methods, which is what it is specified as convenience / higher-level methods, eg:
interface Foo {
void preProcess();
void process();
void postProcess();
default void processAll() {
preProcess();
process();
postProcess();
}
}

Problem is that default methods can only "see" what is declared in the interface itself - not in the implementation class. Any state fields that are declared in the class that implements this interface are simply not accessible. But they can access static final fields of the interface:
interface test {
static final int x = 3;
public default void changeIt() {
System.out.println(x); // this would work
++x; // this will fail
}
}

The Default Method is Just used to gain A Backword_Compatibility Support . Note That The Priority of Default Method is Low Than a Normal Method(or Higher Level Method) So You Cannot Achived the higher-level and convenience methods

Related

Java: Force base class to use base class method instead of overriden method

I have a Base class method, that I want to override in a Derived class.
The derived class method should be called whenever the method with the same name is accessed from "outside" or from the derived class. When acessing the method from inside the base class, I want the base class method to be used. Consider the following code:
public class TestBaseMethod
{
static class Basic {
public Basic()
{
Basic.this.doSomething(); // <<---- This should call Basic version
}
public void doSomething()
{
System.out.println("Doing something old");
}
}
static class Derived extends Basic {
Object ressource = new Object();
#Override
public void doSomething()
{
System.out.println("Doing something completely new");
// ressource.toString(); // <<---- explosion
}
}
public static void main(String[] args)
{
Basic d = new Derived();
System.out.println("-------------------------------");
d.doSomething(); // <<---- This should call Derived version
}
}
I want the following output:
Doing something old
-------------------------------
Doing something completely new
But it produces this output:
Doing something completely new
-------------------------------
Doing something completely new
I thought that explicitly stating the base class name in Basic.this.doSomething(); should do that trick, but apparently it does not.
Obviously, I could declare a variable of type Basic inside a Derived class instead of Deriving, but that kind of defeats the idea that the Derived class "is-a" Basic class and would force me to write oneline-redirection methods to obtain the same interface.
Here is why I want to do that:
When writing base classes, I want to use methods where I have the guarantee that inside the base class, the methods that I wrote are used, because I do not want deriving classes to interfere with base class internals. To me, it makes sense from an encapsulation standpoint, but maybe I am wrong?
The Basic#doSomething() method can be called from the Basic() constructor.
If the Derived#doSomething() method uses ressources from Derived, then those ressources will only be available after Derived construction.
However: Derived construction finishes AFTER the superclass construction, which means that when Derived is constructed, the Derived#doSomething() is called in the Basic() constructor and it will access uninitialized data.
Is there a way around this?
Calling veritable methods from a constructor is a bad practice, more could be found here: On invoking overridable method from constructors
As for enforcing to call the base class method - it's impossible.
Make an inner method in Basic for doSomething and call that directly:
static class Basic {
public Basic()
{
doSomethingImpl();
}
public void doSomething()
{
doSomethingImpl();
}
private void doSomethingImpl()
{
System.out.println("Doing something old");
}
}
What you want to do is bad, from a design point of view. A good design would be to declare two separate methods, one overridable and the other not (either final or private).

What design pattern to use for a method implementation which is repeated in all classes implementing same interface?

I was trying to make an objected oriented examples out of "union find".
so I have an interface called UF,
public interface UF {
boolean connected(int p,int q);
void printArray();
void union(int p,int q);
}
and the following classes implement it quickFindUF,quickUnionUF,quickWeightedUnionUF
but all of them share a function which is identical in implementation, (the function printArray())
what is the best pattern to use to avoid printArray() code to be repeated ? do I create a class call ArrayPrinter and pass the array to it in the printArray() in all of those classes which implement UF ?
Is there any pattern that I can do this without doing abstract inheritance and just use interfaces. because inheritance limits my design, if I inherit a class I wont be able to inherit anything else, I don't make that limitation just for a printArray() method ...
You can have an abstract class AbstractUF like this:
public abstract class AbstractUF implements UF{
public abstract boolean connected(int p,int q);
public void printArray() {
//implementation
}
public abstract void union(int p,int q);
}
and inherit your classes from AbstractUF, so just (override and) implement other 2 functions
You are thinking of delegation. I would personally not call it a design pattern because it's just a compositional technique but anyway there is a Wikipedia article calling it one.
In this example, UnionFind extends ArrayPrinter so that the ArrayPrinter interface is propagated throughout the composite. The delegate implements a piece of the hierarchy:
interface ArrayPrinter {
void printArray();
}
interface UnionFind extends ArrayPrinter {
boolean isConnected(int p, int q);
void makeUnion(int p, int q);
}
class DefaultPrinter implements ArrayPrinter {
#Override
public void printArray() {
/**
* do actual print
*/
}
}
class QuickFind implements UnionFind {
private final ArrayPrinter printDelegate = new DefaultPrinter();
#Override
public void printArray() {
printDelegate.printArray();
}
/**
* the rest
*/
}
Is there any pattern that I can do this without doing abstract inheritance and just use interfaces.
In Java 8, you can declare default methods in interfaces. The limitation is that a default method cannot depend on instance variables declared by implementation classes. They have to rely entirely on the classes public API to access or update the object state.
For the cases where default methods are applicable, they avoid the need to extend a common base class, while also avoiding the cumbersomeness of delegation.
In Java 8, you could do it with Default method
Interface Methods
Default methods and abstract methods in interfaces are inherited like instance methods. However, when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict. These rules are driven by the following two principles:
Instance methods are preferred over interface default methods.
Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
So your code would be
public interface UF {
default public void printArray() {// Provide default implementation }
}
Interface-segregation principle suggests splitting different functionality into separate interfaces. In this case your printArray() method is a responsibility that can be separated from the UF interface.
You implement an ArrayPrinter interface and you pass arrays to it. This also keeps in line with the single responsibility principle as well as facilities decoupled architecture. You're UF interface doesn't know anything about the printing, that is a separated responsibility so it is handled by a different object.

Overriding Object class methods within an interface in Java

Let's consider the following simple code in Java.
package temppkg;
interface Interface
{
#Override
public abstract boolean equals(java.lang.Object arg);
#Override
public abstract String toString();
public void show();
}
final class Demo implements Interface
{
public void show()
{
System.out.println("Method invoked.");
}
}
final public class Main
{
public static void main(String...args)
{
new Demo().show();
}
}
In the above code snippet, the interface named Interface has some Object class methods from JDK and they are with the #Override annotation even though they are abstract. Now, the class Demo has implemented Interface and has not implemented the equals() and the toString(); methods. Still the compiler doesn't complain and the program is running successfully. Why?
What is the relation between interfaces and the object class in Java?
The Java Language Specification clearly says that the members of an
interface are those which are declared in the interface and those
which are inherited from direct super interfaces. If an interface has
no direct superinterface then the interface implicitly declares a
public abstract member method corresponding to each public instance
method declared in the Object class, unless a method with the same
signature, same return type, and a compatible throws clause is
explicitly declared by that interface. This is what makes the
signatures of the Object methods available to the compiler and the
code compiles without any error. Remember if the interface tries to
declare a public instance method declared 'final' in the Object class
then it'll result into a compile-time error. For example, 'public
final Class getClass()' is a public instance method declared 'final'
in the Object class and therefore if an interface tries to declare a
method with this signature then the compilation will fail.
http://geekexplains.blogspot.com/2008/06/do-interfaces-really-inherit-from-class.html
Check out JLS 9.2:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
In other words, every interface implicitly defines each of Object's methods, and you can therefore #Override those methods. The other methods aren't defined in Object, so you can't override them.
In Interface you're not actually overriding anything - an interface by definition can not provide implementations for any of its methods. The class Demo just inherits the equals and toString implementation from Object.
In essence an interface in Java contains a set of zero or more method signatures (all of them are implicitly abstract, in your code you made it explicit by adding the keyword abstract), and the concrete classes that implement the interface must provide an implementation for those methods. In the case of your code, that implementation comes from Object, since all the classes implicitly extend Object, which provides default implementations for equals and toString (among other methods).
You really shouldn't mark the methods in an interface with #Override, as you have seen, it's confusing and serves for no practical purpose. Instead, use #Override in the methods in the concrete class that implement the methods of the interface, like this:
class Demo implements Interface {
#Override
public void show() {
System.out.println("Method invoked.");
}
}
Also, it's completely unnecessary to declare equals and toString in an interface, so you're better off with this definition:
interface Interface {
public void show();
}
#Override can only be used for functions defined in the base class, Object. Object defines equals and toString, so you can use #Override with them, but not with, say, the function show. It indicates a relationship between the #Override functions in a class and its base classes, not it's derived classes.

Constructor in an Interface?

I know it's not possible to define a constructor in an interface. But I'm wondering why, because I think it could be very useful.
So you could be sure that some fields in a class are defined for every implementation of this interface.
For example consider the following message class:
public class MyMessage {
public MyMessage(String receiver) {
this.receiver = receiver;
}
private String receiver;
public void send() {
//some implementation for sending the mssage to the receiver
}
}
If a define an interface for this class so that I can have more classes which implement the message interface, I can only define the send method and not the constructor. So how can I ensure that every implementation of this class really has an receiver set? If I use a method like setReceiver(String receiver) I can't be sure that this method is really called. In the constructor I could ensure it.
Taking some of the things you have described:
"So you could be sure that some fields in a class are defined for
every implementation of this interface."
"If a define a Interface for this class so that I can have more
classes which implement the message interface, I can only define the
send method and not the constructor"
...these requirements are exactly what abstract classes are for.
A problem that you get when you allow constructors in interfaces comes from the possibility to implement several interfaces at the same time. When a class implements several interfaces that define different constructors, the class would have to implement several constructors, each one satisfying only one interface, but not the others. It will be impossible to construct an object that calls each of these constructors.
Or in code:
interface Named { Named(String name); }
interface HasList { HasList(List list); }
class A implements Named, HasList {
/** implements Named constructor.
* This constructor should not be used from outside,
* because List parameter is missing
*/
public A(String name) {
...
}
/** implements HasList constructor.
* This constructor should not be used from outside,
* because String parameter is missing
*/
public A(List list) {
...
}
/** This is the constructor that we would actually
* need to satisfy both interfaces at the same time
*/
public A(String name, List list) {
this(name);
// the next line is illegal; you can only call one other super constructor
this(list);
}
}
An interface defines a contract for an API, that is a set of methods that both implementer and user of the API agree upon. An interface does not have an instanced implementation, hence no constructor.
The use case you describe is akin to an abstract class in which the constructor calls a method of an abstract method which is implemented in an child class.
The inherent problem here is that while the base constructor is being executed, the child object is not constructed yet, and therfore in an unpredictable state.
To summarize: is it asking for trouble when you call overloaded methods from parent constructors, to quote mindprod:
In general you must avoid calling any
non-final methods in a constructor.
The problem is that instance
initialisers / variable initialisation
in the derived class is performed
after the constructor of the base
class.
A work around you can try is defining a getInstance() method in your interface so the implementer is aware of what parameters need to be handled. It isn't as solid as an abstract class, but it allows more flexibility as being an interface.
However this workaround does require you to use the getInstance() to instantiate all objects of this interface.
E.g.
public interface Module {
Module getInstance(Receiver receiver);
}
There is only static fields in interface that dosen't need to initialized during object creation in subclass and the method of interface has to provide actual implementation in subclass .So there is no need of constructor in interface.
Second reason-during the object creation of subclass, the parent constructor is called .But if there will be more than one interface implemented then a conflict will occur during call of interface constructor as to which interface's constructor will call first
If you want to make sure that every implementation of the interface contains specific field, you simply need to add to your interface the getter for that field:
interface IMyMessage(){
#NonNull String getReceiver();
}
it won't break encapsulation
it will let know to everyone who use your interface that the Receiver object has to be passed to the class in some way (either by constructor or by setter)
Dependencies that are not referenced in an interfaces methods should be regarded as implementation details, not something that the interface enforces. Of course there can be exceptions, but as a rule, you should define your interface as what the behavior is expected to be. Internal state of a given implementation shouldn't be a design concern of the interface.
This is because interfaces do not allow to define the method body in it.but we should have to define the constructor in the same class as interfaces have by default abstract modifier for all the methods to define. That's why we can not define constructor in the interfaces.
See this question for the why (taken from the comments).
If you really need to do something like this, you may want an abstract base class rather than an interface.
Here´s an example using this Technic. In this specifik example the code is making a call to Firebase using a mock MyCompletionListener that is an interface masked as an abstract class, an interface with a constructor
private interface Listener {
void onComplete(databaseError, databaseReference);
}
public abstract class MyCompletionListener implements Listener{
String id;
String name;
public MyCompletionListener(String id, String name) {
this.id = id;
this.name = name;
}
}
private void removeUserPresenceOnCurrentItem() {
mFirebase.removeValue(child("some_key"), new MyCompletionListener(UUID.randomUUID().toString(), "removeUserPresenceOnCurrentItem") {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
}
});
}
}
#Override
public void removeValue(DatabaseReference ref, final MyCompletionListener var1) {
CompletionListener cListener = new CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (var1 != null){
System.out.println("Im back and my id is: " var1.is + " and my name is: " var1.name);
var1.onComplete(databaseError, databaseReference);
}
}
};
ref.removeValue(cListener);
}
Generally constructors are for initializing non-static members of particular class with respect to object.
There is no object creation for interface as there is only declared methods but not defined methods. Why we can’t create object to declared methods is-object creation is nothing but allocating some memory (in heap memory) for non-static members.
JVM will create memory for members which are fully developed and ready to use.Based on those members , JVM calculates how much of memory required for them and creates memory.
Incase of declared methods, JVM is unable to calculate the how much memory will required to these declared methods as the implementation will be in future which is not done by this time. so object creation is not possible for interface.
conclusion:
without object creation, there is no chance to initialize non-static members through a constructor.That is why constructor is not allowed inside a interface.(as there is no use of constructor inside a interface)

Why can't I declare static methods in an interface?

The topic says the most of it - what is the reason for the fact that static methods can't be declared in an interface?
public interface ITest {
public static String test();
}
The code above gives me the following error (in Eclipse, at least): "Illegal modifier for the interface method ITest.test(); only public & abstract are permitted".
There are a few issues at play here. The first is the issue of declaring a static method without defining it. This is the difference between
public interface Foo {
public static int bar();
}
and
public interface Foo {
public static int bar() {
...
}
}
The first is impossible for the reasons that Espo mentions: you don't know which implementing class is the correct definition.
Java could allow the latter; and in fact, starting in Java 8, it does!
The reason why you can't have a static method in an interface lies in the way Java resolves static references. Java will not bother looking for an instance of a class when attempting to execute a static method. This is because static methods are not instance dependent and hence can be executed straight from the class file. Given that all methods in an interface are abstract, the VM would have to look for a particular implementation of the interface in order to find the code behind the static method so that it could be executed. This then contradicts how static method resolution works and would introduce an inconsistency into the language.
I'll answer your question with an example. Suppose we had a Math class with a static method add. You would call this method like so:
Math.add(2, 3);
If Math were an interface instead of a class, it could not have any defined functions. As such, saying something like Math.add(2, 3) makes no sense.
The reason lies in the design-principle, that java does not allow multiple inheritance. The problem with multiple inheritance can be illustrated by the following example:
public class A {
public method x() {...}
}
public class B {
public method x() {...}
}
public class C extends A, B { ... }
Now what happens if you call C.x()? Will be A.x() or B.x() executed? Every language with multiple inheritance has to solve this problem.
Interfaces allow in Java some sort of restricted multiple inheritance. To avoid the problem above, they are not allowed to have methods. If we look at the same problem with interfaces and static methods:
public interface A {
public static method x() {...}
}
public interface B {
public static method x() {...}
}
public class C implements A, B { ... }
Same problem here, what happen if you call C.x()?
Static methods are not instance methods. There's no instance context, therefore to implement it from the interface makes little sense.
Now Java8 allows us to define even Static Methods in Interface.
interface X {
static void foo() {
System.out.println("foo");
}
}
class Y implements X {
//...
}
public class Z {
public static void main(String[] args) {
X.foo();
// Y.foo(); // won't compile because foo() is a Static Method of X and not Y
}
}
Note: Methods in Interface are still public abstract by default if we don't explicitly use the keywords default/static to make them Default methods and Static methods resp.
There's a very nice and concise answer to your question here. (It struck me as such a nicely straightforward way of explaining it that I want to link it from here.)
It seems the static method in the interface might be supported in Java 8, well, my solution is just define them in the inner class.
interface Foo {
// ...
class fn {
public static void func1(...) {
// ...
}
}
}
The same technique can also be used in annotations:
public #interface Foo {
String value();
class fn {
public static String getValue(Object obj) {
Foo foo = obj.getClass().getAnnotation(Foo.class);
return foo == null ? null : foo.value();
}
}
}
The inner class should always be accessed in the form of Interface.fn... instead of Class.fn..., then, you can get rid of ambiguous problem.
An interface is used for polymorphism, which applies to Objects, not types. Therefore (as already noted) it makes no sense to have an static interface member.
Java 8 Had changed the world you can have static methods in interface but it forces you to provide implementation for that.
public interface StaticMethodInterface {
public static int testStaticMethod() {
return 0;
}
/**
* Illegal combination of modifiers for the interface method
* testStaticMethod; only one of abstract, default, or static permitted
*
* #param i
* #return
*/
// public static abstract int testStaticMethod(float i);
default int testNonStaticMethod() {
return 1;
}
/**
* Without implementation.
*
* #param i
* #return
*/
int testNonStaticMethod(float i);
}
Illegal combination of modifiers : static and abstract
If a member of a class is declared as static, it can be used with its class name which is confined to that class, without creating an object.
If a member of a class is declared as abstract, you need to declare the class as abstract and you need to provide the implementation of the abstract member in its inherited class (Sub-Class).
You need to provide an implementation to the abstract member of a class in sub-class where you are going to change the behaviour of static method, also declared as abstract which is a confined to the base class, which is not correct
Since static methods can not be inherited . So no use placing it in the interface. Interface is basically a contract which all its subscribers have to follow . Placing a static method in interface will force the subscribers to implement it . which now becomes contradictory to the fact that static methods can not be inherited .
With Java 8, interfaces can now have static methods.
For example, Comparator has a static naturalOrder() method.
The requirement that interfaces cannot have implementations has also been relaxed. Interfaces can now declare "default" method implementations, which are like normal implementations with one exception: if you inherit both a default implementation from an interface and a normal implementation from a superclass, the superclass's implementation will always take priority.
Perhaps a code example would help, I'm going to use C#, but you should be able to follow along.
Lets pretend we have an interface called IPayable
public interface IPayable
{
public Pay(double amount);
}
Now, we have two concrete classes that implement this interface:
public class BusinessAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
public class CustomerAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
Now, lets pretend we have a collection of various accounts, to do this we will use a generic list of the type IPayable
List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());
Now, we want to pay $50.00 to all those accounts:
foreach (IPayable account in accountsToPay)
{
account.Pay(50.00);
}
So now you see how interfaces are incredibly useful.
They are used on instantiated objects only. Not on static classes.
If you had made pay static, when looping through the IPayable's in accountsToPay there would be no way to figure out if it should call pay on BusinessAcount or CustomerAccount.

Categories

Resources