Reputation: 1376
I already read the post of research effort required to post a SO question. I am ashamed again to post this question to a pile of million questions. But I still don't get the idea of interfaces in java. They have unimplemented methods and then defined for every class in which they are implemented. I searched about it. Interfaces were used to support multiple inheritance in java and also to avoid (Deadly) Diamond Death of inheritance. I also came across Composition vs Inheritance and that inheritance is not for code reuse and its for polymorphism. So when I have a common code as a class to extend it will not be supported due to multiple inheritance which gives the option to use Interfaces(Correct me if I am wrong). I also came across that its not possible in most cases to define a generic implementation. So what is the problem in having a common definition (not a perfect generic implementation) of the interface method and then Override it wherever necessary and why doesn't java support it. Eg. When I have 100 classes that implements an interface 70 of them have a common implementation while others have different implementation. Why do I have to define the common method in interface over 70 classes and why can't I define them in Interface and then override them in other 30 classes which saves me from using same code in 70 classes. Is my understanding of interfaces wrong?
Upvotes: 3
Views: 5088
Reputation: 25873
First, an interface in Java (as of Java 7) has no code. It's a mere definition, a contract a class must fulfill.
So what is the problem in having a common definition (not a perfect generic implementation) of the interface method and then Override it wherever necessary and why doesn't java support it
Yes you can do that in Java, just not with interfaces only. Let's suppose I want from this Example
interface to have a default implementation for method1
but leave method2
unimplemented:
interface Example {
public void method1();
public String method2(final int parameter);
}
abstract class AbstractExampleImpl implements Example {
@Override
public void method1() {
// Implement
}
}
Now classes that want to use this method1
default implementation can just extend AbstractExampleImpl
. This is more flexible than implementing code in the interface because if you do so, then all classes are bound to that implementation which you might not want. This is the advantage of interfaces: being able to reference a certain behavior (contract) without having to know how the class actually implements this, for example:
List<String> aList = MyListFactory.getNewList();
MyListFactory.getNewList()
can return any object implementing List
, our code manipulating aList
doesn't care at all because it's based on the interface.
What if the class that uses interface already is a Sub-class. Then we can't use Abstract class as multiple inheritance is not supported
I guess you mean this situation:
class AnotherClass extends AnotherBaseClass
and you want to extend AbstractExampleImpl
as well. Yes, in this case, it's not possible to make AnotherClass
extend AbstractExampleImpl
, but you can write a wrapped inner-class that does this, for example:
class AnotherClass extends AnotherBaseClass implements Example {
private class InnerExampleImpl extends AbstractExampleImpl {
// Here you have AbstractExampleImpl's implementation of method1
}
}
Then you can just internally make all Example
methods being actually implemented by InnerExampleImpl
by calling its methods.
Is it necessary to have the interface in AnotherClass?
I guess you mean AnotherClass implements Example
. Well, this is what you wanted: have AnotherClass
implement Example
with some default implementation as well as extend another class, or I understood you wrong. Since you cannot extend more than one class, you have to implement the interface so you can do
final Example anotherClass = new AnotherClass();
Otherwise this will not be possible.
Also for every class that implements an interface do I have to design an inner class?
No, it doesn't have to be an inner class, that was just an example. If you want multiple other classes have this default Example
implementation, you can just write a separate class and wrap it inside all the classes you want.
class DefaultExampleImpl implements Example {
// Implements the methods
}
class YourClass extends YetAnotherClass implements Example {
private Example example = new DefaultClassImpl();
@Override
public void method1() {
this.example.method1();
}
@Override
public String method2(final int parameter) {
return this.example.method2(parameter);
}
}
Upvotes: 6
Reputation: 24316
I think you are struggling with the concept of Object Oriented Design more than anything. In your example above where you state you have 100
classes and 70
of them have the same method implementation (which I would be stunned by). So given an interface like this:
public interface Printable
{
void print();
}
and two classes that have the "same" implementation of print
public class First implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
public class Second implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
you would instead want to do this:
public abstract class DefaultPrinter implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
now for First
and Second
public class First extends DefaultPrinter
{
}
public class Second extends DefaultPrinter
{
}
Now both of these are still Printable
. Now this is where it gets very important to understand how to properly design object hierarchies. If something IS NOT a DefaultPrinter
YOU CANNOT AND SHOULD NOT make the new class extend DefaultPrinter
Upvotes: 0
Reputation: 856
You should understand the funda of interface first. Which is
Upvotes: 0
Reputation: 371
The idea of the interface is to create a series of methods that are abstract enough to be used by different classes that implement them. The concept is based on the DRY principle (Don't repeat yourself) the interface allows you to have methods like run() that are abstract enough to be usuable for a game loop, a players ability to run,
Upvotes: 0
Reputation: 75356
The Java interfaces could have been called contracts instead to better convey their intent. The declarer promise to provide some functionality, and the using code is guaranteed that the object provides that functionality.
This is a powerful concept and is decoupled from how that functionality is provided where Java is a bit limited and you are not the first to notice that. I have personally found that it is hard to provide "perfect" implementations which just need a subclass or two to be usable in a given situation. Swing uses adapters to provide empty implementations which can then be overrides as needed and that may be the technique you are looking for.
Upvotes: 0
Reputation: 6138
You can create an abstract class to implement that interface, and make your those classes inherit that abstract class, that should be what you want.
Upvotes: 2
Reputation: 5903
A non abstract class that implements and interface needs to implement all the methods from the interface. A abstract class doesn't have to implement all the methods but cannot initiated. If you create abstract class in your example that implements all the interface methods except one. The classes that extend from these abstract class just have to implement the one not already implemented method.
Upvotes: 0