Related
Basically the question in the title but here a little more detail:
I have a set of classes you can create similar objects of (e.g. animals and I have the classes Tiger, Crocodile, Wolf etc. whatever you like). And the types of those objects are specified by the Supertype they are derived from. Now some objects might derive from multiple Supertypes, which obviously need to be implemented as Interfaces. But lets say I have a specific Supertype which I want each animal to only derive EXACTLY ONCE from (e.g. the animal family they belong to). Does this automatically mean that this Supertype should be an abstract class to ensure it can only be extended once in a Subtype?
Edit since Michael pointed out that my question is unclear.
This question is not about a specific piece of code it is more a theoretical question about types, maybe I should ask like this: Can and should an abstract class be used as a tool to ensure a Subtype of this Supertype can only derive it once. Lets say for my example with animals I have the Supertypes "Omnivore", "Herbivore" and "Carnivore" and I know an animal can only be exactly one of those, is this a valid reason to make those abstract classes and not interfaces?
If you have different exclusive categories then different base classes (abstract or not) is a sensible solution.
class HerbivoreBase implements Animal, EatsVegetables { ... }
class CarnivoreBase implements Animal, EatsAnimals { ... }
class OmnivoreBase implements Animal, EatsVegetables, EatsAnimals { ... }
It only makes sense when the classes have (differing) methods.
To look at other languages. Scala has case classes (the name says it all) with pattern matching.
Java also has (will have?) pattern matching based on classes, and instanceof as follows:
Animal animal = ...
if (animal instanceof Herbivore herbi) { ... herbi.eatVegy(...); ... }
else if (animal instanceof Carnivore carni) { ... carni.hunts(...); ... }
Java has also introduced a restricting mechanism to list which classes may be child of a given class, say abstract class Animal.
I would still like to mention, that modeling with inheritance can easily over-architect things, especially if later a change is needed, or the code becomes bloated.
Your question is more about "should I use an interface, or a class (and extend it)?"
Remember that a subclass has a relationship of is-a with its base class. A class has a relationship of has-a with an interface.
An interface define a behaviour that one class has (a car has 4 wheels) (remember also that an interface should define only one behaviour, related to the interface segregation principle, which says that it's better to have more smaller and specific interfaces than one general and bigger, so that classes can implements only needed behaviours), a superclass define a "more general" type (dog is an animal).
See for example:
If you have a MountainBike class, it will implement an interface Bike, or extend a class Bike? It will extend the Bike class, since mountain bike is a "sub-type" of bike.
If you have an Elephant class, it will implement an interface Trunk or extend a class Trunk? It will implement the Trunk interface, since trunk is a part (behaviour) of the elephant, not a "container".
An interface is a way to define signature of a method, but normally it does not define the implementation of a given method. If you want to implement a method in an interface, use the default keyword
interface inter{
public default void myMethod(){/*your code here*/
}
A class can implement multiple interfaces but cannot extend more than one class.
If you are using an abstract class you are can use the following two benefits
The abstract class cannot be initialized
The abstract class can implement abstract methods.
A subclass can still only extend one class, abstract or not.
Your question was: "If I want a superclass to only be derivable from a single subclass, which should I use? Interface or abstract class?"
By derivable, do you mean inheritance? Because if that's the case, then I think you got the question backwards. Subclasses inherit from the superclasses.
The child (subclass) inherits from its parent (superclass)
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.
Well this is allowed in java
ClassA extends ClassB implements InterfaceA
and also
InterfaceA extends IntefaceB , InterfaceC
Well if these arenot multiple inheritance then what are they?
UPDATE
Well I happened to phrase the question in a wrong way. My original question was why doesn't java support multiple inheritance.
Well what I really want to know is:
if more than one interface can be extended by an interface, or a class can extend one class and implement an interface, then why can't those be called multiple inheritance?
Java does support multiple inheritance; just take note that the support is very constrained: you can only inherit more than one interface. That is why you have heard that Java is single-inheritance: it is single class inheritance.
NB Java 8 will push its design even closer to multiple inheritance: interface will be allowed to define method implementations and a class will indeed inherit implementation from multiple parents. The diamond problem will be efficiencly solved by requiring the class having the conflict override the method. Within that override, the child class will be able to refer to each supertype implementation individually.
Thus, as of version 8, Java can be said to almost posses full multiple inheritance of implementation, just with manual resolution of conflicts, unlike C++ and other languages, which specify a formula for how the compiler will automatically resolve them.
The difference between an interface and a regular class is that you cannot specify implementation in an interface. To be more clear, you can only specify methods, but not implement them. If you want to have multiple inheritance then you have to implement multiple interface. Java does not support multiple inheritance due to the below reasons.
Also to note that Interfaces are about subtyping and polymorphism, whereas, inheriting methods is about code reuse.
From here:
The reasons for omitting multiple inheritance from the Java language
mostly stem from the "simple, object oriented, and familiar" goal. As
a simple language, Java's creators wanted a language that most
developers could grasp without extensive training. To that end, they
worked to make the language as similar to C++ as possible (familiar)
without carrying over C++'s unnecessary complexity (simple).
In the designers' opinion, multiple inheritance causes more problems
and confusion than it solves. So they cut multiple inheritance from
the language (just as they cut operator overloading). The designers'
extensive C++ experience taught them that multiple inheritance just
wasn't worth the headache.
You can find this interesting article on the same:-
As Inheritance defined as:
inheriting attributes and behavior from pre-existing classes called base classes, superclasses, or parent classes
Inheritance is to take some implementation from parent class. If a class inherit a class there must be some methods and attributes that child class inherited from base class.
But implementing an interface is not in general add some attributes or behavior.So when a class implements multiple interfaces there is no additional implementation comes from interfaces Or in other words we can say a class cannot inherit implementation from two different sources.
Reason why Multiple Inheritance is not allowed.
(reference wikipedia)
Diamond Problem
The "diamond problem" (sometimes referred to as the "deadly diamond of death") is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and/or C has overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?
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 Rectangle or Clickable (or both), which method should be eventually called?
It is called the "diamond problem" because of the shape of the class inheritance diagram in this situation. In this article, class A is at the top, both B and C separately beneath it, and D joins the two together at the bottom to form a diamond shape.
Java has no support for multiple inheritance. To explain the first example:
ClassA extends ClassB implements InterfaceA
In here, ClassA is extending a single class, and implementing a single interface. Whereas in the second case:
InterfaceA extends IntefaceB, InterfaceC
An interface is declared to extend from two other interfaces, you can think of this as "adding" all the methods from the extended interfaces, but it's not really multiple inheritance, the class that implements InterfaceA will have to provide implementations for all the methods defined in InterfaceA, InterfaceB and InterfaceC.
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.
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.