简体   繁体   中英

Cyclic inheritance hierarchy in Java

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 (eg 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 Object s. Thus, the compiler must forbid cyclic dependencies.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM