Reputation: 5335
class A {
public void talk(){
this.sayIt();
}
private void sayIt(){
System.out.println("class A says...");
}
}
class B extends A {
private void sayIt(){
System.out.println("class B says...");
}
}
Test class, main method:
B b = new B();
b.talk()
//output
class A says...
I cannot get this since:
Class B inherits from class A, the public member and cannot see/inherit the private function. So in class B, we could call talk(). //since it is inherited by the parent class.
Now, in the talk() method, there is a call to sayIt() since sayIt() is defined in class B,
I would expect a call to B.sayIt() to be made when this.sayIt() is executed.
Doesn't "this" refer to the class B?
Please Explain.
Upvotes: 3
Views: 2046
Reputation: 1464
Slightly deviate from the topic but can help you to understand the Java inheritance better.
http://webmoli.com/2008/08/02/why-multiple-inheritance-is-not-allowed-in-java/
Upvotes: 0
Reputation: 2066
Because you defined sayIt() to be private, class B cannot override it. As such, you have two definitions of sayIt() rather than just one that is overriden by a subclass.
While inside a section of class A code, it will always call the version from class A, even if the class B version was protected or public. This is because class A only knows about the version from class A since the class B version is not an override, but a completely different method that just so happens to share the same name.
While inside of a section of class B code, it will always call the version from class B since the class A version is marked private. As noted by others, if you change the definition to protected or public, it will be visible to class B and it will do what you want.
Note that if you were to use the default (package) visibility, the scoping rules would get to be very complex and the actual results would vary depending on which subclasses are in the same package and which are in different ones.
Upvotes: 6
Reputation: 6417
According to Java language specification 8.4.8:
A class C inherits from its direct superclass and direct superinterfaces
all non-private methods (whether abstract or not) of the superclass and
superinterfaces that are public, protected or declared with default access
in the same package as C and are neither overridden nor hidden by a
declaration in the class.
So B did not inherit A.sayIt() and hence did not override it.
Upvotes: 0
Reputation: 3849
Because in talk
you reffer to this.sayIt
and object B is instance of A.
Object A has no knowledge of methods in B. Make object A an abstract class with sayIt
abstract method which you call in A talk or change visibility of sayIt
.
Also - use annotaions and IDE will notify you with warnings.
Upvotes: 0
Reputation: 91871
Because sayIt is a private method, it is in fact not overridden. One way to help understand this is to add the @Override annotation to any method that you think overrides something from the superclass. If you are wrong (as in this case) then the compiler will tell you.
Upvotes: 0
Reputation: 4619
"Doesn't "this" refer to the B class ?" - No. Though you create a the instance from class B you still refer the method of the base type which is talk(). One way you can achieve this same objective is thru template-method pattern.
/BB
Upvotes: 0
Reputation: 25687
Yes "this" of b.talkIt()
refer to the B class but since sayIt()
is private in A and talkIt()
is decalred in A and not overridden in B, the sayIt()
will be referred to the one in A.
You can look at it this way. sayIt()
of A is private so it cannot be overridden. Since it is not overridden, sayIt()
call by methods of A will always point to the one known to A (as it is not overridden).
Hope this helps.
Upvotes: 0
Reputation: 3757
If you change the "sayIt" method to be protected it will work like you expect it to.
It seems like you're a little bit confused about how it works with overriding methods. If I'm not mistaken, what you are trying to do is perfectly alright in C++, but not in Java.
Upvotes: 0
Reputation: 15824
Consider making protected
instead of private
on sayIt
. sayIt
on B is not overriding sayIt
on A.
Upvotes: 3