I know what extends keyword do in java, but I want to understand what java compiler do when it sees extends keyword.
class A{
//some state
//some behavior
}
class B extends A{
}
in my opinion when compiler sees extends keywords then it creates super class object to be used in subclass. and I know we can use super reference keywords in subclass constructor to refer to super class constructor.
No, there is no reference to a superclass object. When you do new B(), with your example, there is one object created, which has a combination of A and B features, not separate B and A objects with a relationship between them. (That would be prototypical inheritance, which is used in several languages, but not Java.)
super isn't a reference to a separate object. From JLS§15.11.2:
The form super.Identifier refers to the field named Identifier of the current object, but with the current object viewed as an instance of the superclass of the current class.
Sometimes, it seems like there must be two separate objects, such as when you shadow an instance field:
class A {
private int field;
A(int value) {
this.field = value;
}
public void sayField() {
System.out.println("(A) field == " + this.field);
}
}
class B extends A {
private int field;
B(int aValue, int bValue) {
super(aValue);
this.field = bValue;
}
#Override
public void sayField() {
super.sayField();
System.out.println("(B) field == " + this.field);
}
}
If you do this:
B b = new B(1, 2);
b.sayField();
...you get (live copy)
(A) field == 1
(B) field == 2
If there's just one object, how can it be that this.field inside A#sayField use a different field than this.field inside B#sayField? The answer is: There are two field fields in that one object. The compiler tells the code in A#sayField to use the first one, and the code in B#sayField to use the second.
Related
super keyword can be used to access the members of parent class. Apart from this, super is also an instance of child class as justified by below code:
class A {
}
class B extends A {
public void method() {
System.out.println(this.getClass().isInstance(new B()));
System.out.println(super.getClass().isInstance(new B()));
}
}
public class InheritanceDemo {
public static void main(String[] args) {
B obj = new B();
obj.method();
}
}
Output:
true
true
Now, If super is the instance of child class as justified above and java allows us to return any instance as per return type then why can we not return super as an instance(I tried it with the help of below code but got compile error). On the other hand, we can return this as an instance.
class A {
}
class B extends A {
public B methodThis() {
return this;
}
public A methodSuper() {
return super;
}
}
TL;DR - new SomeType() creates and allocates only one object, an instance of SomeType in the heap, and it doesn't create objects of entire chain of SomeType's parent classes. Members of the parent classes, however, are referenced dynamically at run-time. So, while you can access the super-class member with super keyword, it doesn't mean that instances of the super-classes are also created.
Details:
There are two important concepts to understand in order to fully answer your question:
When we instantiate an object of let's say type X, are the objects of its immediate parent and grandparent and etc. (entire hierarchy of the parent classes, starting from the type in question, until and including Object class) also created?
Due to the fact, that every constructor does an implicit call, as its first instruction, to its immediate parent class constructor with super(), some people think, that JVM's runtime system instantiates entire chain of the parent classes as well. If our class X extends Y and class Y extends Z, people think, that executing new X(); will implicitly execute new Y() (as constructor of X calls constructor of Y), then new Z();(as constructor of Y calls constructor of Z), and finally new Object(), as Object is the top-most super class of entire ecosystem in Java.
This assumption is wrong, as during the instantiation of the object new X(); only instance which gets created in the heap is the instance of class X. Hence, returning super from the object's method will not work, as there's no super-class instance, on the heap, to be returned;
If the parent classes are not instantiated, then how the members of the super classes are made available to the child class? are they copied to the derived child classes?
Not exactly copied, however, bytecode of the parent class members (fields, methods) [are referenced at run-time] from the child class1.
this represents the current instance of an object.
What do you think super would represent?
super is a reserved keyword in java and is used to call an implementation (of a method or constructor) of a base class.
public class A {
public int testVar = 300;
}
public class B extends A {
public int testVar = 400;
public int getSuper() {
return this.testVar; // returns 400
}
public int getThis() {
return super.testVar; // returns 300
}
}
Let's say I have three classes:
class A {
A() {
// super();
System.out.println("class A");
}
}
class B extends A {
B() {
// super();
System.out.println("class B");
}
}
class C extends B {
public static void main(String args[]) {
C c = new C(); //Parent constructor will get called
}
}
When I create an instance of class C, it calls the constructor of super class. So, is there more than one object that is getting created? If only one object is created, then how is super() like another class' constructor? Does super() method internally create an object? What I know is, the constructor is also a method (I may be wrong).
My questions are:
How many number of Object is created in this case?
If one object is created then how does Super() internally call the parent class constructor?
Great question. What you are probing is how Java initializes objects - and there are a number of steps involved.
i know is constructor is also a method (Maybe i am wrong).
Nearly right. The Constructor is a special method. If you decompile a class file, you'll see the constructors get renamed to <init>. <init> is treated differently from other methods and, for example, can't be called explicitly except through use of the keyword new or super. This is so fundamental that it is implemented in the JVM itself rather than being something defined in the Java language.
How many number of Object is created in this case.
One object is created - an instance of C.
C is additionally and simultaneously an instance of B and an instance of A and also Object.
If one object is created then how internally super() is calling Parent class Constructor . How Super is able to call parent class constructor.
This is where we get into initialization - initialization is how the JVM creates a new instance of an object and sets all the member values - those of the specific class and those of the superclasses. There are several stages involved:
Load all the referenced classes and initialize those classes. Class initialization is itself non-trivial so I won't cover it here. It is well worth reading up.
Allocate a chunk of memory for holding the members of the instance, which will include the all members of A, B and C. NOTE this explains one aspect of your question: how can the constructors of the base class and its subclasses update or refer to the same object - all the members of the instance from all classes are stored one after the other in the same chunk of memory.
Initialize all the members to their default value. For example, int and float members will be set to 0 and 0.0f.
Execute or calculate the member initializers, eg:
private int a = 10;
private int b = a * 5;
private String c = Singleton.getInstance().getValue();
Note (1) that member initialization occurs strictly in the order that members are declared in the class. This means that references to members later in the declaration are broken:
private int a = b * 5; // Forward reference; won't compile
private int b = 10;
Note (2) that there is a under-used facility in Java to run arbitrary code to initialize values before the constructor is executed. These code blocks are executed at this time again strictly in order of declaration:
private int a;
private int b = 1;
{
// Initization occurs after b but before c.
// c cannot be referenced here at all
int i = SomeClass.getSomeStatic();
a = i * 2;
}
private int c = 99;
Execute the constructor of C. Constructors must either directly invoke a constructor from the superclass or the compiler will automatically add super() as the first line of the constructor. This means that the constructors are strictly executed in order:
Object
A
B
C
The object is now initialized and is ready for use. You can do some dangerous stuff if you initialize value using instance methods:
public class Wrong {
int a = getB(); // Don't do this!
int b = 10;
public int getB() {
return b;
}
}
Here, a is initialized to 0. This is because, at the point getB() is invoked, Java has cleared the value of b to the default (0), but has not yet set it to 10 in the second phase of initialization.
In summary - there is only one object and it is created and initialized in a number in stages. During those stages, the object is, by definition, not completely defined.
There will be one and only one object will be created and ie. A object.
You can imagine like when class A extends B, then all methods and variables are copied to class A.
In Code only one object will be created and super call the parent class constructor .
Prove of object creation :
package one;
public class A {
public static A super_var;
public A() {
super_var = this;
System.out.println("Constrcutor of A invoked");
}
}
package two;
public class B extends A {
public static A sub_var;
public B() {
sub_var = this;
System.out.println("Constructor of B invoked");
}
public void confirm() {
if (sub_var == A.super_var)
System.out.println("There is only one object is created");
else
System.out.println("There are more than one object created");
}
public static void main(String Args[]) {
B x = new B();
x.confirm();
}
}
This will prove that there will be only one object created.
And about Super().
What I know that it call Parent class constructor . and each constructor ahve Super() as first statement like you mention in your code . so that you know
I don't know how it internally call super class constructor .
Hope this will make you understand there is only the instace you create in program
In your case only, 1 objects is getting created.
When subclasses constructor is called, it calls the constructor of super class internally to initailize super class's members.
Invoking constructor does not mean you are creating objects. Object is already created when invoking the constructor.The objects is created by the JVM first(i.e memory is allocated on heap and then constructor is called).
Constructor are meant for initializing the members of objects.
Your classes will be internally converted to something like this
class A
{
A(){
super();
System.out.println("class A");
}
}
class B extends A{
B(){
super();
System.out.println("class B");
}
}
public class C extends B
{
public static void main(String args[])
{
C c = new C(); //Parent constructor will get call
}
}
How many number of Object is created in this case.
Only one, which is instance of C, calling super() just invokes the constructor of parent class and doesn't create object
If one object is created then how internally Super() is calling Parent
class Constructor . How Super is able to call parent class
constructor.
When you create C's instance. C's constructor gets called, which first calls B's constructor, which in turn calls A's constructor
How many number of Object is created in this case.
When you create an instance of Class C by C cInstance = new C(); a single instance(Object) of Class C is creates(None of A and B). However since C extends B and B extends A, C will have all the methods of Class A and B(Actually depends on access modifiers used but lets say for this case they are public or default).
If one object is created then how internally Super() is calling Parent class Constructor
. How Super is able to call parent class constructor.
That is how inheritance works. When a new object is created it will call it's super class constructor and that super class will call it's super class constructor and so on. In other ordinary function you have to explicitly call super(). So calling super class constructor goes bottom-up fashion while execution goes top-down fashion of the inheritance hierarchy tree
If you look at dynamics of object allocation as per this SO answer, it must be clear that using new operator, you create only one object per statement. To further clarify the doubt that there is only one object which is being created, go thru this program:
public class A {
public static int aInstanceCount=0;
public static A aInstance;
public String aInstanceVariable;
A() {
//Super();
aInstanceCount++;
aInstanceVariable="aInstanceVar";
System.out.println("class A");
aInstance=this;
}
}
class B extends A {
public static int bInstanceCount=0;
public static B bInstance;
public String bInstanceVariable;
B() {
//Super();
bInstanceCount++;
bInstanceVariable="bInstanceVar";
System.out.println("class B");
bInstance=this;
}
}
class C extends B {
public static void main(String args[]) {
int instanceCount=0;
C c = new C(); //Parent constructor will get call
if(A.aInstance!=null){
instanceCount++;
System.out.println("Value of aInstanceVariable: "+A.aInstance.aInstanceVariable);
}
if(B.bInstance!=null){
instanceCount++;
System.out.println("Value of bInstanceVariable: "+B.bInstance.bInstanceVariable);
}
A a=A.aInstance;
B b=B.bInstance;
System.out.println("bInstanceVariable of B earlier: " + B.bInstance.bInstanceVariable);
//Now we are changing the bInstanceVariable of c which is inherited from B
c.bInstanceVariable="bInstance After modified by C";
System.out.println("bInstanceVariable of B after: " + B.bInstance.bInstanceVariable);
System.out.println("aInstanceVariable of A earlier: " + A.aInstance.aInstanceVariable);
//Now we are changing the aInstanceVariable of c which is inherited from A
c.aInstanceVariable="aInstance After modified by C";
System.out.println("bInstanceVariable of A after: " + A.aInstance.aInstanceVariable);
}
}
The output:
class A
class B
Value of aInstanceVariable: aInstanceVar
Value of bInstanceVariable: bInstanceVar
bInstanceVariable of B earlier: bInstanceVar
bInstanceVariable of B after: bInstance After modified by C
aInstanceVariable of A earlier: aInstanceVar
bInstanceVariable of A after: aInstance After modified by C
If you can notice, the super constructor is implicitly getting called each time if a subclass object is created, but since the new operator is used only once, there is only one object which is actually allocated the space. And by modifying the aInstanceVariable via C object c, we are actually changing the aInstanceVariable of aInstance. So it clearly proves that there is actually one object.
Steps of object creation when you call a constructor to create object:
Memory allocation using init is done. This init makes a system call to allocate memory for object creation.
Then your constructor is called to initialize the object's fields.
Then it calls super class constructor (If there's any super class) and Step 1 through 3 repeats.
What you see when you decompile a class file using javap shows different calls to be made. init makes system call to initialize memory allocation but object's field are initialized when constructor's code is run.
I am not sure how polymorphism/overriding works at the time of GC.
But it should be worth a try to override finalize method in all your classes and check when JVM exits main method.
If only C object is created, it should call finalize for 'C'.
If all A,B, C object is created, it should call finalize for A,B, C.
I think this is simplest check you can apply.
class A {
A() {
//Super();
System.out.println("class A");
}
public void finalize(){
System.out.println("Class A object destroyed");
}
}
class B extends A {
B() {
//Super();
System.out.println("class B");
}
public void finalize(){
System.out.println("Class B object destroyed");
}
}
class C extends B {
public static void main(String args[]) {
C c = new C(); //Parent constructor will get call
}
public void finalize(){
System.out.println("Class C object destroyed");
}
}
I agree with the previously posted answers, but want to add a reference to the ultimate authority on this issue, the Java Language Specification.
The expression new C() is a "Class Instance Creation Expression". Section 15.9.4 Run-time Evaluation of Class Instance Creation Expressions describes the run time steps involved in creating an object. Note that it refers to "the object", and only allocates space once, but states "Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type."
This all becomes much clearer by distinguishing between creating a new object, and invoking a constructor. Invoking a constructor only does part of object creation, the part that runs initializers, superclass constructors, and the body of the constructor. Because a C is also a B, the B constructor has to run during creation of a C.
The super keyword enables a subclass to call the methods and fields of its superclass. It is not an instance of the superclass object but a way to tell the compiler which methods or fields to reference. The effect is the same as if the subclass is calling one of its own methods.
Examples:
Consider a subclass Employee that extends its superclass Person:
public class Employee extends Person{
public Employee()
{
//reference the superclass constructor
super();
}
public String getName()
{
//reference superclass behaviors
return super.getFirstName() + " " + super.getLastName();
}
}
The super keyword can be used to reference the constructer of the Person class or any of the behaviors or fields that it has access to (e.g., getFirstName() and getLastName()).
In your Case One object is created
while doing the following, this super() will provided by Compiler Implicitly
class A {
A() {
System.out.println("class A");
}
}
class B extends A {
B() {
System.out.println("class B");
}
}
class C extends B {
public static void main(String args[]) {
C c = new C(); //
}
}
It is similar to calling a super() inside your methods
B() {
super();
System.out.println("class B");
}
The super keyword can also be used when a method is overridden in the current class, but you want to invoke the super class method.
super() will makes the all constructors reference to one class. (For easy understanding: Its like all the member functions are comes under a same class.)
Its going to call all the constructor methods only.
So its done the work of calling constructor only, so super() will not done any object creation. Its just referring the member functions.
If you add one more line of Code System.out.println(this.hashCode()) will remove your confusion.
Here in All Case hashCode() will print same hashCode all the time. It means there is one and only one unique Object is Created.
class A {
A() {
// super();
System.out.println(this.hashCode()); // it will print 2430287
System.out.println("class A");
}
}
class B extends A {
B() {
// super();
System.out.println(this.hashCode()); // it will print 2430287
System.out.println("class B");
}
}
class C extends B {
public static void main(String args[]) {
C c = new C(); //Parent constructor will get called
System.out.println(this.hashCode()); // it will print 2430287
}
}
but there is two Constructor is getting invoked to initialize the Parent member variable. I think if you know the concept of super() keyword which invokes the Constructor of parent Class and Initialize the member Variable of parent Class.
3 constructors will call
Code:
class A
{
A()
{
System.out.println("In A");
}
}
class B extends A
{
B()
{
System.out.println("In B");
}
}
class C extends B
{
C()
{
System.out.println("In C");
}
}
public class InheritanceTest {
public static void main(String args[])
{
C c1=new C();
}
}
Output:
In A
In B
In C
I have a class A with static field F:
class A {
public static String F = null;
}
Class B:
class B extends A {
public static String F = "somestring";
}
and a typed class with a method that uses field F:
class C<T extends A> {
public void someMethod() {
String someString = T.F;
// Manipulations with someString
}
}
And then my code that calls it.
C<B> c = new C<B>();
c.someMethod();
and I'm getting a null pointer exception when trying to manipulate with someString. So, the T.F is null, but T is B, so it should be "somestring"! Why?
You can't Override fields. Since it is extends A, it will always use the field in A.
Add a getter in class A and B that returns F. From there, Override the method in A with the one in B.
class A {
public String getF(){
return null;
}
}
class B {
#Override
public String getF(){
return "someString";
}
}
This doesn't have to do with generics.
The fields of a class cannot be overridden by a subclass - only methods can. So, even if you define a field in your subclass with the same name as the one in the superclass, you're merely creating a new field that simply happens to have the same name but actually shadows (not overrides) the previous one.
Consider putting an assignment with the default value of the field in the constructor of your subclass. Then it should work.
A static member in Java can be hidden, but not overridden. A reference to a static member is resolved at compile time - and at compile time, the only known type of T is A.
See http://www.coderanch.com/how-to/java/OverridingVsHiding.
Edit: A field cannot be overridden anyway, whether it is static or instance.
This happens because all the static members of A are common to A alone and cannot be inherited by B.
No new static member, which is not present in A, can be present in B.
Virtually, when you say
class C < T extends A > {
...
}
You can only use methods(both static and instance - unless #Overriden) and fields which are common in A. So, since F is not an instance field, it is not overriden and the JVM finds the occurance of F in A.
Hence you get an NPE.
I'd like to better understand what is the difference in referring to a class field by using this.field and field alone as in
this.integerField = 5;
and
integerField = 5;
this keyword refers to the current object.
usually we use this.memberVariable to diffrentiate between the member and local variables
private int x=10;
public void m1(int x) {
sysout(this.x)//would print 10 member variable
sysout(x); //would print 5; local variable
}
public static void main(String..args) {
new classInst().m1(5);
}
Off from the concrete question,
the use of this In Overloaded constructors:
we can use this to call overloaded constructor like below:
public class ABC {
public ABC() {
this("example");to call overloadedconstructor
sysout("no args cons");
}
public ABC(String x){
sysout("one argscons")
}
}
The use of this keywords lets you disambiguate between member variables and locals, such as function parameters:
public MyClass(int integerField) {
this.integerField = integerField;
}
The code snippet above assigns the value of local variable integerField to the member variable of the class with the same name.
Some shops adopt coding standards requiring all member accesses to be qualified with this. This is valid, but unnecessary; in cases where no collision exists, removing this does not change the semantic of your program.
When you are in an instance method, you may need to specify to which scope you refer a variable from. For example :
private int x;
public void method(int x) {
System.out.println("Method x : " + x);
System.out.println("Instance x : " + this.x);
}
While, in this example, you have two x variables, one is a local method variable and one is a class variable. You may distinguish between the two with this to specify it.
Some people always use this before using a class variable. While it is not necessary, it may improve code readability.
As for polymorphism, you may refer to the parent class as super. For example :
class A {
public int getValue() { return 1; }
}
class B extends A {
// override A.getValue()
public int getValue() { return 2; }
// return 1 from A.getValue()
// have we not used super, the method would have returned the same as this.getValue()
public int getParentValue() { return super.getValue(); }
}
Both keywords this and super depend on the scope from where you are using it; it depends on the instance (object) you are working with at run-time.
It's exactly the same. Because you often type this.xyz it's a shortcut that means the same thing if there is a field by that name and there isn't a local variable that shadows it.
Though they look and act the same, there is a difference when the same name is shared between a field and a method argument, e.g.:
private String name;
public void setName(String name){
this.name = name;
}
name is the passed parameter, and this.name is the proper class field.
Notice that typing this.... prompts you a list of all the class fields [and methods] in many IDEs.
From the Java tutorials:
Within an instance method or a constructor, this is a reference to the
current object — the object whose method or constructor is being
called. You can refer to any member of the current object from within
an instance method or a constructor by using this.
So, when you call a method within a object the call looks like this:
public class MyClass{
private int field;
public MyClass(){
this(10); // Will call the constructor with a int argument
}
public MyClass(int value){
}
//And within a object, the methods look like this
public void myMethod(MyClass this){ //A reference of a object of MyClass
this.field = 10; // The current object field
}
}
Why are we not able to override an instance variable of a super class in a subclass?
He perhaps meant to try and override the value used to initialize the variable.
For example,
Instead of this (which is illegal)
public abstract class A {
String help = "**no help defined -- somebody should change that***";
// ...
}
// ...
public class B extends A {
// ILLEGAL
#Override
String help = "some fancy help message for B";
// ...
}
One should do
public abstract class A {
public String getHelp() {
return "**no help defined -- somebody should change that***";
}
// ...
}
// ...
public class B extends A {
#Override
public String getHelp() {
return "some fancy help message for B";
// ...
}
Because if you changed the implementation of a data member it would quite possibly break the superclass (imagine changing a superclass's data member from a float to a String).
Because you can only override behavior and not structure. Structure is set in stone once an object has been created and memory has been allocated for it. Of course this is usually true in statically typed languages.
Variables aren't accessed polymorphically. What would you want to do with this that you can't do with a protected variable? (Not that I encourage using non-private mutable variables at all, personally.)
class Dad{
public String name = "Dad";
}
class Son extends Dad{
public String name = "Son";
public String getName(){
return this.name;
}
}
From main() method if you call
new Son().getName();
will return "Son"
This is how you can override the variable of super class.
Do you mean with overriding you want to change the datatype for example?
What do you do with this expression
public class A {
protected int mIndex;
public void counter(){
mIndex++;
}
}
public class B extends A {
protected String mIndex; // Or what you mean with overloading
}
How do you want to change the mIndex++ expression without operator overloading or something like this.
If you have the need to override an instance variable, you are almost certainly inheriting from the worng class.
In some languages you can hide the instance variable by supplying a new one:
class A has variable V1 of type X;
class B inherits from A, but reintroduces V1 of type Y.
The methods of class A can still access the original V1. The methods of class B can access the new V1. And if they want to access the original, they can cast themself to class A (As you see dirty programming provokes more dirty progrtamming).
The best solution is to find another name for the variable.
you can override a method,that is all right
but what do you mean by overriding a variable?
if you want to use a variable at any other place rather than super class
u can use super.
as in
super(variable names);
why do you want to override a variable?
i mean is there any need?
we can not overriding structure of instance variables ,but we ovverride their behavior:-
class A
{
int x = 5;
}
class B extends A
{
int x = 7:
}
class Main
{
public static void main(String dh[])
{
A obj = new B();
System.out.println(obj.x);
}
}
in this case output is 5.