Multiple Inheritance :Java vs C++ - java

Recently ,after reading some articles in Programming Languages and Practice book ,it is mentioned that multiple interface inheritance in Java does not suffer from the same problems as multiple class inheritance in C++.
But I can't understand why this happens. How java is able to use multiple interface inheritance while in C++ implementation errors exists ??
Is there a way to replace multiple inheritance in C++ as to avoid implementation problems ??
For the last statement to be more specific ,lets say that we have:
class A {...};
class B : public A {...};
class C : public A {...};
class D : public B, public C {...};
Then class D inherits class B,C which both inherit class A. So if A had a field-variable then B,C would have the same variable name ,then what variable would D has (inherited from B or C) .To avoid this could we write the above code without multiple inheritance but with similar results?
The question is not a duplicate since it is not focused on what finally will be the inheritance in the example ,but to understand the difference between Java-C++ multiple inheritance(see the first question above) and also if there is a way suggested to overcome some multiple inheritance problems (like the above).

Java (unlike C++) does not allow multiple inheritance of state and, therefore, does not suffer from a diamond problem.
It allows multiple inheritance of type through interfaces (a class can implement multiple interfaces).
Starting with Java 8 there is also multiple inheritance of behavior through default methods in interfaces.

But I can't understand why this happens. How java is able to use multiple interface inheritance while in C++ implementation errors exists???
That is possible because Java does not allow multiple inheritance, but only multiple implementation from multiple interface.
Implementation is different than inheritance.
The general problem with multiple inheritance is (in short) that two classes may define different ways of doing the same thing, and the subclass can't choose which one to pick.
Since interface in java can only declare the signature of methods without implementing them, the problem does not exists if multiple interface are derived.
In conclusion, in order to avoid the problem Java forbids directly multiple inheritance, and allows only multiple implementation of interface.
Is there a way to replace multiple inheritance in c++ as to avoid implementation problems???
The first suggest I can give you is to avoid a design so complex.
Anyway the problem you've exposed in your question is very common and known as diamond problem.
C++ provides a solution in order to solve that problem with the usage of virtual inheritance.
Let an inheritance graph:
A
/ \
B C
\ /
D
This is the problem:
C++ by default follows each inheritance path separately, so a D object would actually contain two separate A objects, and uses of A's members have to be properly qualified.
And this is a briefly explanation about the virtual inheritance:
If the inheritance from A to B and the inheritance from A to C are both marked "virtual" (for example, "class B : virtual public A"), C++ takes special care to only create one A object, and uses of A's members work correctly. If virtual inheritance and nonvirtual inheritance are mixed, there is a single virtual A and a nonvirtual A for each nonvirtual inheritance path to A.
In short, with virtual inheritance you prevent the part class A is duplicate in the class D.

To avoid this could we write the above code without multiple inheritance but with similar results?
It follows a minimal, working example:
struct A {};
struct B {};
struct C {};
struct D {
operator A&() { return a; }
operator B&() { return b; }
operator C&() { return c; }
private:
A a;
B b;
C c;
};
void f(const B &b) {}
int main() {
D d;
f(d);
}
If you don't want to create an explicit hierarchy, but still you would like to use an instance of D where a reference to B is required, the solution above works just well.
It is based on composition instead of inheritance, as you can see.
It has some limits, of course, as an example you cannot cast a pointer to D to a pointer to B.
If it fits your requirements mostly depends on the real problem, so I cannot say.
Anyway, that's is a viable solution somehow similar to the inner class idiom, if you are interested in having further details.

The "multiple inheritance" in Java is no real multiple inheritance. Since Java can only create the diamond problem by using interfaces.
Interfaces are only a reference to an implemented method in the sub class, because an interface cannot implement a method.
So the child class cannot have parents with different implementions. It doesn't matter from which interface you inherit the method, since no implementation exists.
Edit: oh I forgot how Java destroyed the principle behind interfaces by introducing default methods...

