Самый простой способ визуализировать это состоит в том, чтобы учесть, что наследование похоже на отношения родитель / потомок.Вы можете иметь Parent -> Child -> Grand Child и т. Д.
Когда у вас есть:
class A {}
class B extends A{}
class C extends B{}
C
, это как внучатый ребенок A
.А это значит, что C
наследует все методы от B
, включая те методы, которые B
сам унаследовал от A.
In OOP words,
C **is**
A`.
Однако, когда у вас есть
class A {}
class B extends A{}
class C extends A{}
C
и B
являются классами sibling , то есть оба они наследуют методы A
, но они несовместимы друг с другом.
В первом случае они действительны:
C c = new C();
c.methodFromA(); //C inherits methods from A by being its grand-child
c.methodFromB(); //C inherits methods from B by being its child
c.methodFromC();
Во втором случае, однако, когда оба B
и C
extends
A
напрямую:
C c = new C();
B b = new B();
c.methodFromA(); //C inherits methods from A by being its child
b.methodFromA(); //B inherits methods from A by being its child
c.methodFromB(); //not allowed
b.methodFromC(); //not allowed
Однако прямой связи между B
и C
нет.Это неверно:
B b = new B();
C c = new C();
b = (B) c; //invalid, won't compile
A b = b;
c = (C) b; //will compile, but cause a ClassCastException at runtime