• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Method invocation without Object

 
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,
I have a little doubt regarding following code

Output: Placed in T

Now I understand that the method is not overridden here, so the compiler decides that the method for T must be invoked.But at the runtime,I guess JVM looks at the real object before invoking a method.We have object of class K, not T.How come method of T is invoked, when we don't even have the object of T.Why are we not getting a runtime error?I know that the polymorphic invocation takes place only in the case of overriding, but this invoking of method by just reference is confusing me.

Please help me out.


Thanks...
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
K extends T, so K inherits the methods of T, if they aren't overridden. Because a K is-a T, you always know that a K will have any methods that exist in T. Otherwise polymorphism couldn't work - it would never be safe to call any method.
 
Sudhanshu Mishra
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Matthew,
Thanks for your reply,but I think you did not get clearly the question.Let me rephrase it.
First of all here is no inheritance because the method is private in superclass.
Secondly, my question was that how come a method got invoked just based on reference, while the actual object is something else.
The method invoked was of superclass, while we have object of subclass only.

Please have a look again and then answer.

Thanks....
 
Ranch Hand
Posts: 67
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi sudhanshu,

Sudhanshu Mishra wrote:
........ how come a method got invoked just based on reference, while the actual object is something else.
The method invoked was of superclass, while we have object of subclass only.



You know that in JAVA every method invoked based on that reference type.
your question is why based on reference type not in actual type ? That's the way JAVA is working.

maybe that will help you : http://docstore.mik.ua/orelly/java-ent/jnut/ch02_10.htm

...... all the Java primitive types have well-defined standard sizes, so all primitive values can be stored in a fixed amount of memory (between one and eight bytes, depending on the type). But classes and array types are composite types; objects and arrays contain other values, so they do not have a standard size, and they often require quite a bit more memory than eight bytes. For this reason, Java does not manipulate objects and arrays directly. Instead, it manipulates references to objects and arrays. Because Java handles objects and arrays by reference, classes and array types are known as reference types. In contrast, Java handles values of the primitive types directly, or by value.

 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sudhanshu Mishra wrote:Hey Matthew,
Thanks for your reply,but I think you did not get clearly the question.Let me rephrase it.
First of all here is no inheritance because the method is private in superclass.



Private methods are inherited. But they aren't visible in the subclass. Here that's not a problem, because the method is being called from the class where it's defined.

There's an important principle in OO languages, called the Substitution Principle (often called the Liskov Substitution Principle). It says, roughly speaking, that anything you can do to an instance of a class you can do to an instance of any subclass. In this case it's obvious that calling placement() on that line is safe if it's a T object. Therefore it has to be safe to call it on a K object.
 
Sudhanshu Mishra
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Ankit,
Thanks for reply

But have a look at code below


Now, as you can see that child does not have the method display(), but still the object created is of type child only, as is confirmed by the printed results.I know that at compile time the refernce's type is checked but is it not true that at runtime, the method of actual object is invoked, and if it is not there, a runtime exception must be thrown(remember the ClassCastException!)?
So in this case, no inheritance of method, and no object of parent, still method invoked.At complile time it was fine, as parent class has method display(). and compiler only checked the refrence's type,not the actual object, but waht about runtime?

I guess I make my self clear this time.I want to know that how come the method invoked at first place if the class child not having that method at all.Print results prove that the object created was indeed of child class.

Please reply.....
Thanks...
 
Ankit Gareta
Ranch Hand
Posts: 67
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sudhanshu Mishra wrote:
... at compile time the refernce's type is checked but is it not true that at runtime ...



No. At runtime also the method invoked based on the Reference Type. So, the reference type has a method then it invoked otherwise error.
If you are not clear in this, then i afraid , you are not getting method overriding correct also.

So make clear that, object is whatever type, the method invoked only of reference-type, if method override take place then it will call the method of object type(subclass).

Hope that will help.

Thanks,
Ankit
 
Sudhanshu Mishra
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well thanks again Ankit.
This line from K&B
"The JVM looks at the real object at the
other end of the reference, "sees" that it has overridden the method of the declared
reference variable type, and invokes the method of the object's actual class"

So, what you mean to say is that it is only in the case of overriding that the JVM looks at the real object.If the real object is of child type,and the method is overridden, invoke it,but if the method is not their in the child class , invoke the one of super class.
Please correct me if wrong.

Thanks...
 
Ankit Gareta
Ranch Hand
Posts: 67
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sudhanshu,

Yup, You are right, the behavior is like that.
 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Brown wrote:
Private methods are inherited. But they aren't visible in the subclass.



Private members are not inherited . from JLS:


A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
It is not inherited by subclasses

 
Sudhanshu Mishra
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Seetharaman,
I would also request you to correct my understanding.I have always read that we always require an instance to invoke an instance method.In the code I posted above, I dont have an instance at all ,adn the type of reference just describes that what method is invoked,but the actual method invocation is on the real object at runtime.
Then why did the code I posted earlier worked?

I am sorry but I am sill not convinced that just becuase the reference type is of parent class, the method of parent class got invoked.Shouldn't the JVM throw a runtime error as the real object(of child class) is not having the method invoked?

Please correct me..
Thanks...
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sudhanshu Mishra wrote:Hey Ankit,
Thanks for reply

But have a look at code below


Now, as you can see that child does not have the method display(), but still the object created is of type child only, as is confirmed by the printed results.I know that at compile time the refernce's type is checked but is it not true that at runtime, the method of actual object is invoked, and if it is not there, a runtime exception must be thrown(remember the ClassCastException!)?
So in this case, no inheritance of method, and no object of parent, still method invoked.At complile time it was fine, as parent class has method display(). and compiler only checked the refrence's type,not the actual object, but waht about runtime?




Regarding line 11 of your code -- specifically " //this line should throw an error at runtime as the child class is not having display()." -- not sure how you came to this conclusion. The display() method is private to the parent class, and the main() method which is calling the display() method is part of the parent class, so, there should be no error. In other words, the private access modifier means that it is private to the class, and can only be called from code from that class -- which it is.

Henry
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sudhanshu Mishra wrote:Hi Seetharaman,
I would also request you to correct my understanding.I have always read that we always require an instance to invoke an instance method.In the code I posted above, I dont have an instance at all ,adn the type of reference just describes that what method is invoked,but the actual method invocation is on the real object at runtime.
Then why did the code I posted earlier worked?



Not sure what you are referring to here -- as every snippet of code above, has methods that are called with an instance.

Henry
 
Sudhanshu Mishra
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Henry,
Thanks for the reply.
But , let me ask it this way.In the snippet above, we have object of child class, not parent class.We just have reference of parent type, but the actual object is of child type.So at runtime, will the JVM not serach for the real object to which the reference is pointing?And if the JVM does invokes the method on the real object,why did it invoke the method in this case.We do not have a parent object, we have object of child.
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sudhanshu Mishra wrote:
But , let me ask it this way.In the snippet above, we have object of child class, not parent class.We just have reference of parent type, but the actual object is of child type.So at runtime, will the JVM not serach for the real object to which the reference is pointing?And if the JVM does invokes the method on the real object,why did it invoke the method in this case.We do not have a parent object, we have object of child.




You have to remember that a child object IS-A parent object. Everywhere that requires a parent object, should work when you pass a child object to it. If the compiler (and actually the whole inheritance feature) didn't allow this, then it would be pretty useless.

In this case, you have a parent reference, so the compiler will use that to find the right method (along with access checks and other bookkeeping stuff). At runtime, the method is called, with the child instance as its this object. The method expects a parent object as the this object, which is fine because the child instance IS-A parent instance.

Henry



PS... BTW, naming the classes "parent" and "child" is probably the source of the confusion. If the parent has been named "apple", and the child named "grannysmith", then when I say that a grannysmith IS-A apple, it would make much more sense.
 
Sudhanshu Mishra
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Henry,
I guess you are missing that the child class is not having the method display() at all.It is private in parent class.Does this bring any change in your answer?I am repeatedly trying to say that child instance is not having method display(), yet the method is invoked on child instance at run time.
Please get me corrected if wrong.
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sudhanshu Mishra wrote:
I guess you are missing that the child class is not having the method display() at all.It is private in parent class.Does this bring any change in your answer?I am repeatedly trying to say that child instance is not having method display(), yet the method is invoked on child instance at run time.
Please get me corrected if wrong.




No. I am *not* missing that point at all -- because it is *not* true. A child class IS-A parent class, and hence, has *all* the methods of the parent class (footnote 1). For most cases, you can use a child instance to call methods of the parent class (provided that you have access permissions, and if hiding is happening, you can get around it), The only exception is for a method has been overridden, then you are limited in how you can call it -- only the child instance itself can call the parent version of the method via the super keyword.

To repeat, a child instance IS-A parent instance. You should be able to use a child instance like a parent instance, and that includes calling methods of the parent class.

Henry