Related

How interfaces in java used for code reuse? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am learning java, and came to know that Java doesn't support multiple inheritance. So, java introduced interfaces for that. How does the problem of multiple inheritance is solved by interface?
What I read online : "Inheritance in java means code reuse".
If i implement an interface in class say A, I will have to give my own implementation for it in A, and same in B, which means methods in interface (say I) will have different implementation in A and B. How does it use the code re-usability feature?
You haven't given proper citations for any of the assertions that you make in your Question, so it is impossible to know what they are actually saying ... or why you think that they are say these incorrect or misleading things.
I am learning java, and came to know that Java doesn't support multiple inheritance.
That is correct.
So, java introduced interfaces for that.
That is INCORRECT. Java introduced interfaces to support polymorphism. Specifically polymorphism that does not depend on class inheritance.
How does the problem of multiple inheritance is solved by interface?
It isn't.
Multiple inheritances are about inheritance of method and field declarations from multiple parent classes. Interfaces does not provide that, and it does not solve the problem.
Interfaces do allow you to declare a common API (or APIS) and implement that API without necessarily sharing code. But with careful design you can do code-sharing under the hood any; e.g. by using the Delegation design pattern.
What I read online : "Inheritance in java means code reuse".
I doubt that what it actually said. Anyway, it is INCORRECT.
Inheritance (of classes) is one way to achieve code reuse, but it is only one of many ways to achieve reuse. There are many others.
If i implement an interface in class say A, I will have to give my own implementation for it in A, and same in B, which means methods in interface (say I) will have different implementation in A and B.
I presume that you mean something like this:
public interface I {
void someMethod();
}
public class A implements I {
void someMethod() {
// some code
}
}
public class B implements I {
void someMethod() {
// some code
}
}
How does it use the code re-usability feature?
There is no code reuse in that example. But this is not inheritance of classes (which I described as one way to achieve code reuse). It is a class implementing an interface.
(Now in Java 8, you can put code into interfaces in certain circumstances; read up on the default methods feature. And that does allow direct code reuse via an interface. But I doubt that is what the sources you have been looking at are talking about.)
Java solved the problem of multiple inheritance (or rather the problems that come with this feature) by allowing single inheritance, that is allowing only one super class. This design created a new problem of a class that needs to implement multiple contracts. a contract, like is explained in #Kermi's answer, allows other objects to refer to the same Object as different types, for various purposes, the most common one is for storing in Collections. an interface can be regarded as a super class that has no implementation (all the methods are pure virtual if you like)
So, Java removed the problems that come with multiple inheritance (the famous diamond problem) but also the advantages that come with it such as code reusability. This design follows the principal of making Java simple and easy and predictable by removing "advanced" (some say confusing) C++ features like multiple inheritance, operator overloading, pointer manipulation (among others).
There are several technics that allow Java to restore most of the code reusability of multiple inheritance. One such technic is composition: so if we take #Kermi's example, you can have a GeneralAnimal class that implements the most common behavior of an Animal. every Dog instance holds a reference to a GeneralAnimal instance (obtained through ctor or factory or dependency injection or ...) and can delegate some messages (=method calls) to that instance. The same is done in Cat instances and so on.
Interface doesn't resolve multiple inheritance problem or rather it doesn't create a multiple inheritance problem. It gives you a possibility to reuse existing implementations.
For example:
class Dog implements Comparable<Dog>, Animal
As your class implements 2 interfaces you can use them in difeerent ways. To use TreeSet object needs to implement Comparable methods (it is not the only possibility). When Dog is passed to TreeSet implementation of that structure is then sure that object has compareTo(Dog dog) method and can use it.
But than you want to store a List of Animals, and than iterate through that list with execution method declared for Animal, than you would not use Comparable interface, but Animal.
List<Animals> animals = new ArrayList<>();
animals.add(dog);
animals.add(cat);
for (Animal animal : animals) {
animal.walk();
}
Interface is a criterion, I think.
A and B should conform to it. In addition, A and B do different things such as ArrayList and LinkedList.
"Inheritance in java means code reuse" is right, but Interface is not. It embodies a norm.
When you learn Collections, you will understand it clearly.

Why is the diamond case with its common ancestor used to explain Java multiple inheritance issue, instead of two unrelated parent classes?

This question might sound weird to Java people but if you try to explain this, it would be great.
In these days I am clearing some of Java's very basic concept.
So I come to Inheritance and Interface topic of Java.
While reading this I found that Java does not support Multiple Inheritance and also understood that, what I am not able to understand that why everywhere Diamond figure issue(At least 4 class to create diamond) is discussed to explain this behavior, Can't we understand this issue using 3 classes only.
Say, I have class A and class B, these two classes are different (they are not child class of common class) but they have one common method and they look like :-
class A {
void add(int a, int b) {
}
}
class B {
void add(int a, int b) {
}
}
Ok,Now say if Java supports Multiple inheritance and if there is one class which is the subclass of A and B like this :-
class C extends A,B{ //If this was possible
#Override
void add(int a, int b) {
// TODO Auto-generated method stub
super.add(a, b); //Which version of this, from A or B ?
}
}
then compiler will not be able to find which method to call whether from A or B and that is why Java does not support Multiple Inheritance. So is there any thing wrong with this concept ?
When I read about this topic I was able to understand Diamond issue, but I am not able to understand why people are not giving example with three class (If this is valid one, because we used only 3 classes to demonstrate issue so its easy to understand by comparing it to Diamond issue.)
Let me know whether this example does not fit to explain issue or this can also be referred to understand issue.
Edit:
I got one close vote here stating that question is not clear.
Here is main question :-
Can I understand Why "Java does not support Multiple Inheritance" with 3 classes only as described above or I must need to have 4 classes (Diamond structure) to understand the issue.
The problem with diamond inheritance is not so much shared behaviour but shared state. As you can see, Java in fact has always supported multiple inheritance, but only multiple inheritance of type.
With only three classes the problem is resolved relatively easily by introducing a simple construct like super.A or super.B. And while you're only looking at overridden methods, it indeed doesn't matter whether you have a common ancestor or just the basic three classes.
However if A and B have a common ancestor, the state of which they both inherit, then you're in serious trouble. Do you store two separate copies of the state of this common ancestor? That would be more like composition than inheritance. Or do you only store one that is shared by both A and B, causing strange interactions when they manipulate their inherited shared state?
class A {
protected int foo;
}
class B extends A {
public B() {
this.foo = 42;
}
}
class C extends A {
public C() {
this.foo = 0xf00;
}
}
class D extends B,C {
public D() {
System.out.println( "Foo is: "+foo ); //Now what?
}
}
Note how the above wouldn't be so big a problem if class A didn't exist and both B and C declared their own foo field. There would still be a problem of clashing names, but that could be resolved with some namespacing construct (B.this.foo and C.this.foo maybe, as we do with inner classes?). The true diamond problem on the other hand is more than a naming clash, it's a matter of how to maintain class invariants when two unrelated superclasses of D (B and C) share the same state they both inherit from A. This is why all four classes are needed to demonstrate the full extent of the problem.
Shared behaviour in multiple inheritance doesn't exhibit the same problem. So much so that the recently introduced default methods do exactly that. This means that multiple inheritance of implementations is allowed now too. There is still some complication around the resolution of which implementation to call but since interfaces are stateless, the biggest bugbear is avoided.
Java does not support multiple inheritance because the designers of the language designed Java this way. Other languages like C++ support multiple inheritance just fine, so it is not a technical issue but just a design criteria.
The problem with multiple inheritance is that it is not always clear which method from which class you are calling to, and which instance variables you are accessing to. Different people interpret it differently and the Java designers believed at that time that it was better to skip multiple inheritance altogether.
C++ solves the diamond shaped class issue with virtual inheritance:
Virtual inheritance is a technique used in object-oriented
programming, where a particular base class in an inheritance hierarchy
is declared to share its member data instances with any other
inclusions of that same base in further derived classes. For example,
if class A is normally (non-virtually) derived from class X (assumed
to contain data members), and class B likewise, and class C inherits
from both classes A and B, it will contain two sets of the data
members associated with class X (accessible independently, often with
suitable disambiguating qualifiers). But if class A is virtually
derived from class X instead, then objects of class C will contain
only one set of the data members from class X. The best-known language
that implements this feature is C++.
Contrary to Java, in C++ you can disambiguate which instance method to call by prefixing the call with the name of the class:
class X {
public: virtual void f() {
}
};
class Y : public X {
public: virtual void f() {
}
};
class Z : public Y {
public: virtual void f() {
X::f();
}
};
That is just one difficulty that you have to solve for multiple inheritance in a language. Since there exist languages that do have multiple inhertance (e.g. Common Lisp, C++, Eiffel), it is obviously not insurmountable.
Common Lisp defines the exact strategy for priorizing (ordering) the inheritance graph, so there is no ambiguity in the rare cases where it does matter in practice.
C++ uses virtual inheritance (I have not yet put the effort in to understand what that means).
Eiffel allows to specify exactly how you want to inherit, possibly renaming methods in the subclass.
Java just skipped multiple inheritance. (I personally think that it is difficult not to be insulting to its designers while trying to rationalize this decision. Of course, it is hard to think about a thing when the language you think in does not support it.)
The diamond problem with four classes is simpler than three classes problem described in the question.
The problem with three classes adds another issue that has to be solved first: The naming conflict caused by two unrelated add methods with the same signature. It's not actually hard to solve but it adds unnecessary complexity. It would probably be allowed in Java (like it is already allowed to implement multiple unrelated interface methods with the same signature), but there could be languages that simply prohibit multiple inheritance of similar methods without a common ancestor.
By adding a fourth class which defines add, it is clear that both A and B are implementing the same add method.
So the diamond problem is more clear because it shows the problem using simple inheritance instead of just using methods with the same signature. It is well known and probably applies to a wider range of programming languages, so the variation of it with three classes (which adds the additional naming conflict issue) doesn't make much sense and therefore hasn't been adopted.
Multiple inheritance is no problem if you find a sane solution to method resolution. When you invoke a method on an object, method resolution is the act of picking which class'es version of the method should be used. For this, the inheritance graph is linearized. Then, the first class in this sequence that provides an implementation of the requested method is chosen.
To illustrate the following examples of conflict resolution strategies, we will be using this diamond inheritance graph:
+-----+
| A |
|=====|
|foo()|
+-----+
^
|
+---+---+
| |
+-----+ +-----+
| B | | C |
|=====| |=====|
|foo()| |foo()|
+-----+ +-----+
^ ^
| |
+---+---+
|
+-----+
| D |
|=====|
+-----+
The most flexible strategy is requiring the programmer to explicitly choose the implementation when creating an ambiguous class, by explicitly overriding the conflicting method. A variant of this is banning multiple inheritance. If a programmer wants to inherit behaviour from multiple classes, composition will have to be used, and a number of proxy methods to be written. However, naively explicitly resolved inheritance conflicts has the same shortcomings as…
Depth first search, which might create the linearization D, B, A, C. But this way, A::foo() is considered before C::foo() although C::foo() overrides A::foo()! This can't be what we wanted. An example of a language using DFS is Perl.
Use a clever algorithm that guarantees that if X is a subclass of Y, it will always come before Y in the linearization. Such an algorithm will not be able to unravel all inheritance graphs, but it provides sane semantics in most cases: If a class overrides a method, it will always be preferred over the overridden method. This algorithm exists and is called C3. This would create the linearization D, B, C, A. C3 was first presented in 1996. Unfortunately, Java was published in 1995 – so C3 was not known when Java was initially designed.
Use composition, not inheritance – revisited. Some solutions to multiple inheritance suggest getting rid of the “class inheritance” bit, and instead propose other units of composition. One example is mixins, which “copy & paste” method definitions into your class. This is incredibly crude.
The idea of mixins has been refined into traits (presented 2002, also too late for Java). Traits are a more general case of both classes and interfaces. When you “inherit” a trait, the definitions are embedded into your class, so that this does not complicate method resolution. Unlike mixins, traits provide more nuanced strategies to resolve conflicts. Especially, the order in which traits are composed matters. Traits play a prominent role in Perl's “Moose” object system (called roles) and in Scala.
Java prefers single inheritance for another reason: If each class can only have one superclass, we don't have to apply complicated method resolution algorithms – the inheritance chain already is the method resolution order. This makes methods a bit more efficient.
Java 8 introduced default methods which look similar to traits. However, the rules of Java's method resolution make interfaces with default methods much less capable than traits. Still, a step in the direction of adapting modern solutions to the multiple-inheritance problem.
In most multiple inheritance method resolution schemes, the order of superclasses does matter. That is, there's a difference between class D extends B, C and class D extends C, B. Because the order can be used for simple disambiguation, a three-class example does not sufficiently demonstrate the problems associated with multiple inheritance. You need a full four-class diamond problem for that, as it shows how naive depth-first search leads to an unintuitive method resolution order.
The diamond problem that you cite is one reason (and a very good one) not to support multiple inheritance. There are other reasons too, which you can read a bit about here.
A lot of the reasons boil down to complexity (it's quite complex to do it right), the relatively rare legitimate need to use it, and all sorts of other problems with dispatching (aside from just the diamond problem) that it creates.

Is possible to support multiple inheritance through virtual?

I know that Java does not have any ability to support Multiple Inheritance. For an example, class C inherits all the properties from class A and class B then the compiler gets confused which method should be called which is defined in A and B. So, C++ supports multiple Inheritance and Java does not support.
I know that by using Interface can achieve this Multiple Inheritance in Java.
My doubt is, whats that Diamond problem and how could be solved in Java?
For an example, consider multiple classes such as A, B, C, D. Class B and Class C inherits the properties from Class A and class D inherits the properties from both class B and Class C. This is called as "Diamond problem".
How can we solve this Diamond problem in Java and when does this Diamond problem may occur exactly in coding?
I also referred that in C++ by using Virtual can achieve this Multiple Inheritance concept. And, Java is built and designed for simplicity !
What is that actual meaning of Virtual in C++ and how could be used in Java? Is it possible to achieve multiple Inheritance through Virtual?
I am Java Beginner and very sorry for this kinda question. But, I believe that can learn from my mistakes!
There is no concept of multiple inheritance in Java. Implementing multiple interfaces is possible, but this is not multiple inheritance.
Because there's no multiple inheritance, the "diamond problem" that arises in languages that do have multiple inheritance does not arise in Java. So there is no virtual keyword in Java - there's no need for it.
The designers of Java decided that the number of cases in which multiple inheritance is actually useful is so small that it wasn't worth including in the language. In approximately 15 years of programming Java, I have only once encountered a business problem in which C++-style multiple inheritance would have been useful. So I'm happy to say they were right.
If you want multiple 'inheritance', you need to implement multiple interfaces. Each interface declares abstract methods that the implementing class needs to provide definition for.
public class MyClass implements interface1, interface2, interface3{
// provide a definition to the abstract methods of interface
}
The 'diamond' problem in C++ is when a class inherits from two classes , both of whom have methods from a common grand parent. In Java, there is no diamond problem because you can never extend two classes; just one class and many interfaces.
You are combining far too many questions. I recommend that you split your post into separate questions.

Is "derived" in C++ the same thing as "extended" in Java?

As the title states: when I "derive" a class in CPP, that's pretty much the same thing as "extending" a class in Java, yes?
Yes. Since Java doesn't have multiple inheritance, it can be a bit more verbose with the language. Java's class D extends B is class D : public B in C++, but in C++ you can also have in­her­itances like struct D : B1, private B2, protected B3.
Similarly, in Java super refers to the (unique) base subobject, and understandably there is no com­par­able concept in C++ (you have to specify the base by name).
(Note that there's also implements in Java for dedicated interface classes. Since those have no mem­bers and only abstract functions, there's no need to refer to those interface bases from the derived (i.e. "implementing") class.)
Yes, they mean the same thing. Although, "derived" is not a keyword in C++ the way that extends is in Java, even though the C++ standard uses the word "Derived" to indicate the idea of a subclass. Inheritance in C++ is expressed using the : symbol, along with an optional access qualifier like public or private.
C++ inheritance is also slightly more complicated than Java inheritance, because multiple inheritance is supported, and as such virtual inheritance is also an option.

type conversion for user defined classes

I have a lot of classes which are basically equivalent, ie have almost the same functions in all respect. Let's call them A and B. There are hundreds of methods that are using A and now due to code changes I have to change them to B.
Is there a way by which I can program a mapping between A and B such that I have minimal code changes?
If A is not final, you can make B extends A, and have B's methods #Override A's. Then wherever previously you were invoking methods on an instanceof A, you now provide an instanceof B, and let dynamic dispatch handle the rest.
This is called polymorphism. It only works with non-static methods having the same exact signature. You can not #Override static methods.
See also
Java Tutorials/Object-Oriented Programming Concepts
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
Related questions
Why doesn’t Java allow overriding of static methods ?
On interfaces
Depending on why you were doing this, you should know learn the concept of interfaces and how they're used in object-oriented programming to allow precisely this kinds of flexibility and convenience.
Consider the interface List<E>, for example, and an implementation ArrayList<E>. If you wrote an entire library that works with an ArrayList<E>, doing all the usual add/addAll/remove etc, and now you must use a LinkedList<E> instead, then you'd have little choice but to go to the source code and change all the ArrayList<E> to LinkedList<E>, and hope that the change doesn't break another code which still assumed that ArrayList<E> was used.
If instead your library works with a List<E>, then switching to a LinkedList<E> need to be done only wherever the objects are created. All the other code that was doing the add/addAll/remove would've still worked just fine, since those are methods that are defined in the interface List<E> which all implementors will have.
It's not clear from the current context, but if A and B are so similar, then perhaps they belong to some type X. If so, you should consider defining interface X, and have A implements X, and B implements X.
See also
Java Tutorials/Object-Oriented Programming Concepts/Interfaces
Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces
Related questions
Is it just me or are interfaces overused?
Why are interfaces preferred to abstract classes?
Explaining Interfaces to Students
You should define an interface that both A and B implement.
Well, you should probably use inheritance in this case.
If you make B a subclass of A, you can use B wherever you had been using A without changing any of the code.
Sun/Oracle has some great tutorials on inheritance that you may want to take a look at in order to get started.
There are many ways, each with advantages and disadvantages. A couple ideas:
Make B a subtype of A. Then you can pass instances of B to methods requiring A. Alternatively, extract a common interface, and replace uses of A with that interface where possible (a good IDE can do this automatically).
In A, include the following constructor:
A(B b) {
// create an A with the data from b
}
or create an Adapter that subclasses A and delegates all calls to B.
In any case, if minimizing tedium in changing the code is your objective, look into your IDE's refactoring operations.
You can make A an adapter for B. I.e.
class A {
private B b = new B();
public String someMethod() {
return b.equivalentSomeMethod();
}
}
That's in case the methods are similar, and not exactly the same. If they are exactly the same - use your IDE to get rid of one of the classes and replace it with the other.

Categories

Resources