Implementation of Multiple Parallel interface - java

Suppose I have an interface defined as:
public interface TestInterface1 {
public void add();
}
which is implemented by classes A, B and C.
Now I need to add a subtract functionality only to class C; for that I have created a new interface TestInterface2 and implemented that to class C:
public interface TestInterface2 {
public void sub();
}
Class C looks like this:
public class C implements TestInterface1, TestInterface2 {
public void add() {
System.out.println("I am in add");
}
public void sub() {
System.out.println("I am in Sub");
}
}
Now the problem is instances of C has been use in hundreds of places like this:
TestInterface1 c = new C();
And only class C is getting the add method of TestInterface1.
Is there any way or pattern to implement both the interfaces in class C so that where ever the object of class C is created, it gets both the method from TestInterface1 and TestInterface2?

If you can change your interfaces then make TestInterface1 extend the other one, so object created using first interface can use its parent methods.
public interface TestInterface1 extends TestInterface2{
public void add();
}

Before we get into this, you have to consider why you're even using interfaces for this at all. An interface guarantees that all instances are using the same implementations. If you want a specific class to have a more specific implementation, then that sounds more like a method on the concrete class more than it does a new interface at all.
Regardless, we can discuss your options. One of them is cleaner and conveys clear intent; the other muddies things.
The first option - which conveys clearer intent - is to eschew the usage of the more restrictive interface and instead use TestInterface2 for every declaration that you want to use C.
This means you'd write TestInterface2 c = new C(); everywhere you wanted to use it. Yes, you'd be changing it in all of the places that you're using C, but given that you have to have a method specifically attached to instances of C, this option is clearest.
This would be the same approach if you just wrote the method in C. There's really no difference between the two and I personally would prefer if you wrote the method that only belonged to C in C.
The second option - which muddies things and also requires Java 8 - is to use a default method. This requires that you implement it in the interface at first...
public interface TestInterface {
default void sub() {
System.out.println("I am in sub!");
}
}
...but you can override it in your class later. This muddies things because any class that implements TestInterface has access to this default method, which is likely not what you want for your requirements.

Related

default method in interfaces

For a while I have been puzzled as to why we need default methods in Interfaces, and today I was reading about it. Even though few of my questions are answered, I still have a few queries.
Let's take a simple example, I've an interface1. Class A and class B implement interface1. interface1 has a method X.
interface interface1{
void methodX();
}
class A implements interface1{
#override
public void methodX(){
//something
};
}
class B implements interface1{
#override
public void methodX(){
//something
};
}
From what I understood, since adding a new method Y to interface1, would have broken Class A and class B, default methods were introduced. This means that now I can add a default method, without the need for modifying Class A and Class B. This also means that the default method has to be generic enough to do whatever we expect it to do, for both class A and class B.
Now, let's consider that we normally add functions in interface so that we can provide a class specific implementation to them by overriding it. So basically, if I am adding a method Y in an interface as default, then I will expect class A and class B (or class A/ClassB) to override the method.
Which means, I will be modifying Class A/Class B or both.
This is what confuses me. This could have been handled by creating a new interface and modifying 1 (or both) class(es) to implement that new interface (interface 2 extending interface1), and then provide implementation for the same in the class.
interface interface2 extends interface1{
void methodY();
}
class A implements interface2{
#override
public void methodY(){
//something
}
}
class B implements interface1{
#override
public void methodX(){
//something
};
}
How does default method, actually help us in not modifying the classes which implements it.
Default methods provides "base" implementation of some behaviour which can be composed of existing methods at given interface. For example, you have an interface with add method. This is enough to provide default implementation for addAll behaviour:
default void addAll(Collection<? extends E> c) { for (E e : c) { add(e); } }
Another example can be sort method in List, which can be implemented by provided methods: get(int), set(int,E), size(). Subclass might override this default implementation in order to provide more efficient sorting based on specific list properties. In LinkedList you can take advantage of attaching/detaching nodes (no need to shift an elements on right when inserting or removing node), in ArrayList you can take advantage of super fast access of element at any index).
If you mandate all the implementing classes to override the new method, then it should (if there is no valid default implementation) not be a default method.
But, the approach you have said in which to create a new interface that extends the existing one and making the classes that wish to override the new method(s) by changing the interface type they implement will be problematic since the new method is part of the new interface, you cannot access it when you have the parent/base interface type.
Example:
Existing code:
interface Base {
void m1();
}
class A implements Base {
#Override
public void m1() {
....
}
}
class B implements Base {
#Override
public void m1() {
....
}
}
You create the following interface
interface ExtendedBase extends Base {
void m2();
}
Only class A wants to implement m2. So, it becomes
class A implements ExtendedBase {
#Override
public void m1() {
....
}
#Override
public void m2() {
....
}
}
All is good so far.
When you have a method that takes an object of type Base, you can only call m1 on it (irrespective of you pass object of type A or B)
void someMethod(Base base) {
base.m1();
//base.m2(); won't work
}
To actually make use of m2 elsewhere, you need to change Base to ExtendedBase which would mean that you can no longer pass a B to it. So, you have made all classes implement m2 anyway.
Since a default method is defined in an interface, it can only access instance methods also defined in the same interface. Hence, it can only invoke functionality that is actually provided by the implementing classes (in your example A and B).
The default method does not "change" the classes' behavior, it extends it by accessing existing, properly defined behavior.
So basically, if I am adding a method Y in an interface as default, then I will expect class A and class B (or class A/ClassB) to override the method.
This wrong.
The idea of default method is to introduce new method without break compatibility with old code.
Existing implementation classes do not need to be modified to work with new default method.
This could have been handled by creating a new interface and modifying 1 (or both) class(es) to implement that new interface (interface 2 extending interface1), and then provide implementation for the same in the class.
Then you have to touch / modify the implementation class. That's what default method try to avoid.

