I know following cyclic inheritance hierarchy is not allowed in Java. Compiler throws an error, but what I'm really interested is knowing the exact reason for the compilation failure.
class A extends B{}
class B extends C{}
class C extends A{} // this will give you compile time error.
What is the thing due to which the compiler will throw an error, the moment I write the code class C extends A{}
Such relation is simply not possible. It defines an infinite recursive class. In order to define class C, you need class A, to define class A you need class B, and to define class B you need class C - and you are back to the starting point. This goes on infinitely so compiler can't do this and it also has no logical meaning.
Just look at the word extends, in Java a child class really extends its super class. It means child object is all of its super object plus some new members and some specified members.
So how can
A be an extension to B
B be an extension to C
C be an extension to A
?
We can say extension is an Order Relation so:
A extends B means A < B (and even not A <= B), and then in your case B < C, so it is obvious C can not be less than A.
There is simple a very practical problem (besides the logical problems which are explained in the other answers):
The classes must be initialized during instantiation. This is done in Java by initializing the superclass first. When you have a cycle the initialization code goes up the inheritance ladder and tries to initialize the superclass which is never reached...
Therefore for Java this must be forbidden.
We can reduce the problem to these statements since C IS-A B :
class A extends C{}
class C extends A{}
Obviously it is a conflict and thus the compiler gives that error.
Let's abstract out the concept of inheritance to family trees. Essentially, this is what they boil down to. I'll use the reverse mapping scheme here, so I'll work my way from C to A.
You inherit certain attributes from your mother.
Your mother inherits certain attributes from her father.
Your grandfather can be considered the highest in the inheritance chain.
In Java, this results in:
C inherits from B.
B inherits from A.
A is the highest object in your inheritance chain.
Taken to logical extremes, this would include multiple inheritance, a feature that is not supported in Java, yet can be mitigated through the use of interfaces.
What your inheritance scheme says is that the grandfather inherits directly from the grandchild, which makes no sense.
Cyclic Inheritance can have two examples:
1. Class A extends A { } :- This does not make any sense because members of class A are already present in class A then why to extend.
2. Class A extends B { } and Class B extends A { } :- In this case, members of both the classes can be written in one class then why to write two classes and extend each other.
Since above usecases are not-valid hence Java does not support Cyclic Inheritance.
I thought that I would add an as-of-yet unstated Java specific answer to this thread. In Java, every class must ultimately be derived from the Object class. That's why every object can be casted to an instance of Object without issue. To support this fact, the Java Inheritance Tutorial states:
Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object.
Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object.
If cyclic inheritance dependencies are allowed, and because classes in Java must have exactly one direct superclass (see above), then instances of classes in any cyclic dependency chain (e.g. instances of your classes A, B, and C) could not be inherited from Object, which is not permitted. So none of these cyclic dependency objects could be treated as Objects. Thus, the compiler must forbid cyclic dependencies.
Related
In Java file, suppose there are 2 classes - Class A & B, we can create a object of class A in Class B and can call methods of Class A. So then why we need to inherit Class A like "Class B extends A" as we can call class A methods by creating object of A in Class B ?
Think about the real world: a Dog is a Mammal. It doesn't contain one! In such situations it can make more sense for Dog to extend Mammal.
One key use case is that the base class implements certain behaviors (methods) that a child class needs to have, too. Then inheritance is one possible solution.
But you are correct in the sense that composition is often preferred over inheritance.
Also note: Java is a statically compiled language. Therefore it is really important to express such relationships on a type level. In contrast to dynamic languages, Java has no concept of declaring (at runtime): this object here has a quack() method, so let's assume the object is of type Duck.
I just had an interview, and I was asked a question.
Interviewer - Does Java support multiple inheritance?
Me - No
Interviewer - Each class in Java extends class Object (except class Object) and if we externally extend one class like
Class A extends B{
// some code here
}
then you can say that class A extend class B and class Object, which means it is multiple inheritance. So how can you say Java does not support multiple inheritance?
Me - Actually class B extends class Object, so when you extend class B in class A then class A extends class Object indirectly. This is multi-level inheritance, not multiple inheritance.
But my answer did not satisfy him.
Is my answer correct? Or where am I wrong?
What actually happens internally?
My answer is correct?
Yes, mostly, and certainly in the context you describe. This is not multiple inheritance:
It's what you said it is, single inheritance with multiple levels.
This is multiple inheritance: Inheriting from two or more bases that don't have any "is a" relationship with each other; that would be inheriting from unrelated lines, or from lines that had previously diverged (in Java, since Object is always a base, it would be the latter):
(Image credits: http://yuml.me in "scruffy" mode)
Internally What happens actually?
Just what you said: There are multiple levels. When the compiler is resolving a member on an instance:
obj.member
...it looks to see if the type of obj (which in this case is a class, say ClassB) has member, either because it provides it directly or it has it through inheritance. At runtime, the JVM uses the member the object actually has.
The reason I said "mostly" above is that Java has interfaces, and as of Java 8 it has "default methods" on interfaces. This complicates things a bit, but your answer about levels is correct in the context of what you described the interviewer saying about Object, ClassA, and ClassB.
Interfaces have always made it possible, in Java, for something to have an "is a" relationship with two different types: A class type it inherits from, and any of several interface types it implements. Interfaces without default methods aren't multiple inheritance in a practical way (the class has to provide the implementation), but they did make it possible for a class to have multiple "is a" relationships from unrelated type trees. (I'm not an academic, it's possible an academic would argue that they provide multiple inheritance in an academic way.)
With Java 8, interfaces can provide default implementations of the methods they define, which really blurs the lines even at the practical level. Let's look at that a bit more deeply:
Say we have ClassA:
class ClassA {
void doSomething() {
// Code here
}
}
and Interface1:
interface Interface1 {
default void doSomethingElse() { // Requires Java 8
// Code here
}
}
and finally ClassB:
class ClassB extends ClassA implements Interface1 {
}
ClassB inherits the implementation of doSomething from ClassA. But it also gets the "default" version of doSomethingElse from Interface1. We didn't implement it in ClassB, but ClassB isn't abstract: It really has doSomethingElse. It gets it from the interface. I used the word "gets" rather than "inherits" there, but this looks a lot like inheriting the default method.
This is basically multiple-inheritance "light" (as in "light beer"). It does an end-run around the thornier problems with true multiple inheritance, like:
What should the type of super be? (Java 8's answer: ClassA)
What order do you run constructors in? (Java 8's answer: Single-lineage constructor chaining, interfaces don't have constructors.)
Do you run constructors that you inherit more than once, more than once? (Java 8's answer: You can't inherit constructors more than once, interfaces don't have them.)
What happens if you inherit multiple methods with the same signature? (Java 8's answer: If one of them is from the base class, that's the one that's used; a base class's implementation can override the default method of multiple interfaces. If you have multiple default methods with the same signature from different interfaces at compile-time, it's a compile-time error. If an interface has been changed without the class being recompiled and the situation arises at runtime, it's a runtime IncompatibleClassChangeError exception listing the conflicting default methods.)
you are correct
First of all, Object class is the super/base/parent class of every class including user-defined classes.
So even if we don't mention it explicitly, the user-defined classes extends Object class by default.
its like
class A
class B extends A
but compiler read it as
class A extends Object
class B extends A
proved
for more detail check this java documentation for inheritance
My answer is correct?
You are absolutely correct in saying that it is multi-level inheritance and not multiple inheritance.
Only the root of the hierarchy is Object, all classes don't individually extend Object.
A counter to the interviewer:
If all classes extend Object, then how many times constructor of Object will be called on A a = new A();
The answer is only once, and that will be for the root of the hierarchy.
Multiple inheritance and class Object
Yes, you are correct... as many others have pointed out. I just wanted to say that interviews are not only about technical knowledge, it is also about sticking to your guns. Some interviewers will question your answer, not because they want to know if you are sure of your convictions but also to test how well you can teach others and how well you handle an authoritative figure.
For the first point, if you can't teach others then you can't be a mentor. Nowadays it is crucial to hire someone who can coach junior developers.... because it makes sense economically.
For the second point, because they don't want you changing technical aspects just because your boss asked you to. If your boss asks you to remove all indexes from the database because they take up too much space, would you do it? Would you try to convince your boss otherwise? How?
Does java support multiple inheritance?
Yes for interfaces but not for classes.
The class and interface can implements many interfaces but extends only one class
Your answer is correct !
class Object //for illustration purpose
{
}
class B
{
}
class A extends B
{
}
When you create an object of class A, constructor chaining happens.
i.e. the constructor of class A calls super() implicitly and hence the constructor of class B is invoked, which then calls its super class implicitly which is the Object class.
In java, a class extends only a single class because the constructor of that class only call one super class constructor. This is not true in case of Interfaces since they do not have constructors.
Also when an object of class A is created, and assume that you have defined the constructors of both classes A and B, then constructor of class B is executed first and then the constructor of class A.
Your answer is perfectly alright. You can explain interms of multilevel inheritance support from Object class in java
Your answer is right, because java doesn't support multiple inheritance from classes. Java supports multiple inheritance from interfaces, and there is no any other inheritance. But you can use composition of classes, but that's another story.
What a dumb question.
Of course Java doesn't support multiple inheritance, and interfaces are not inherited.
Inheritance only happens via "extends", not via "implements". When you define a class implements several interfaces you are not saying it will be an extension of those interfaces, but it will have the same behavior, and behavior (at least in Java), doesn't define inheritance.
For Java to support multiple inheritance, it would need to support something like
public class MI extends Object, MyOtherClass
Which Java can't.
Well, maybe I wouldn't get the job for calling the interviewer's question dumb :)
Your answer is absolutely correct.
These types of questions asked just to check whether a candidate is conceptually strong or not.
Well the simplest and precise answer to this question is here:
"Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object."
Please refer this link
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The answer you gave is correct. The interviewer was wrong:
Internal process
if suppose Class A Doesn't extends any other class
then ---> Class B extends java.lang.Object
then ---> Class A extends B
then class A also inherited the property of java 'Object' class...
so,Java doesn't support multiple inheritance.
If you want to verify this process just generate 'javadoc' for your class A and verify the results.
This question already has answers here:
Java : If A extends B and B extends Object, is that multiple inheritance
(11 answers)
Closed 8 years ago.
Actually the question was asking by one of the interviewer
Que: How can you say that java is not supporting multiple inheritance?
If Object class is a parent of all classes in java.
I have no answer of that question.
That means no clear idea about java concepts :-(
Ex:
if A extends B
And here A is already extending Object class. right?
Now how its works?
Please share your answers..
Multiple inheritance is about multiple-direct-inheritance.
A single class class can't have two immediate parent classes. It can have a grandparent class, though.
A extends B and B extends C, is not the same as A extends both B and C.
The reason this is disallowed is for simplicity when you have a case like:
A extends both B and C
B extends D
C extends D
If you had such a case, and then you had this code:
A a = new A();
a.someAbstractOrVirtualMethodOnD();
... are you talking about the B implementation of someAbstractOrVirtualMethodOnD(), or the C implementation of that same method? Which should get called? (Hint: there isn't a great answer)
So, Java bans it.
Note, you can get something much like multiple inheritance if you implement multiple interfaces. But since there is only one concrete implementation, there is no confusion as to what gets called.
On the top of all to keep the language design simple
And the example from the blog I follow regularly.
1)We have two classes B and C inheriting from A.
2)Assume that B and C are overriding an inherited method and they provide their own implementation.
3) Now D inherits from both B and C doing multiple inheritance. D should inherit that overridden method, which overridden method will be used? Will it be from B or C?
Here we have an ambiguity.
Any ways to overcome this we have interfaces and Multilevel inheritance.
Edit :
And here A is already extending Object class.
That is never called as Multiple inheritance.That is called Multi level inheritance.
In Multi level ,
Many classes are involved in inheritance, but one class extends only one. The lowest subclass can make use of all its super classes' contents.
Multiple inheritance means a single class can inherit from multiple classes. In other way, it can have multiple parent classes.
For Object class example cited by the interviewer, there are two possibilities:
The interviewer himself is confused about multiple parent class(multiple inheritance) and multiple child class.
Or he is trying to trick you using that question
A parent class can have many child classes and that does not relate to multiple inheritance.
Have a look at this StackOverflow answer: https://stackoverflow.com/a/9790475/2619912
Your class that extends that other class, but it extends Object, too, so you're still in one line of inheritance, not two.
This is a common misconception with Java.
The way multiple inheritance works (in C++ and Python) is something like this.
Parent1 Parent2 Parent3
| | |
_______________________
|
v
Child
It means that Child will inherit the attributes and methods from all the parents.
However, in Java, inheritance works like this.
Object
|
v
Child1
|
v
Grandchild
So, object is the superclass of all classes, but it is not the immediate parent of all classes. Java does, however provide a way to somewhat implement multiple inheritance by the way of Interfaces
Object
|
v
Child <--- Interface
|
v
Grandchild
Now, Grandchild will inherit methods from Child which, in turn is obligated to implement the methods defined in the interface [Unless it is an abstract class, but that is separate discussion altogether]
So, Object is the ancestor of all classes, but it is not the parent of all classes, and Java, therefore does not support multiple inheritance.
Multiple inheritance is where a single class can extend from multiple classes. That is not possible in java. See here: http://en.wikipedia.org/wiki/Multiple_inheritance
When you do class A extends B in Java, then A extends B only, and not Object. B in turn extends Object (or whatever else, which will eventually extend object)
The only resemblence of mutiple inheritance in java is Interfaces.
A class can implement multiple interfaces.
Object class is not an example of multiple inheritance. May be you misinterpreted the question.
The answer is Java supports multi-level inheritance but not multiple inheritance.
Please refer this : http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
In case of Object class to other classes its not actually multiple inheritance ... As said , its where a single class can extend from multiple classes ..
A java class can only be a direct child of a single parent class. It can have a grandparent but no second parent.
It is like having a single biological mother. You cannot have more than one biological mothers, sure you can have a grandmother.
Let there be a class A and class B.
Now we define a class Derived.
Multiple Inheritance means: class Derived can inherit both class A and class B.
But this is not possible in Java. Hence it does not support Multiple Inheritance.
Que: How can you say that java is not supporting multiple inheritance? If Object class is a parent of all classes in java.
Object is ancestor of all classes (father, grandfather, great grandfather, etc.) but every class has only one father (if not specified, it's the Object class).
Multiple inheritance should allow a class to inherit multiple parent classes. But Java doesn't allow this since it might create Diamond problem
Regarding Object class being parent, and then having many classes in inheritance hierarchy, its termed as Multi level inheritance
Sidenote:
C# allows multiple inheritance by interface by allowing child to implement multiple parent type's methods separately even though they have same signature
First case: Suppose you create a class A without using inheritance. By default, it is derived from Object class.
Second case: Suppose you create the class B that extends class A. Class A contains all the fields from Object class, so class B will also contain them through inheritance. It is
class B extends A(which extends Object), so you could say that B is a subclass for A and also for Object.
So if I write the following code in Java:
public class A extends A{
public static void main(String[] args){
}
}
This gives a compiler error message cyclic inheritance involving A.
The same happens if I write two classes A and B and A inherits B and B inherits A.
This makes sense to me, as it is quite hard to imagine how this would be possible anyway.
I then asked about this from one of the professors at my uni. He said there are languages where this is possible and he lamented how this is not possible in Java and that he had done some projects where he had used cyclic inheritance and so on, but I couldn't really understand any of it. He also mentioned he had had problems where he would have liked to use cyclic inheritance.
Can you educate me on the possible uses of this strange phenomena of cyclic inheritance? When is it possible and how? Are there problems where this could be useful?
I dug up this interesting reference: basically it says that cyclic inheritance is valid as long as there are no repeated fields, as the lookup for any field just needs to traverse one loop of the cycle to find out a meaning. If a field is repeated then none of the two definitions is more valid than the other and apparently there would be a problem.
So suppose that you want to define a person as a human and as a voter, and set different attributes for each. In pseudo-code:
class Person extends Human:
String name;
class Human extends Voter:
String language;
class Voter extends Person:
Country residence;
Now you can address different aspects of an individual without having to define a hierarchy, and you might instantiate different people as a Person (with name), a Human (that speaks a language) or a Voter (in a particular country). No aspect is more important than the other.
While interesting, I don't think it is practical to use outside of research projects. Imagine having constructors for all classes that pass parameters to the super() constructors -- it would be easy to mess up the whole construct.
Update: the given pseudocode does not compile when translated to Java 8, and apparently under any language (except Cecil as shown by the link given above). It seems that nobody found any valid uses and therefore disallowed cyclic inheritance. This does not mean that the concept is inherently impossible; just that the practical uses do not justify the effort implementing the special case.
I could only see it possible if the classes were on the same level of hierarchy. Think of the class hierarchy as a tree, which it is. Java looks for the hierarchy to be at least one level above or more. In some languages, you would be able to inherit characteristics from a class on the same level as the class you are using.
I don't get the sense of cyclic inheritance. I don't know why your professor thinks it's useful in anycase mind that the inheritance reation that is called IS-A relationship states that if B is a subclass of A then B IS-A A in the sense that everywhere an A is required then a B can be used without problem (Liskov substitution principle).
Now, theoretically, if A is a subclass of B and B is a subclass of A then then both classes must have exactly the same outside interface. This because if you add a method to any of them the other one will inherit the same method automatically so you will have either to override it either to get the other implementation.
In addition you will have many circumstanced in which odd side effects comes into play (think about method A.foo() calling super.foo() and B.foo() calling super.foo(). I don't see any practical reason because this should be allowed.
Inheritance is intended as a tree in which every subclass specifies the behavior or the classes that are up in the tree, having two classes at the same level doesn't mean anything useful.
I disagree with the accepted answer that states that their code will not throw an error. I am running Java 8 and compiled the following code:
class Person extends Human:
String name;
class Human extends Voter:
String language;
class Voter extends Person:
String residence;
and I recieved an error stating "error: cyclic inheritance involving Person."
Therefore, in Java you can not have cyclic inheritance.
Cyclic inheritance is of no use and moreover let us see why logically it is not allowed.
I would like to start with Object class, if a class doesn't extend any class it extends Object class (this is true), and if a class extends any other class indirectly extends the Object class.
Example:
class B
{
..//
}
class A extends B
{
...//
}
class A extends Object, because B class extends Object class.
So when we do Cyclic Inheritance, it never extended the Object class.
Example:
class A extends A
{
}
I hope I was clear, so and a class that cannot extend Object class that is not possible in Java.
I am curious as to how the concept of "inheritance" takes place in the world of object oriented programming. Let me explain my dilemma (I came across this dilemma while studying Java but I hope that my question is generic in nature) :
Suppose there is a class A and a class B. Class A "inherits" Class B. What does this actually mean? Does the compiler make a "new" class, which is THEN instantiated into an object which contains the elements of both the classes A and B behind the scenes? If that's the case, then how are the access restrictions implemented according to the access specifiers?
For a moment, I wondered if it happens in the following manner :
An object of class A is created and then an object of class B is created. Java then somehow "link" the members of A to the members of B and make it appear as if they belonged to the same class and it does that according to the access specifiers.
But then, it occurred to me that there is a fault with this theory. Suppose two different classes, B and C are inheriting class A. Then, if we are going to make objects of class B and class C, then they'll have their OWN copies of the elements of class A. So this theory fails too.
I was just trying to explain the confusion about inheritance that I have in my mind. It's giving me headache. Please help.
EDIT : This is a link to a discussion related to my question which i found on this site.
Do subclasses inherit private fields?
I may fail, but I'm going to take a stab at an explanation on this for you.
In honesty, I think you may be making what is really a very classic mistake in how you conceive object programming - and that's making the distinction between objects and classes. Object creation in virtually any object-oriented language is one of construction based on a class definition. From your question, it sounds as though you are mentally modeling an OO language in general and object inheritance in particular as aggregating discrete objects, where in reality the objects are being defined in terms of aggregated class definitions.
public class A
{
public A();
}
public class B:A
{
public B();
}
public class C:B
{
public C();
}
In your A->B->C model, C's definition is in terms of its own unique properties plus all the members of its immediate ancestor, B, which, in turn, is defined in terms of its own unique properties plus all the members of its immediate ancestor, A. The process of creating the object is still a unique and discrete event, and the object, despite its multi-layered heritage, is still only one object at instantiation time.
Regarding the visibility of certain members: When a class author designs and builds a class, he makes certain decisions about what he makes available in two distinct perspectives: that which is exposed to consumers of the class, and that which is exposed or available to subclasses. Members and fields declared private are every bit a part of descendant classes, even if they are "contractually" forbidden to be accessed by subclasses. You could make a crude analogy that a TV has a "public" interface of an on/off button, volume control, and color controls, but has "internal" controls not intended for the consumer such as the internal electronic components, or the power supply. They're still very much there even though they are not "visible" or "available" to consumers or subclasses.
Now, that said, there are constructs in most OO languages that reflect the properties you describe - multiple objects - and that involve a design pattern known as Composition (or, sometimes, Aggregation. This is where a class isn't derived from an ancestor class - typically because the class is declared "sealed" (C#) or "final" (Java) (or other designation that prohibits inheritance). That forces a developer interested in using the class to make it a member of another class, such that when the an object of the class is instantiated, you DO have discrete objects of both classes.
You might have the following:
public final class InterestingThing
{
//definitions
public InterestingThing()
}
public final class MyThing
{
InterestingThing _interestingThing = new InterestingThing();
public MyThing()
}
This is very much the kind of scenario you were describing in your original question, in which the creation of MyThing implies the distinct creation of an InterestingThing. Keep in mind, too this structure is generally forced by the design and definition of the original class of interest.
Ultimately, objects are defined by their classes, and multiply-inherited classes are still just a class, but in a refined, hopefully increasingly robust, hierarchy based on good, incremental object design.
I hope, in some way, this explanation helps to answer your question.
Class A "inherits" Class B. What does this actually mean?
If class A extends class B, it inherits all members (fields and methods) of B, i.e. class A will have these members even through they are not declared in the body of class A.
Whether class A is permitted to access a particular member is an unrelated matter.
An object of class A is created and then an object of class B is created. Java then somehow "link" the members of A to the members of B and make it appear as if they belonged to the same class and it does that according to the access specifiers.
No. A single object of class A is created. That object just happens to have all inherited members, too. For instance, if you have:
class B {
private int x;
}
class A extends B {
private int y;
}
The runtime will store, for every object of class A, the value of x and the value of y.
That code in class A does not access the value of x is enforced by verifying that the source code of A does not use the name x upon compilation, and by verifying that the bytecode of A does not refer to the field x upon loading the class at runtime. Put differently, access modifiers are independent of memory layout.