Andreas
Andreas

Reputation: 5335

Java inheritance - please explain

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

Answers (10)

Venkat Sadasivam
Venkat Sadasivam

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

James
James

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

Murali VP
Murali VP

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

Trick
Trick

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

Yishai
Yishai

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

Illuminati
Illuminati

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

NawaMan
NawaMan

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

sinuhepop
sinuhepop

Reputation: 20307

You are trying to override private methods. It has no sense.

Upvotes: 2

Mattias Nilsson
Mattias Nilsson

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

John Paulett
John Paulett

Reputation: 15824

Consider making protected instead of private on sayIt. sayIt on B is not overriding sayIt on A.

Upvotes: 3

Related Questions