Multiple inheritance and multiple interface. What's the true difference?

I was reading through online for the reason as to why multiple inheritance is not allowed in Java and the following example was given to illustrate it:
class A {
public void doSomething() {
}
}
class B {
public void doSomething() {
}
}
class C extends A,B {
}
public static void main(String args) {
C c = new C();
c.doSoemthing(); // compiler doesnt know which doSeomthing to call.
The above example illustrates what we call a diamond problem where by both parent classes have the same method name. when a child class tries to retrieve it, the compiler gets confused.
My question is, how will an interface solve this kind of problem ?
It's not fair to say that multiple inheritance achieved through interfaces in java
Java support only multiple interface inheritance, and java does not support multiple inheritance.
You should see In mixin inheritance, one class is specifically designed to be used as one of the classes in a multiple inheritance scheme.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
Lets think about the following code
interface P {
public void doSomething();
}
interface Q {
public void doSomething();
}
class A {
public void doSomething() {
}
}
class B {
public void doSomething() {
}
}
class C implements P,Q {
public void doSomething(){
// implementation
}
}
class D extends A,B { // suppose it is possible
}
now to use object of C you have the implementation of doSomething() in C class. Which is only implemented in C class.
But if you could create an object of D and call doSomething which method should be called? as this method is implemented in both A and B.
Diamond Problem
actually the real diamon problem is
class A {
public void doSomething() {
}
}
class B extends A{
public void doSomething() {
}
}
class C extends A{
public void doSomething() {
}
}
class D extends B,C { // suppose it is possible
// no implementation of doSomething.
}
it is called diamond because of it's diamond shape. Here if you want to do following
D d = new D();
d.doSomething(); // which method should be called now????
From wikipedia here is a nice real time example
For example, in the context of GUI software development, a class
Button may inherit from both classes Rectangle (for appearance) and
Clickable (for functionality/input handling), and classes Rectangle
and Clickable both inherit from the Object class. Now if the equals
method is called for a Button object and there is no such method in
the Button class but there is an overridden equals method in both
Rectangle and Clickable, which method should be eventually called?
The interface does not implement the doSomething() method, so you cannot call an interface method. Interface is a mere signature what methods to implement in the actuall (implementing) class. You would implement the doSomething() in your class C and that would be the method you are calling when invoking B.doSomething() or A.doSomething().
In the case of extending two claasses with two doSomething() methods, they could be having different implementations and you would not know which one is invoked. See this example:
class A {
public void doSomething() {
System.out.println("A");
}
}
class B {
public void doSomething() {
System.out.println("B");
}
}
class C extends A & B { //if this would be an option
}
public static void main(String args) {
C c = new C();
c.doSoemthing(); //Print "A" or "B" ???
}
Conclusion: It's an implementation thing. Interfaces do not offer any implementation for any method, so it's safe to inherit from interfaces having the same method signatures.
Multiple inheritance can inherit member data from many classes as well as all their functions. Multiple interfaces can only inherit function prototypes and they must be implemented by the child class.
An interface has no implementation of the method, and thus they both will be merged into the same method.
In fact, your object promises to implement a method called doSomething, but not tied to specifically one of the interfaces (serves both)
Answer lies in your question itself. In case of interface compiler does not get confused as there is no implementation in your interface. Its your concrete class which will provide the actual implementation .Hence no confusion.
Both classes provide code that the JVM can jump to when the call is made. This is where the ambiguity lies. Same problem with attributes, the compiler might have two attributes with the same name to look into, which will give a similar ambiguity.
An interface will not provide that code. Hence there will be no conflict.
Other languages that support multiple inheritance makes the compiler prohibit these ambiguities when they arise. And resolving them needs to be made ad hoc. I.e.
class C{
public void doSomething(){
// Call (this inferred)
B.doSomething();
// leave A.doSomething() alone.
}
}

Calling super class method inside implemented abstract method

Basicaly I have a need for several methods that do the same thing but with different parameters the sub-classes can chose from, and still force the implementation.
Is this a correct approach/design ?
EDIT: I have edited the addItem() body, these methods contain the final logic that is used to handle the passed parameters
public abstract Class A {
public abstract void addItemImpl()
addItem(String s) {
// do stuff
}
addItem(Collection c) {
// do stuff
}
addItem(Item item) {
// do stuff
}
}
public Class B extends A {
addItemImpl() {
addItem("text, text2")
}
}
public Class C extends A {
addItemImpl() {
addItem([item, item2])
}
}
No, this will not work.
You will not be able to define the "doStuff()" method because you have to handle the parameters. You provide not enough information to give you detailed help. But it's possible that generics might come in handy:
public abstract Class A<T> {
public addItem(T t) {
// dostuff with t
}
}
public Class B extends A<String> {
}
public Class C extends A<Collection> {
}
This is a perfect case for: Favor composition over inheritance.
Your subclasses don't fully benefit from the superclass and don't depend on its implementation details. Then define an interface for the contract B and C must obey (addItemImpl()) and compose them with A.
Ask yourself: is B really an A? is C really and A?
What you have is technically correct, but with out knowing what addItem actually does it is difficult to know if this is the best solution. My guess would be that there probably is a better way.
If addItem essentially set values to be used in the doStuff, I would just do that work in the Class B and C instead. Any others that need to do it the same way as B could extend it instead of A.
Edit: Based on your edit, I would say this is probably a bad example to use an abstract class. There is no truely shared functionality. An interface would be more appropriate as you need a different implementation for each. You are just trying to hide that inside an abstract class. I would change A to an interface along with using generics.
Only go the abstract class route if there is actually shared code that is exactly the same in all the classes without having to do any tricks to make it work (like above).
If you need force implementation for few methods, then Abstract methods are ideal.
But be careful only the very first Non-Abstract sub-class of the Super-class is bound to implement all the abstract methods in it....

Interfaces usage

Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class? Therefore having object A which uses the interface and object B which does not use it.
Thanks
Updated:
Assuming you have a Professor class and this class implements an interface called Employer, which has employ(rAssist x) abstract method.
Now I want to instantiated 2 objects from the Professor class implementing this interface Object A - Professor can employ a research assistant and Object B - Professor cannot employ research assistants.
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class?
No, if class C implements the interface, then all instances of C will provide the methods declared in the interface.
What you can do is something like
class MyClass implements MyInterface {
#Override
void interfaceMethod() {
System.out.println("Interface method");
}
}
and then do
MyClass x = new MyClass();
MyClass y = new MyClass() {
#Override
void interfaceMethod() {
throw new UnsupportedOperationException();
}
};
In effect, x supports the use of interfaceMethod while y does not. Note however that...
The usage of y.interfaceMethod is not prevented at compile-time, i.e. it will not be enforced by the type system.
With this solution, you are in fact creating an (anonymous) subclass of MyClass and assigning an instance of it to y.
Do you mean you want class A and Class B to implement a common Interface but you dont want to implement all methods in Class B?
An Interface in simple terms means it is sort of a contract and all the classes which implement it should follow that contract.So if you want Class B to implement the interface , Class B should also follow the same contract. But if you dont want to implement any methos you can always do this.
class ISampleInterface {
void sampleMethod();
void optionalMethod();
}
Class A implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
//Your Implementation
}
}
class B implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
throw new UnsupportedMethodException();
}
}
No, that's not the point of an Interface.
An Interface is contract that guarantees that implementations WILL implement it's signature
The idea of interface is to establish a obligation for the class that implements the interface.
If your's is a requirement, you can use the java.lang.reflect.Method reflection class to change the visibility of the method at runtime. However, this is not a clean way.
1. Interfaces were introduced in Java because Multiple Inheritance was not allowed in Java.
2. But as far as Design Pattern are concerned, following are the uses..
- To implement certain Roles.
Consider Dog a Super class, but then Pet dog and Wild dog can be interfaces, which
can be implemented by the Sub Classes of Dog class.
- Used when Behaviors keeps changing.
Consider you have a Class Drawing, and paint method() in it, now paint can be stroking, shading, etc...
You must Encapsulate such behaviors in an Interface or an Abstract class.

