This question already has answers here:
Why do we assign a parent reference to the child object in Java?
(11 answers)
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
I am so confused in this topic.
//a class (lets say B) extendes or implements another class or interface respectively
interface myInterfaceA{
int interfaceDataMember1;
int interfaceDataMember2;
void interfaceMethod1();
void interfaceMethod2();
}
class myClassA{
int parentClassDataMember1;
int parentClassDataMember2;
myclassA(){}
void parentClassMethod1(){}
void parentClassMethod2(){}
}
//case1
class B implements myInterfaceA{
int dataMember1;
int dataMember2;
B(){}
void method1(){}
void method2(){}
}
// OR case2
class B extends myClassA{
int dataMember1;
int dataMember2;
B(){}
void method1(){}
void method2(){}
}
// so in either case what is the purpose of creating the object of class B in the following way
myInterfaceA objectB = new B();
// or
myClassA objectB = new B();
1) is there any name of this procedure?
2) what (data memeber, methods, constructor ) will be loaded in objectB?
3) if all the code of class B will be loaded in the objectB then why did we give the refrece of interface or parent class?
4) is this shows polymorphism? if yes, then why?
5) in case2 will class B also inherit the constructor of myClassA
6) why the constructor of parentclass is also called whe we create child class object
1) is there any name of this procedure?
This is polymorphism.
2) what (data memeber, methods, constructor ) will be loaded in
objectB?
Every data member and method will be inherited by the objectB.
In case of interfaces, the data members are private, static, final constants. They must be initialized in the constructor. The methods must be implemented by the class B.
In case of superclasses, the data members and methods are simply inherited. You can override the methods. Variables are not polymorphic.
3) if all the code of class B will be loaded in the objectB then why
did we give the refrece of interface or parent class?
We give reference of interface or parent class so that in case of multiple subtypes, we can have a single method that accepts supertype instead of creating multiple methods. This reduces lines of code and makes the code readable.
4) is this shows polymorphism? if yes, then why?
This shows polymorphic behaviour so you don't need to bind each subtype to a different method. A single method can be written to dynamically bind all the subtypes of a single supertype.
5) in case2 will class B also inherit the constructor of myClassA
The constructor is not inherited. You must call explicitly super() if required.
6) why the constructor of parentclass is also called whe we create
child class object
It is not mandatory to call the constructor of the parentclass everytime. You may skip it if it is not required. But as a standard practice, super() is the first line of the child class constructor, so that any changes in the super class object creation does not affect child class.
Interfaces (and implementing them) only dictate what method signatures the inheriting class must have. The only thing that is 'copied', ie available as methods, are default methods since Java 8
Extending from a class (or abstract class) is a whole different story, although it also can dictate what method signatures are to be implemented by the inheriting class.
But here, all data is not copied, but available, to the calling interface.
Interfaces are used to standardise behaviour (treat dogs and birds as pets), abstract classes to standardise behaviour AND provide implementations (let budgie and cockatoo fly)
package zoo;
import java.util.ArrayList;
interface Pet {
void printName();
}
abstract class Bird implements Pet {
public void fly() {
System.out.println("I (" + getClass().getSimpleName() + ") am flying");
}
}
class Dog implements Pet {
#Override public void printName() {
System.out.println("Hans");
}
}
class Budgie extends Bird {
#Override public void printName() {
System.out.println("Jockl");
}
}
class Cockatoo extends Bird {
#Override public void printName() {
System.out.println("Zenzi");
}
}
public class AnimalSchool {
public static void main(final String[] args) {
final Dog d = new Dog();
d.printName();
final Budgie b = new Budgie();
b.printName();
b.fly();
final Cockatoo c = new Cockatoo();
c.printName();
c.fly();
final ArrayList<Pet> pets = new ArrayList<>();
pets.add(d);
pets.add(b);
pets.add(c);
for (final Pet pet : pets) {
System.out.print("\nPet is a " + pet.getClass().getSimpleName() + " and is called ");
pet.printName();
}
final ArrayList<Bird> byrdies = new ArrayList<>();
// byrdies.add(d); this will not compile, as it is not a bird
byrdies.add(b);
byrdies.add(c);
for (final Pet pet : byrdies) {
System.out.print("\nBird is a " + pet.getClass().getSimpleName() + " and is called ");
pet.printName();
}
}
}
To answer your question.
It is called polymorphism
In object B using case 1, B will be forced to implement myInterfaceA methods also your class B cannot have unimplemented methods except you declare the class as abstract thus:
class B implements myInterfaceA{
int dataMember1;
int dataMember2;
B(){}
public void method1(){
}
public void method2(){
}
//interface methods
public void interfaceMethod1(){
}
public void interfaceMethod2(){
}
}
Hence class b will have properties of the interface and that of itself as well as methods it has implemented.
Using case 2 B will however be implemented like this. (Assuming a is not an abstract class, thus it's methods will be implemented not declared like interface methods or abstract class method)
class B extends myClassA{
int dataMember1;
int dataMember2;
B(){
super();
}
public void method1(){
}
public void method2(){
}
}
notice that an explicit call may be made to the super class constructor
we give the reference to the interface/parent class because we want to have a single implementation where the super type is passed and the implementation is used for cases where there are many subtypes
Yes, it is polymorphic so that we can have different behaviours and implementations of the super type.
As i said earlier, an explicit call will be made to the super class constructor
It is standard practice to call the superclass constructor so that changes to it will not affect the subclass
Related
I want to call the constructor of a class inside the method of an interface.
For example, if I have two classes B and C and they both implement SomeInterface, so that each of them has method foo().
interface SomeInterface {
public SomeInterface foo();
}
class B implements SomeInterface {
public B(int fst, int snd) {}
#Override
public SomeInterface foo() {
return new B(1, 1);
}
}
class C implements SomeInterface {
public C(int fst, int snd) {}
#Override
public SomeInterface foo() {
return new C(1, 1);
}
}
And let's say, for the sake of this question, that I have a lot more classes that implement SomeInterface and they all do the same thing, that is return new <nameoftheclass>(1,1)
and all these classes extend the parent class A.
Is there a way for me to create only one method in A such that if any of these classes use the foo method that is found in A it will call their constructor and just like that save me lines of code?
You can do something like this with reflection, although it will be prone to failure.
public SomeInterface foo() {
Constructor<? extends SomeInterface> c = getClass().getConstructor(int.class, int.class);
return c.newInstance( 1, 1);
}
You'll have to manage some exceptions, but is this what you're after?
The question would then be, where can this be used? Interfaces don't have a common constructor.
public interface SomeInterface{
default SomeInterface another(){
Constructor<? extends SomeInterface> c = getClass().getConstructor(int.class, int.class);
return c.newInstance( 1, 1);
}
}
That would work provided whatever the implementations try to use it have that constructor. There is no guarantee that constructor exists though. Maybe you would want it on an abstract class?
use the foo method that is found in A it will call their constructor and just like that save me lines of code?
You are getting it wrong. Class design decisions must be based on use cases and relationships of the classes in your domain. If your main criteria will be to spare some lines of code, you can end up with a coffee machine extending combine harvester because both of them have tree dimensions. Don't take a pill if you have no headache.
Parent class A that you've mentioned doesn't make any sense because method foo() returns an instance of SomeInterface interface which A doesn't implement (because if it does, its subclasses don't need to declare to implement it). I.e. A and SomeInterface are not compatible and compiler will not allow to type cast between them. Therefore, I'll omit the parent class.
As an example, the "template" you've provided might be useful, will be a situation when classes with similar functionality need to grouped together.
The interface can serve as a single entry point for the user of the code. Every class will implement the behavior defined by the interface, and only through the interface it'll be possible to get an instance of the class with a particular flavor of functionality. The actual classes will be hidden from the user.
Similarly, abstract class NumberFormat from the JDK provides a way to obtain different kinds of formatters, but actual implementations are hidden are not exposed (the approach shown below is far more simple than the actual way of how factory methods of the NumberFormat are implemented).
Note, interface and its implementations must reside in the same package.
public interface BaseInterface {
public static BaseInterface getInstance(Classifier classifier) { // factory
return switch(classifier) {
case A -> new A();
case B -> new B();
};
}
void doSomeThingUseful(); // behaviour that every class should implement
}
enum Classifier { A, B }
class A implements BaseInterface {
A() {}
#Override
public void doSomeThingUseful() {
System.out.println("Class A");
}
}
class B implements BaseInterface {
B() {}
#Override
public void doSomeThingUseful() {
System.out.println("Class B");
}
}
main() - demo
public static void main(String[] args) {
List<BaseInterface> items = List.of(BaseInterface.getInstance(Classifier.A),
BaseInterface.getInstance(Classifier.B));
for (BaseInterface item: items) {
item.doSomeThingUseful();
}
}
Output
Class A
Class B
I'm having trouble wrapping my head around the concept of super(). Java Tutorials gives this example:
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
But if I am overriding the printMethod, why do I need to invoke the Superclass method? Why can't I just write whatever in the Subclass method of printMethod() and just move on?
There is absolutely no need to call the super.
It just helps you to call the logic contained within super class method if you require that.
Many times you want the exact logic to run and then provide your additional logic.
Overriding always does not mean providing brand new logic. Sometimes you want to provide a slight variation. For e.g., if the method returns a value, then you call the super class method and get the value. Then you make some slight modification in that object using logic in the sub class method and return it back to caller.
You can override it. In that case, the parent method is ignored. super() is used if you want the parent method to be executed in the subclass.
This is used to avoid duplicated code. Let's say you have a class:
public class SuperClass() {
private int var1;
private int var2;
private int var3;
public SuperClass() {
var1 = 1;
var2 = 2;
var3 = 3;
}
}
and a subclass:
public class SubClass() {
private int var1;
private int var2;
private int var3;
private int var4;
public SubClass() {
super();
var4 = 4;
}
}
In this example, you are using super() to invoke superclass constructor (constructor are usually used to initialize members) so you can focus on the SubClass members, and you don't have to repeat all the initialization lines (for var1, var2 and var3).
Basically the super class is the upper most level of the program. When you create a new subclass you must "inherit" from the super class using the keyword 'extends'. This does 2 things; It allows you to use any methods created in the super class, in the subclass and it also allows you overwrite methods in the super class. Basically, if you have one method you want to use in a bunch of classes you use the super class to create it and then the sub-classes can just call the method using standard dot notation.
If you just run this program, Inside PrintMethod of the subclass will call to super class "printMethod" (print "Printed in Superclass") and then execute the things you have written in the sub class method(print "Printed in Subclass").
public void printMethod() {
//super.printMethod(); // comment this line
System.out.println("Printed in Subclass");
}
if you run like this, it will print only the things that you have written in the sub class method.
Idea is, If you want use Super class method information in the sub class, then you can call like Super.MethodName().
Clear Explanation :
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
Subclass s = new Subclass();
(i) when we are creating sub class object what wiill happens?
constructor of subclss will be executed
(ii) Do we have any costructor in sub class (Subclass )
if we have dat will execute..
but we are not having so default costructor will excecute
(iii) what default costructor will have?
Subclass (){
super();
}
(iv) what super() will do?
it calls super class contructor
in super class also we are not having constructor so
will execute default constructor
Superclass(){
super();
}
super class of superclass is Object class
so Object class is the super class of evry class in java
so it will creates object of object class..
object of Object class created
|
and comes to its subclass constructor...//step (iv)
Superclass(){
super(); // executed
}
object of Object class created
|
object of Superclass craeted
so super class constuctror execution also completed so
it will creates Object of SuperClass..
then control comes to its subclass conctructor // step (iii)
so Subclass (){
super(); // executed
}
after completion of subclass constructor it creates the object of subclass
*Important point : after completion of constructor execution
Object of thet class will be created*
object of Object class created
|
object of Superclass craeted
|
object of Subclass craeted
all this happened because of Subclass s = new Subclass();
so when you created object of sub class 3 objects are created..
s.printMethod();
now you are calling a method on subclass object
^
printMethod() is there in super class and sub class
when u r calling a method on sub class object what happens?
(i) it will search for that method in outer most objest: Object of Object class
so now printMethod() is not there in object of object class
(ii) Next its searches in next superclass object ie. object of Superclass
object Superclass object having printMethod() method
(iii) so method found...eventhougth method found controll serches in next sub most object is object of subclass object....
(iv) two methos found in two object but it excecutes sub most object method.
so sub most object is Subclass object...
so it executes the subclass printMethod() method.
Note: when we call a method on object it will executes the sub most objects method if ovverriden.....
now our method is....
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
first line in this method is super.printMethod();
by default super ponts to super class object : object of Superclass
object of Superclass .printMethod() is
public void printMethod() {
System.out.println("Printed in Superclass.");
}
so prints :
Printed in Superclass.
next line is : System.out.println("Printed in Subclass");
so it prints : Printed in Subclass
Note : first while creating object it called super class constructor..
now in method called super class method..
Note:
1.if class not having any constructor jvm assigns default constructor as
ClassName(){
super(); calls super class constructor
}
if class alrdy having constructor
the first line of the constructor should be the super() call.
for example: class A{
int variablea;
A(int a){
variablea=a;
}
public static void main(String[] args) {
A a=new A(2);
}
}
in this example
A(int a){
variablea=a;
} code replaces with
A(int a){
super(); by jvm by default
variablea=a;
}
You can use super in a subclass to refer to its immediate superclass. Super has two general forms.
to call the super class's constructor from the subclass
to access a member of the superclass from the subclass
I'm assuming that you are trying to understand the second one.
An example which might make you understand how super helps in referencing members of the super class:
public class Human {
String name;
int age;
public void printDetails() {
System.out.println("Name:"+name);
System.out.println("Age:"+age);
}
}
public class Student extends Human {
int rollNumber;
String grade;
public void printDetails() {
super.printDetails();
System.out.println("Roll Number:"+rollNumber);
System.out.println("Grade:"+grade);
}
public void printNameAgeAndSayGoodMorning(){
super.printDetails();
System.out.println("Good morning!");
}
public static void main(String[] args) {
Student s = new Student();
s.name="MyName";
s.age=27;
s.rollNumber=3;
s.grade="A+";
s.printDetails();
System.out.println(); //just an empty line
s.printNameAgeAndSayGoodMorning();
}
}
I avoided constructors or any getter/setter methods for simplicity.
In this example, do you think you really have to "just write whatever in the Subclass" instead of reusing the printDetails() method available in the super class?
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
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use of ‘super’ keyword when accessing non-overridden superclass methods
I'm new to Java and have been reading a lot about it lately to get more knowledge and experience about the language. I have a question about inherited methods and extending classes when the compiler inserts automatic code.
I've been reading that if I create class A with some methods including lets say a method called checkDuePeriod(), and then create a class B which extends class A and its methods.
If I then call the method checkDuePeriod() within class B without using the super.checkDuePeriod() syntax, during compilation will the compiler include the super. before checkDuePeriod() or will the fact that the compiler includes the super() constructor automatically when compiling the class imply the super. call of the methods that class B calls from class A?
I'm a little confused about this. Thanks in advance.
The super class's implementation of regular methods is not automatically invoked in sub classes, but a form of the super class's constructor must be called in a sub class's constructor.
In some cases, the call to super() is implied, such as when the super class has a default (no-parameter) constructor. However, if no default constructor exists in the super class, the sub class's constructors must invoke a super class constructor directly or indirectly.
Default constructor example:
public class A {
public A() {
// default constructor for A
}
}
public class B extends A {
public B() {
super(); // this call is unnecessary; the compiler will add it implicitly
}
}
Super class without default constructor:
public class A {
public A(int i) {
// only constructor present has a single int parameter
}
}
public class B extends A {
public B() {
// will not compile without direct call to super(int)!
super(100);
}
}
If you call checkDuePeriod() in B without super., means you want to invoke the method that belongs to the this instance (represented by this within B) of B. So, it equivalent to saying this.checkDuePeriod(), so it just doesn't make sense for the compiler to add super. in the front.
super. is something that you must explicitly add to tell the compiler that you want to call the A's version of the method (it is required specially in case B has overridden the implementation provided by A for the method).
Call of super() as a default constructor (constructor with no args) can be direct or non direct but it garants that fields of extendable class are properly initialized.
for example:
public class A {
StringBuilder sb;
public A() {
sb = new StringBuilder();
}
}
public class B extends A {
public B() {
//the default constructor is called automatically
}
public void someMethod(){
//sb was not initialized in B class,
//but we can use it, because java garants that it was initialized
//and has non null value
sb.toString();
}
}
But in case of methods:
Methods implement some logic. And if we need to rewrite logic of super class we use
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
//new check goes here
}
}
and if we want just implement some extra check, using the value returned from checkDuePeriod() of superclass we should do something like this
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
if(super.checkDuePeriod()){
//extra check goes here
}else{
//do something else if need
}
return checkResult;
}
}
First about the Constructors:
- When ever an object of a class is created, its constructor is initialized and at that time immediately the constructor of its super-class is called till the Object class,
- In this process all the instance variables are declared and initialized.
- Consider this scenario.
Dog is a sub-class of Canine and Canine is a sub-class of Animal
Now when Dog object is initialized, before the object actually forms, the Canine class object must be form, and before Canine object can form the Animal class object is to be formed, and before that Object class object must be form,
So the sequence of object formed is:
Object ---> Animal ---> Canine ---> Dog
So the Constructor of the Super-Class is Called before the Sub-Class.
Now with the Method:
The most specific version of the method that class is called.
Eg:
public class A{
public void go(){
}
}
class B extends A{
public static void main(String[] args){
new B().go(); // As B has not overridden the go() method of its super class,
// so the super-class implementation of the go() will be working here
}
}
Java does not allow multiple inheritance, meaning that a class cannot inherit from two classes, which does not have anything in common, meaning that they are not on the same inheritance path. However, a class can inherit from more classes, if these classes are super classes of the direct super class of the class. But the class inherits from these classes indirectly, meaning that it does not "see" anything from these upper super classes, right? I was confused when considering constructors (using super() in the constructor). For example, if we have the following classes:
public class A {
public A() {
....
}
}
public class B extends A {
public B() {
super();
....
}
}
public class C extends B {
public C() {
super();
....
}
}
the constructor of class C invokes first the constructor of class B using super(). When this happens, the constructor of B itself invokes first the constructor of A (with super()), but the constructor of C does not know anything about the constructor of A, right? I mean, the inheritance is only from the direct super class - the first (nearest) class from the inheritance hierarchy. This is my question - with super() we mean only the constructor of the direct super class, no matter how many other classes we have in the inheritance hierarchy.
And this does not apply only for constructors, but for any methods and instance variables..
Regards
You have to invoke some constructor in your immediate base class. This can be
public class A {
public A() {
....
}
public A(String foo) {
....
}
}
public class B extends A {
public B() {
super();
.. or ..
super("ThisIsAB")
}
}
public class C extends B {
public C() {
super();
....
}
}
So for constructors you cannot AVOID constructing your intermediate base classes, but you can choose which constructor to use. If there is only the no-args constructor it's all handled for you with an implicit call to super. With multiple constructors you have some more choices.
super can refer to any non-private variable or method in any base class. So methods and variables are not the same as constructors in this respect.
Even if you could avoid calling the intermediate ctor, you wouldn't want to, because that would mean you had uninitialized pieces of the intermediate classes that might be acessed by the bottom-most derived class. To horrible effects.
But I sense that you're trying to trick your way around Java to do multiple inheritance. That is a Bad Thing. Instead, you can do it Java-wise by using an interface
class B extends A implements C {
// ... implement C methods here
}
or by using aggregation
class B extends A {
private C c;
}
Constructors for all parents are called. In fact, deep down C knows about A because B extends A. For example, if the class A contained method foo(), then you could call foo() from C.
So from your example, C calls the constructor from B, which calls the constructor from A. Additionnally, A also extends from the class Object. So the constructor in the class Object is also called!
Furthermore, you do not need to add a call to super(). If there is no call for the constructor of the parent, super is call implicitly.
As you say, C's constructor invokes B's constructor which invokes A's constructor. You can call any "A" methods on a C object, and a C object can see non-private fields in A.
Even if you override A's method "foo" in C, you can get the A version with "super.foo()", assuming B doesn't also override it.
As far as C knows, anything that it does not overwritten in C is contained in B, even if under the covers class A is where the implementation might be.
public class A {
public A() {
}
public void aMethod() {
}
}
public class B extends A {
public B() {
super();
}
}
public class C extends B {
public C() {
super();
}
public void doWork() {
super.aMethod();
}
}
So in this case A handles the implementation of aMethod(), even though calling super() in C's constructor called B's constructor directly, not A's.