Reputation: 2656
package P1;
public class Base {
private void pri( ) { System.out.println("Base.pri()"); }
void pac( ) { System.out.println("Base.pac()"); }
protected void pro( ) { System.out.println("Base.pro()"); }
public void pub( ) { System.out.println("Base.pub()"); }
public final void show( ) {
pri();
pac();
pro();
pub();
}
}
and
package P2;
import P1.Base;
public class Concrete1 extends Base {
public void pri( ) { System.out.println("Concrete1.pri()"); }
public void pac( ) { System.out.println("Concrete1.pac()"); }
public void pro( ) { System.out.println("Concrete1.pro()"); }
public void pub( ) { System.out.println("Concrete1.pub()"); }
}
And I'm executing
Concrete1 c1 = new Concrete1();
c1.show( );
Now, the output is shown to be
Base.pri()
Base.pac()
Concrete1.pro()
Concrete1.pub()
Can someone explain why this is so? From what I understood about inheritance, this should have happened:
1) P2.concrete1 inherits P1.Base
2) c1 object of concrete1 is created
3) c1.show()
is called. Since P1.Base.show() is public
, it can be called.
4) Now, in P2.concrete1 after inheritance, only it's own methods (pri, pac, pro, pub) and P1.Base's inheritable methods (pro, pub, show) are accessible.
Now WHY does it show Base.pri() and Base.pac() in the output when they're not even accessible?
It's clear that I've not got a very clear fundamental understanding of inheritance. Can someone explain this situation and how inheritance is actually 'structured'. I used to think that inheritable methods and fields of the superclass would just superimpose onto the subclass. But that line of reasoning is obviously wrong.
Thanks!
Upvotes: 8
Views: 5285
Reputation: 9528
Private and no-modifier methods are by design not visible to its subclass. See here for detailed explanation.
Upvotes: 0
Reputation: 2349
The short answer is that you can only override methods that are visible. The first two methods, pri
and pac
are private and package protected respectively. Because nothing outside the class can see a private method, it can't be overridden. Similarly because Concrete1
is in a different package from Base
it can't see Base.pac
so cannot override it.
What this means is that while you define a pri
and pac
method in Concrete1
, they're just methods that happen to have the same name as the methods in Base
, not overrides. The other two methods pro
and pub
are protected and public respectively, so are visible to Concrete1
. As a result the pro
and pub
methods in Concrete1
are overrides of the methods of the same name in Base
.
Because show
is defined in Base
, it's compiled calling the 4 methods as defined in Base
. When executed the JVM looks to see if any are overridden and if they are executes the overridden methods. As explained above, pri
and pac
are not overridden so the Base
versions are executed where as pro
and pub
are so the Concrete1
versions are executed.
If you were to move the show
method into Concrete1
instead of Base
then it would execute the 4 methods as defined in Concrete1
as those would be the methods visible to show
.
Upvotes: 12