Inheritance and memory allocation - java

for the following code:
class Parent {
public void say(){
System.out.println("Parent");
}
}
class Child extends Parent{
public void say(){
System.out.println("Parent");
}
}
class Test {
public static void main(String[] args){
Parent p = new Child(); // What does the compiler check
p.say();
}
}
The following questions have always confused me.
1. what exacly is happening during compile time? How does the comiler know that Parent p = new Child() is a valid code as no object has been created at compile time?
2. what exactly is hapenning at runtime? How is memory allocated
3. The implicit call to parent's constructor creates an Parent Object. A child object is also created. How is it stored and how does jvm use this for method resolution.
4. Lastly, is JVM hardcoded not to ovverride static methods and variables or there is some other reason. Why can't we use Runtime objects instance method() why not runtime objects variables
Where can I read more on these topics?
Thanks

exactly is happening during compile time? How does the comiler know that Parent p = new Child() is a valid code as no object has been created at compile time?
Well, whole books are written about that subject. In essence, the compiler parses the input source, and it finds that assignment:
Parent p = new Child();
And now the compiler does two things:
it checks what it can find out about the types on both sides of the assignment
thus it finds: the left hand side needs an object of type `Parent``
it also looks at the right hand side, to understand the (potential) result types that comes out of that expression
So, in the end, the compiler will see: "I need a Parent ... and I get something that is a Child." Then the compiler has to check if an instance of Child satisfies "I need a Parent". And obviously: it does.
what exactly is happening at runtime? How is memory allocated
Again, whole books are written about that. See here for example.
The implicit call to parent's constructor creates an Parent Object. A child object is also created. How is it stored and how does jvm use this for method resolution.
The JVM "simply" knows two things:
when reserving the memory for a Child object, it needs to also consider the memory required for any super class fields
so, in the end, you simply have one area of memories large enough to hold all fields of all parent classes, down to the Child class itself
Finally: static methods are inherented, but yes, there is no polymorphism for them in Java. That is simply a design point of the language, and the semantics that are defined for Java. It could be done differently, but 20+ ago, the fathers of Java decided to do it like they did.

Related

Subclass object with superclass funcionality

I'm confused why this code works.
The object "person" is declared as an instance of B with only the functionality of A, yet it somehow prints out hello twice. If the object only gets access to the methods in A, how can it end up accessing the print out statement?
abstract class A {
abstract void move();
void go() {
this.move();
}
}
class B extends A {
void move() {
System.out.println("hello");
}
}
public class Main {
public static void main(String[] args){
A person = new B();
person.move();
person.go();
}
No, you have a "link" of class A, but functionality depends on object (in your code it is new B();), so your A link points to a B object with B functionality.
The object "person" is declared as an instance of B with only the functionality of A
Not exactly. Java is a reference-based language; here you have made an instance (new B()), and have exactly one reference to it, called person.
You could have no references to it (leading to the created object being garbage collected eventually). You can have 2000 references to it. You could have B b = new B(); A a = b;, and now you have 2 references to it, one of type A and one of type B. But they are pointing to the exact same object.
Thus, person isn't an object, it's a reference. And that reference has type A, sure, but the object it is referencing is just a B, it isn't 'restricted' to have only A functionality.
You probably know all this, but terminology is important here, as it seems to have led to some confusion. Restating your question with less ambiguous terminology:
The reference "person" currently references an instance of B, but only exposes functionality that A has.
Yes. And A's functionality is described solely by the signatures present there, not by the code. A's functionality involves having a go() method, which takes no arguments and returns nothing, as well as a move() method with the same rules. And that is all - 'invoking go will actually run the move method', or 'move has no implementation' is not part of that.
Thus, both move() and go() are part of the functionality exposed by A.
The implementation of the functionality has nothing whatsoever to do with the reference type (A person) and everything to do with what the reference is actually pointing at (new B()). B's implementation of the move() and go() methods specified by A are such that move prints "hello", and go() calls move (thus, prints hello()) - that implementation is inherited from A, but B was free to change that; B however decided not to.
Said more technically:
Java uses something called dynamic dispatch. What that means is that at compile time (i.e. write time), java figures out if a method you're calling even exists and which variant (if you have move(String a) and move(int a), that's two methods with the same name, at write time java decides which one you are attempting to invoke), and uses the type of the expression in front of the dot to figure that out. But then at runtime, the actual type of the object that 'the expression in front of the dot' is actually pointing at is used to figure out which actual code to invoke. This always happens and you can't opt out (you can't choose to run A's implementation when you invoke main(). Only B's implementation can choose to not override A's implementation, or to explicitly invoke its supertype's implementation. A user of B's code cannot do that).
Note that static stuff doesn't 'do' inheritance at all, and therefore, dynamic dispatch doesn't apply there.

What really happens on inheritance in Java?

Suppose I have two classes Parent and Child, and Child inherits from Parent. I have three methods in Parent, out of which two are public and one is private.
Normally we say that all the non-private methods are inherited into the Child class, but I'm confused about exactly what happens. Does Java make a copy of the methods in the Child class, or does it use some kind of reference to maintain the relationship?
class Parent{
// Private method
private void method1(){
System.out.println("In private method of Parent class");
}
void method2(){
// calling private method
method1();
}
void method3(){
// calling private method
method1();
}
}
class Child extends Parent{
}
class MainClass{
public static void main(String[] args){
Child child = new Child();
// calling non-private method which internally calls the private method
child.method2();
}
}
Does Java makes copy of the methods in the Child class or it uses some kind of reference to maintain the relationship?
Latter. Take a look at invokespecial. Java recursively looks up methods one class at a time. The first matching method is called. This is why calling a virtual (default) method is slower than calling a final method.
In general, the actual code within a method is not copied when you inherit from a class containing that method.
Neither.
Inheritance is a programming language concept, not a real action. When you investigate the compiled Child class, e.g. with javap, you won’t find any artifact related to the three methods of Parent. There will be the information that Child has the superclass Parent, but no mentioning of the inherited methods, neither as references nor as copies.
The fact that Child conceptionally inherits methods from Parent comes into play when you actually try to invoke one of them through a variable whose compile-time type is Child, like in your Test class. Then it is up to the compiler to find the inherited methods in order to compile the code containing the invocation correctly. It is also up to the compiler whether it searches the class hierarchy every time it resolves a target method of an invocation or whether it collects the existing methods in certain data structures to speed up subsequent lookups and which data structures it uses.
This process is more complicated than you might think. There may be multiple candidates among which the compiler has to select one and it may even fail due to ambiguity. The result of the process will be a decision about whether the invocation is valid and, in case it is valid, a single target method and its actual signature.
The compiled invocation will contain the name and signature of the target method and a reference to the compile time type of the reference on which it is invoked, i.e. Child. It will not contain the information that the actual method has been inherited from Parent. This is intentional. Whether Child declares the method itself, inherits it from Parent or overrides a method of Parent should not affect the code of the invoker Test nor the compatibility between compiled class files.
This implies that at runtime a class like Test may contain a reference, given by name and signature, to a method in Child not being stored in the class file of Child, in other words, the JVM is responsible as well, for making the concept of inheritance working. At the same time, it has to ensure that the concept of overriding works, when a method invocation is executed.
The way it implements this is also unspecified, leaving room for different strategies. Searching class hierarchies on every invocation would be legal, but lead to poor performance.
A common technique is a vtable. Associated with every class is a table (array) containing references to the available methods, be it declared or inherited. On initialization of a subclass, its table will start with a copy of the superclass’ table, having entries for new methods appended at the end and entries of overridden methods changed. At some time, the method invocation will be linked by finding the index of the vtable entry, appropriate to the specified name and signature. A typical strategy is to do the lookup on the first invocation. The instruction is then modified to refer to the index to avoid subsequent lookups. From then, subsequent executions consist of fetching the vtable for an object’s runtime class and getting the method reference from the table’s entry.
Considering that, you could say that at runtime, inheritance is typically implemented as some kind of reference—but wait.
Implementations like Oracle’s JVM are capable of doing hotspot optimizations in which the context of often executed code is considered. There might be, for example an inherited method which itself invokes methods which have been overridden in some subclasses. When the JVM finds out that this method is called very often on a single concrete subclass, it may create an optimized version for that particular case. Then, a copy of the method’s code will be the starting point for the subsequent code transformations, inlining code of the specific subclass, etc.
Since such sophisticated implementations will use references for non-optimized code while using optimized copies in other cases, an alternative to the initial answer answer could be:
Both.
Method bodies aren't copied in the undefined method body of a subclass. Instead, when you call
Child child1 = new Child();
child1.method1();
It will look through its hierarchy, going up a level every time it can't find an implementation. First it will check Child which has no implementation. One level above that there's Parent which does, so it will use that one.As correctly mentioned by #Dante above that this is achieved via the super() call in the constructor of the Child Class. This image might help you get a better picture :
I think your confusion is somehow associated to the point
of non inheritance of the private methods.So,I would like to address that as well
Why Private Members are not inherited ?
You could say that private members are not inherited, because nowhere can Child refer explicitly to value. I.e. any code like this.value can't be used within Child, nor can obj.value be used from some calling code (obviously).
However, in another sense, you could say that value is inherited. If you consider that every instance of Child is also an instance of Parent, then that object must contain 'value' as defined in Parent. Even if the Child class knows nothing about it, a private member name value still exists within each and every instance of Child. So in this sense, you could say that value is "inherited" in Child.So without using the word "inheritance", just remember that child classes don't know about private member defined within parent classes. But also remember that those private members still exists within instances of the child class.
Note: The the JLS states (http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.2):
Members of a class that are declared private are not inherited by
subclasses of that class. Only members of a class that are declared
protected or public are inherited by subclasses declared in a package
other than the one in which the class is declared.
Java does not make a copy of the methods.The methods that are inherited stay with the parent class only.
Now you must me wondering,How does child class get access to them?
The answer lies in understanding the super keyword.
The super keyword is used to refer to object of immediate parent class.The very first thing super does is initialize object of parent class.This means it is responsible for creating object of parent class and is used to refer to that object.
The super(); is implicitly the first statement inside constructor of child class,however you can do that explicitly also.
Now the important part:
If you have the following:
super();
not as your first statement inside child class constructor,then compile error is generated saying:
call to super must be first statement in constructor.
The reason is:
Because the child class is assumed to have the inherited methods,but do not possess a copy of them.
The inherited methods are basically with parent class,so it is important to create object of parent class first,so that whenever following is used
instance_of_child.method_of_parent();
The method will be actually invoked from object of parent class,which was already created by super(explicitly or implicitly used).
This is the reason why you can have child class constructor like:
Child()
{
super();
parent_method();
}
but not like:
Child()
{
parent_method();
super();
}
because parent_method(),that is the inherited method requires reference to object of parent class which is provided by super().

Runtime polymorphism

Suppose I have class A
public class A
{
public void method()
{
//do stuff
}
}
Also another class B
public class B extends A
{
public void method()
{
//do other stuff
}
}
Now I have the following statements:
A a = new B();
a.method();
Is this an example of run time polymorphism? If yes, then is no binding is done for the reference a at compile time?
The compiler will tell you that this can't work, because there's no relationship between A and B that will allow you to write A a = new B();
B either has to extend A or both have to implement a common interface with void method() in it.
You could have answered this very quickly by trying it with the compiler. Be an experimentalist - it's faster than forums.
UPDATE:
It works, now that B extends A. The binding that you care about, dynamic binding, is done at runtime. The static compile time type for the variable "a" is class A; at runtime it is dynamically bound to a reference of type B. Yes, I would consider this to be an example of polymorphism.
I was waiting to put my answer to another post, into a more correctly classified problem. Your question fits the concept, I've tried to explain in detail. but, since I don't know how link answers, I'll just copy/paste the complete script here .... Kindly go through it, you'll understand everything that there is to understand about your problem, you've asked
let's say compiler has to resolve a call like this : *
A a = new AA(); // Assume AA to be some subclass of class A
a->someFunc(); // and we're invoking a method "someFunc()' on a
*.
Now, compiler will go over following steps methodically.
1.) Firstly, compiler knows the declared type of variable a, so it will check whether the declared type of object a (lets call this, class A for time being), have a method with the name someFunc() and that it must be public. This method could either be declared in class A, or it could be a derived method from one of the base class(es) of class A, but it doesn't matter to compiler and it just checks for it's existence with it's access specifier being public.
Needless to say any error in this step will invite a compiler error.
2.) Secondly, once the method is validated to be a part of the class A, compiler has to resolve the call to the correct method, since many methods could be there with same name (thanks to function overloading). This process of resolving correct method is called overloading resolution. Compiler achieves this by matching the signatures of the called method with all the overloaded methods that are part of the class. So, of all the someFunc() s only the correct someFunc() (matching the signatures with called method) will be found and considered further.
3.) Now comes the difficult part, It may very well happen that someFunc() may have been overridden in one of the subclasses of the class A (lets call this class AA and needless to say it is some subclass of A), and that variable a (declared to be of type A) may actually be referring to an object of class AA, (this is permissible in C++ to enable polymorphism). Now, if the someFunc() method is declared to be of type virtual, in base class (i.e. Class A) and someFunc() has been overriden by subclass(es) of A (either in AA or classes between A and AA), the correct version of someFunc() have to be found out by the compiler.
Now, imagine you're the compiler and you have this task of finding whether the class AA has this method. Obviously, class AA will have this method since, it is a subclass of A and public access of A in class A has already been validated in Step 1 by the compiler !!! . But Alternatively, as mentioned in previous paragraph, someFunc() may be overriden by class AA (or any other class between A and AA), which is what compiler needs to catch. Therefore, you (since, your'e playing the compiler) could do a systematic check to find the bottom-most (lowest in the inheritance tree) overridden method someFunc() starting from class A and ending at class AA. In this search, you'll look for same method signatures as was validated in overloading resolution. This method will be the method which will be invoked.
Now, you may be wondering, "What the heck", is this search done everytime ? ... Well, Not really. The compiler knows the overhead of finding this everytime, and as such, maintains a data-structure called Virtual Table for every class type. Think of virtual table, as mapping from method signatures (which are publicly accessible) to the function pointers. This virtual table is made by compiler during compilation process and is maintained in-memory during program execution. In our example, class A and class AA will both have their own virtual tables. And when compiler has to be find someFunc() in class AA (since actual object pointed by variable a is of type AA), it will simply find the function pointer through the virtual table of Class AA. This is as simple has hashing into the table and is a constant time operation.
Regards
AViD
The code example you've given isn't legal, so I guess the answer is that it's not a kind of polymorphism.
You can't assign a class to a variable of an unrelated type like that. I'm guessing that you might be intending for B to derive from A?
Is this an example of run time polymorphism?
As of the edit: yes that would be runtime polymorphism, since which method is actually executed depends on what is assigned to a.
Edit:
If method() would be static, then calling a.method() would always result in the version of A being called. However, you'd then just write A.method() and if you don't do that any decent IDE would warn you about that (because it might be misleading to call a static method on an instance).
End Edit.
Compile time polymorphism would be the overloading mechanism, i.e. the compiler decides whether to use someMethod(Number) or someMethod(Integer) depending on what it knows about the parameter that is passed (if you pass a Double or just a Number it would be the first one, if you pass an Integer it would be the second).
If yes, then is no binding is done for the reference a at compile time?
What do you mean exactly? Note that the type of a will be A so you can assign everything that extends A at runtime. The compiler will just complain if the assigned value is not an A (you might trick the compiler with a cast, but this is just evil and if this breaks your program, you have been warned ;) )
It should be
public class B extends A {
public void method()
{
//do other stuff
} }
If it were compiling, it would be the B::method() that would be called. (only if you changed your code to make the B class inherit the A class).
In this case your use your object like it was only an A, but if some methods are overidden in B, then these methods are called, instead of A's methods.

Problem regarding interface reference variable

I've studied that in case of instance methods, at run time the jvm uses the actual class of instance and in case of class methods the compiler will only look at the declared type of a reference variable not the actual class..
I studied this concept instance method hiding..
And in my proram I've used interface reference variable to store the object of the class and try to access the instance method of the class using this but it raise an error..
My program is as follows:
interface A
{
void show();
}
class B implements A
{
public void show()
{
System.out.println("Interface Method");
}
void info()
{
System.out.println("IN Info");
}
}
class interDemo
{
public static void main(String args[])
{
A a;
B b=new B();
a=b;
a.show();
a.info();
}
}
Please help me to understand the conept...
The compiler is telling you that the type A does not have a method called info defined. This is true: the compiler doesn't know that at runtime, the type of a will actually be B, which does have the info method. It would be unsafe to allow the a.info() call to actually be compiled and emitted into bytecodes, there's nothing to say that a will always be of type B.
This is known as static typing. In Java and other static-typed languages, you need to "cast" a variable in order to force the compiler to treat it as another type. In this case, you can write ((B) a).info().
sjr is correct. Here's another way to look at it:
You're specifying that a A can only show. That means when you have a A reference variable, that's all you can do.
That means any class that is willing to show can implement that interface. Clients that need an object to show can use an A without knowing or caring whether that the underlying class has other methods. This is a key aspect of the abstraction provided by object-oriented programming.
You might probably want to see this lecture on YouTube. It covers you problem and I hope it will help you.
In short: static type of a is A. After assigning b to a, dynamic type of a is B. So at this point, static type a is A and dynamic type of a is B. Compiler does not follow dynamic types, it only checks static types. So it will not let do anything other then static type will allow.
So in your example if you are using reference of static type A, you can only call methods from class A.
super concept without confusion
=====================================
2 rules to know from where a method will execute(when super type reference is used to call methods)
NOTE:check "object creation"/"reference assignment" statement for applying rule
1 RULE: 1st check the method to be called.If static/overloaded/single--then it becomes static polymorphism/static(compiler looks for reference type)---hence always execute from reference type
2 RULE: check method to be called --if overridden--then it becomes dynamic polymorphism(jvm looks for object type)---hence always executed from object type(i.e right to new keyword)
for example:
super s=new child();
s.play();
here 2 cases:
1st: check play() is what i.e static(static/overloaded/single method) or dynamic(overridden)
2nd: if static it will execute from super i.e reference type leads to compile time polymorphism
if dynamic it will execute from child i.e object type leads to dynamic polymorphism

method overriding

class A
{
int i=10;
void show()
{
System.out.println("class A");
}
}
class B extends A
{
int i=5;
public void show()
{
System.out.println("class B");
}
}
class M
{
public static void main(String s[])
{
A a=new B();
a.show();
System.out.println(a.i);
}
}
OUTPUT= class B
10
If class A method is overridden by class B method then why not the variable 'i'?
Because variables are not virtual, only methods are.
It is not overwritten, but hidden. In your output you specifically requested the value of a.i, not ((B)a).i.
This is a "feature" of the implementation. In memory, this looks like so:
a:
pointer to class A
int i
b:
pointer to class B
int i (from A)
int i (from B)
When you access i in an instance of B, Java needs to know which variable you mean. It must allocate both since methods from class A will want to access their own field i while methods from B will want their own i (since you chose to create a new field i in B instead of making A.i visible in B). This means there are two i and the standard visibility rules apply: Whichever is closer will win.
Now you say A a=new B(); and that's a bit tricky because it tells Java "treat the result from the right hand side as if it were an instance of A".
When you call a method, Java follows the pointer to the class (first thing in the object in memory). There, it finds a list of methods. Methods overwrite each other, so when it looks for the method show(), it will find the one defined in B. This makes method access fast: You can simply merge all visible methods in the (internal) method list of class B and each call will mean a single access to that list. You don't need to search all classes upwards for a match.
Field access is similar. Java doesn't like searching. So when you say B b = new B();, b.i is obviously from B. But you said A a = new B() telling Java that you prefer to treat the new instance as something of type A. Java, lazy as it is, looks into A, finds a field i, checks that you can see that field and doesn't even bother to look at the real type of a anymore (because that would a) be slow and b) would effectively prevent you from accessing both i fields by casting).
So in the end, this is because Java optimizes the field and method lookup.
Why no field overrides in Java though?
Well, because instance field lookups in Java happen at compile time: Java simply gives you the value of the field at a given offset in object's memory (based on the type information at hand during compilation: in this case a is declared to be of type A).
void foo() {
A a = new B();
int val = a.i; // compiler uses type A to compute the field offset
}
One may ask "Why didn't compiler use type B since it knows that a is in fact an instance of B? Isn't it obvious from the assignment just above?". Of course, in the case above, it's relatively obvious and compiler may try to be smarter and figure it out.
But that's compiler design "rat hole", what if a "trickier" piece of code is encountered, like so:
void foo(A a) {
int val = a.i;
}
If compiler were "smarter", it would become its job to look at all invocations of foo() and see what real type was used, which is an impossible job since compiler can not predict what other crazy things may be passed to foo() by unknown or yet unwritten callers.
It's a design decision by the developers of Java, and is documented in the Java Language Specification.
A method with the same method signature as a method in its parent class overrides the method in its parent class.
A variable with the same name as a variable in its parent class hides the parent's variable.
The difference is that hidden values can be accessed by casting the variable to its parent type, while overridden methods will always execute the child class's method.
As others have noted, in C++ and C#, to get the same override behavior as Java, the methods need to be declared virtual.
a is an instance of A. You call the constructor B(). But it is still a A class.
That is why i equals 10;
The override from the method will be succeded.
Note a class starts not with
public class A()
but with;
public class A { ... }
Tip: You can use setters and getters to make sure of what data-members you use.
Or: You simply can set the values at the constructor instead of the class declaration.
Because by default the variables are private. You must declare it as "protected", then will be properly inherited.

Categories

Resources