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.
}
}
Related
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.
I have one class and two interfaces
public class A implements B, C {
public static void main(String[] args) {
A a = new A();
a.foo();
}
}
public interface B {
default void foo(){
System.out.println("foo in B");
}
}
public interface C {
void foo();
}
The thing i'm concerned about is that java doesn't compile this giving an error that I must implement method from C. Hence I have a question. Why doesn't the default body cover that part, I mean the only thing java must be concerned about is that all the methods have their implementations, right? But for the class A, it's obvious that the implementation is given in B.
So why is java giving that error?
This is because interface B and C are not in same inheritance tree. And if they are not then Java compiler cannot be sure that implementing class has implementation of all methods of interface until it checks for each method from each implementing interface.
If you will define interface C as public interface C extends B then you will not get the error because in this case Java compiler will be sure that all methods are implemented.
Read more from JLS §9.4.1. Inheritance and Overriding
If a class is implementing two interfaces, which inteface is actual the parent interface for that class in Java
interface A {
void m1();
}
interface B {
void m1();
}
public class C implements A,B {
public void m1() {
System.out.println("m1 method !!!");
}
public static void main(String[] args) {
C obj = new C();
obj.m1();
((A)obj).m1();
((B)obj).m1();
A objAsA = (A)obj;
objAsA.m1();
B objAsB = (B) obj ;
objAsB.m1();
}
}
There is no such concept as "the actual parent interface" in Java. All interfaces are on equal footing as the supertypes of the class. That doesn't change even in your case where both interfaces declare the same method signature: the same method in C implements both A and B.
BTW you don't need a cast operator to accomplish an upcast:
A objAsA = obj;
objAsA.m1();
B objAsB = obj;
objAsB.m1();
parent is a concept related for extension not implementation.
From Java Java Specification
interface Fish { int getNumberOfScales(); }
interface Piano { int getNumberOfScales(); }
class Tuna implements Fish, Piano {
// You can tune a piano, but can you tuna fish?
public int getNumberOfScales() { return 91; }
}
the method getNumberOfScales in class Tuna has a name, signature, and return type that matches the method declared in interface Fish and also matches the method declared in interface Piano; it is considered to implement both.
So its considered you implement BOTH
Your question doesn't make sense. You do not have 'parent' interfaces in java.
An interface is like a contract, you 'promise' to provide the methods listed in the interface. You are getting inheritance mixed up with interfaces.
Inheritance is where one class inherits parts of another class.
Like Dog -> Husky, Dog -> Poodle
An interface is where every Animal promises to have a method called public String getSpecies() for example.
In case you want to find all the interfaces a class has look at this question.
Determining the extended interfaces of a Class
While an interface can extend other interfaces, a 'normal' class doesn't have the concept of parent interfaces.
Thank you to akhil for spotting this.
You can think of child classes as specialisations of their parents, each level being more specific.
Animal -> Dog -> Husky. However every lower level has some common functionality with its siblings. All Dogs can bark(), all Animals can move().
Now try applying this logic to interfaces and you will see that it doesn't really make sense. An interface exists only to ensure that every class has a specific ability. All animals need to breathe, regardless of what species so you can make Animals implement Breathable. Which ensures that every animal has a method breathe().
Here class C implements both the interfaces and C is A and C is B as well.
An implemenation means you need to use that method in your class. So there is no parent of it. With extendions this can be, but then there can't be 2 parents to 1 class. For example:
public static void main(String[] args){
C c = new C();
c.m1();
}
class A {
public void m1() {
System.out.println("A printing");
}
}
class B {
public void m1() {
System.out.println("B printing");
}
}
class C extends A {
public void m1() {
System.out.println("C print");
}
}
printing: "C print"
C can't extend B at the same time. But it does override the method of class A. If C did not contain the method "m1()" then the method from class A was used and the console would print: "A printing"
Having the following superclass:
public class SuperClass {
protected Integer a;
protected Integer b;
public void doSomething() {
this.a = 10;
}
public void doEverything() {
SuperClass.this.doSomething();
this.b = 20;
}
public static void main(String[] args) {
SuperClass instance = new SubClass();
instance.doEverything();
System.out.println(instance.a); //should print 10
System.out.println(instance.b);
}
}
And the following subclass:
public class SubClass extends SuperClass {
#Override
public void doSomething() {
super.doSomething();
super.a *= 10;
}
public void doEverything() {
super.doEverything();
this.b += 5;
}
}
Outputs:
100
25
So, SuperClass.this.doSomething(); is accessing SubClass's doSomething, but I need it to access the SuperClass's doSomething. In that case, I don't have the super keyword, because I'm already on super!
Is there a way to reference¹ the deep SuperClass.this.doSomething, so it would output 10 for the first output value?
¹ I'm interested on referencing: we could, of course, extract the SuperClass's doSomething to an auxiliar private method and access it directly.
If there is no way, does the situation where a superclass method needing to access its another (although overridden) method mean that my OOP design isn't correct? Why?
I assume you come to Java from C++ background. The languages are similar in concepts and in syntax, but they are different in the implementation.
You can achieve what I think is your intention also in Java, but the structure will look differently from C++.
In Java the construct SuperClass.this in your example is exactly the same as this, so SuperClass.this.doSomething(); is exactly what just doSomething() would be. So why does Java at all has the construct SuperClass.this? It has its meaning unrelated to the inheritance. It is useful in the context of nested classes.
Imagine a structure like this:
class A {
class B {
public void doSomething() {
// this here refers to an instance of the class B
System.out.println(this);
// We need to write is this way,
// because this hides the this reference to the instance of A.
// A.this is the instance of A where this is nested
System.out.println(A.this);
}
}
So how can you make sure to be able to have a method in a class that subclasses can override, and still be able to call the specific implementation?
Well, in the strict sense, you cannot. What you can do, is to create a final method, which cannot be overridden, and call it from a non-final method.
class SuperClass {
public void doSomething() {
doSuperClassyThing();
}
public final void doSuperClassyThing() { // cannot be overridden
...
}
}
A similar approach (with a bit different goal) you can see in the Template Method Pattern.
You cannot do what you want. The way polymorphism works is by doing what you are seeing.
That means there is no direct way to call SuperClass.doSomething() from SuperClass.doSomething() without going though SubClass.doSomething() unless you're working with an actual instance of SuperClass.
In some other languages you have power to tell how to handle this for example with keyword virtual in c++, but in java you don't have that option. All the method are being dynamically binded so you cannot do that. You can only not override or prevent it from being overriden at all.
The answer is that you can't refer to it. The only way to do this is the private helper method approach that you are aware of already.
If you want to know the reason why, I guess it's just because it would complicate the language for no reason; you can always get the same result by using a private helper method. The syntax SuperClass.this.doSomething() is already taken for something else. That means calling the method doSomething on the enclosing instance if SuperClass is an enclosing class.
If you ever find yourself on that situation, maybe you should rethink and consider that the class structure is not that correct yet.
Try to implement one of the following approaches:
Composition over Inheritance.
Creating a new Inheritance level (a class in the middle that has a reference to super).
Same as (2.), but using an inner class.
Extract the wanted method to a separate private one and call it where applicable.
Since (1.) wouldn't be as dry as the others, (4.) leaves a feeling of a workaround, and (2.) would require the creation of a new file and would reference outside SuperClass; I think the closest approach would be (3.), which is the only solution that in some way references super inside SuperClass (although it's actually referenced on a SuperClass inner class):
SuperClass.java:
public abstract class SuperClass {
protected Integer a;
protected Integer b;
public void doSomething() {
this.a = 10;
}
public abstract void doEverything();
public static class Impl extends SuperClass {
#Override
public void doEverything() {
super.doSomething();
this.b = 20;
}
}
public static void main(String[] args) {
SuperClass instance = new SubClass();
instance.doEverything();
System.out.println(instance.a); //prints 10
System.out.println(instance.b);
}
}
SubClass.java:
public class SubClass extends SuperClass.Impl {
#Override
public void doSomething() {
super.doSomething();
super.a *= 10;
}
#Override
public void doEverything() {
super.doEverything();
this.b += 5;
}
}
Say that I in Java have 3 classes, wheres the super one has a function named func(), I now make a subclass which overrides this, and a subclass to my subclass, now working on my sub-sub-class how will I call the 'func()' of the sub class, and the superclass?
I tried casting the 'this' "pointer", but Java 'fixes' it at runtime and calls the subsub func().
Edit:
Thanks everyone; 'Skeen is back at the drawing board'.
The best you can do is call super.func() in your subsub class, and have the func() implementation in your subclass also call super.func().
However, ask yourself, if I need knowledge not only of my parents implementation but also my grandparents implementation, do I have a design problem? Quite frankly this is tripping my "Something stinks in the fridge" instinct. You need to re-evaluate why you want to do this.
This isn't possible in Java. And btw. there aren't any pointers in Java.
I would jump on the "something in this design smells funny" train. Normally, you override a method so that it works properly for that specific subclass. If you have code in your parent class that is shared across multiple subclasses, perhaps that code could be moved to a non-overridden method so that it is readily accessible by all children/granchildren/etc.
Could you perhaps flip your design over and use more of a template method approach? (http://en.wikipedia.org/wiki/Template_method_pattern)
The notion behind Template Method is that you have some algorithm in your parent class and you can fill in the pieces that need to be class specific by polymorphic calls into your subclasses. You don't have a ton of detail in your question, but by the sounds of things, I'd really take a good look at your design and see if it makes sense.
Why don't you have func() be not inherited (call it funcBase() or whatever) and then add a wrapper func() function that calls it?
class A{
public void funcBase() {
// Base implementation
}
public void func() {
funcBase();
}
}
class B extends A{
public void func(){
super.func();
}
}
class C extends B{
public void foo(){
super.func(); // Call B's func
funcBase(); // Call A's func
}
}
I have no idea what you're trying to do, but it sounds like your class design is not appropriate for what you want, so you may want separate functions in A instead of trying to sneak your way up the ladder.
This example is the only way to call a "grandparent" super method.
class A{
public void foo(){ System.out.println("Hi"); }
}
class B extends A{
public void foo(){ super(); }
}
class C extends B{
public void foo(){ super(); }
}
This would be a different story if B doesn't override foo().
Another option would be to have a "protected helper" method in the middle class.
class D{
public void foo(){ System.out.println("Hi"); }
}
class E extends D{
public void foo(){ System.out.println("Hello"); }
protected void bar(){ super.foo(); }
}
class F extends E{
public void foo(){ super.bar(); }
}
You can access the superclass methods from within the subclass itself, e.g.
class A {
void foo() {...}
}
class B extends A {
void foo() {...}
void defaultFoo() { super.foo(); }
}
However, you really shouldn't be exposing overridden methods this way, you should write B.foo() in such a way that works fine for A and B. This is where it is a good idea to use super.foo(); like this:
class B extends A {
void foo() {
super.foo(); //call superclass implementation first
... //do stuff specific to B
}
}
Update: In response to your comment on trying to access the implementation 2 levels up, here's a way of doing it.
class A {
void foo() {
defaultFoo();
}
protected void defaultFoo() { ... }
}
class B extends A {
void foo() {...}
}
class C extends B {
void foo() {
defaultFoo();
... //do other stuff
}
}
This is a healthier pattern of coding what you want to do.
You should probably rethink how you are handling your class hierarchy if you need to place a call to a function that is defined two levels up the hierarchy. Consider writing new methods that are implemented by each subclass in a different way.