1. Technically, this isn't true. Method definitions are part of class definitions, so are not part of any instance. Also, no definitions are copied. The compiler will use the method defined in the parent's class.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Seetharaman Venkatasamy wrote:Private members are not inherited . from JLS:


A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
It is not inherited by subclasses


Well, they're not accessible, as I already said. They certainly exist in the subclass, as the Substitution Principle requires (and this code demonstrates) - I'd have called that inheritance, but you're probably right that's not the formal definition as defined by the JLS.
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another point (and probably the main reason for your mistake) ....

Sudhanshu Mishra wrote:
I guess you are missing that the child class is not having the method display() at all.It is private in parent class.



The "private" (in private method) is referring to the accessibility by the caller -- meaning can the method be called by the calling code? In this case, it is being called by the main() method of the parent class. And since that code is part of the class that it is private to, it can be called.

It seems that you have your own definition of what is a private method -- with the meaning that private methods can't be called (using child instances) at all.


Anyway, as an alternative, if the main() method was part of the child class, then the compiler would have complained. Try it. Move the main method to the child class, and you will see that it doesn't work.

Henry
 
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:Another point (and probably the main reason for your mistake) ....

Sudhanshu Mishra wrote:
I guess you are missing that the child class is not having the method display() at all.It is private in parent class.



The "private" (in private method) is referring to the accessibility by the caller -- meaning can the method be called by the calling code? In this case, it is being called by the main() method of the parent class. And since that code is part of the class that it is private to, it can be called.

It seems that you have your own definition of what is a private method -- with the meaning that private methods can't be called (using child instances) at all.


Anyway, as an alternative, if the main() method was part of the child class, then the compiler would have complained. Try it. Move the main method to the child class, and you will see that it doesn't work.

Henry


@Henry : At runtime , there is a child object. Child class must have have the function display() so that it can be called at runtime. But Child class does not inherit neither define the display() function. So shouldn't the JVM through a RUNTIME Exception inspite of calling Parent class display() function?
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

sharma ishu wrote:@Henry : At runtime , there is a child object. Child class must have have the function display() so that it can be called at runtime.



Agreed.

sharma ishu wrote:But Child class does not inherit neither define the display() function.



Arguably, the child class does *not* inherit the display() method from the parent class, because "inherit" implies polymorphism, and a bunch of loaded words that will take this topic into a rathole (assuming that it isn't already in a rathole).

However, the child class does have access to the display() method, just like it has access to the parent's static methods. If you used an instance of a child class to call the parent's static method, which does not exist in the child class that will work too. This is just like that -- you can use the child instance to call private methods of the parent class, assuming that you can get around the hiding and access permission issues.

Now, is this inheritng? Let's postpone that debate for another topic. Right now, just understand that the method is available to be called.

sharma ishu wrote:So shouldn't the JVM through a RUNTIME Exception inspite of calling Parent class display() function?



So, to repeat again, No. It will work fine -- as you already seen when you ran the code.

Henry
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

sharma ishu wrote:So shouldn't the JVM through a RUNTIME Exception inspite of calling Parent class display() function?



What you'll actually find is that the compiler is much stricter than the runtime when it comes to type checking, but the other way around. Unless you override it (by explicit casting, etc) the compiler won't allow things like this to happen unless it can guarantee the call is valid. You can have cases where a call would succeed at runtime, but the compiler won't allow it. But you won't find the compiler letting things through that then fail.
 
Ranch Hand
Posts: 62
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To explain , i have made few changes to your code.

Now ,
fruit p = new apple();// here we have created a apple object(child class) with reference (which is p) of fruit class(Parent Class).
At compile time,
p.display();
JVM will check the type of reference of p which is fruit (parent class). It will then check whether fruit class have display method or not. As fruit class have display method,it will compile fine.
Moving on to Runtime,
p.display();
Now JVM knows p is a subclass's object i.e. apple's object. So it will check for display method in apple class. There is no such method in apple class as neither display method is inherited (private methods are not inherited) nor it is defined in apple class.
Ideally this should have given error but the reference type is of fruit class(parent class),it will check if parent class has this display method(); and there it is.
Voila ! it will run that method but using object of apple class(child class) as object is of type apple class.
Now with private modifier,if main was defined inside apple class then JVM would have thrown exception as private methods are invisible to other classes even subclasses.
But here you have defined main inside parent class or the class which contains private method,so it is visible there and hence executed.
I hope you got all your doubts cleared.
Tushar
 
reply
    Bookmark Topic Watch Topic
  • New Topic