What (not) to declare when implementing an interface with an abstract class?

I have an interface A, for which I have to supply a few different
implementations. However, those implementations share some helper methods, so
I moved those methods to an abstract base class.
Interface A {
void doX();
}
abstract Class B implements A {
protected void commonY() {
// ...
}
#Override
public abstract void doX();
}
Class C extends B {
#Override
public void doX() {
// ...
}
}
Class D extends B {
#Override
public void doX() {
// ...
}
}
My code works as expected, but I have a few questions:
Should I declare the abstract Method doX() in Class B? Why (not)?
Should I also explicitly declare "implements A" on Class C and D? Why (not)?
I think it would be better to do it as follows:
Interface A {
void doX();
}
abstract Class B {
protected void commonY() {
// ...
}
}
Class C extends B implements A{
public void doX() {
// ...
}
}
Class D extends B implements A{
public void doX() {
// ...
}
}
You shouldn't mix the interface (signature of methods) with the implementation.
Should I declare the abstract Method doX() in Class B? Why (not)?
No. It's an abstract class - defining the interface will mean that all subclasses will need to implement those methods. In other words, it's redundant.
Should I also explicitly declare "implements A" on Class C and D? Why (not)?
No, again - because your superclass (Abstract base class) implements that interface, your concrete subclasses will be guaranteed to implement that interface.
I'll just throw in the other option.
Turn abstract class B into an AUtil class that doesn't implement A. The method signatures may require an additional argument of type A to work with.
C and D implement A, and instantiate an AUtil internally. This does allow C and D to extend other classes.
I agree with JeeBee: consider implementing your helper methods somewhere other than an abstract base class.
If your helper method commonY() only exists in abstract base class B, all classes which implement Interface A will have to also extend base class B in order to take advantage of that implementation of commonY(). But, you might not always want to be forced to extend class B.
Also, what if you want to change the implementation of commonY() in the future? You will then affect lots of implementations of interface A. But if you don't control all these implementations of interface A, you may affect their functionality (in a bad way) without intending to.
Using an abstract base class in this situation may simply take away some flexibility without giving you anything in return.
An abstract class implementing an interface must implement that interface. Specifically, it must have a public method for every method-name-and-signature specified in that interface.
Inheritance is transitive. You do not need to write that class C implements interface A if class C derives class B which implements interface A. However, there isn't much harm to it either.
I would not declare doX() in B and not add "implements A" on C and D because you should not repeat yourself.
The abstract doX() in B adds nothing, as it's already specified by "implements A". The same is true for adding "implements A" to C and D.
The only possible use for those clauses would be documentation: If you want to make it very explicit that C (or D) is-a A, then you could add the implements, but you should be aware that it really doesn't matter to the compiler.

Categories