Is it mandatory to call base class constructor in Java?
In C++ it was optional, so I am asking this.
When I extend ArrayAdapter, I get this error: "Implicit super constructor ArrayAdapter<String>() is undefined. Must explicitly invoke another constructor"
So, what is the purpose of calling base constructor? When I create object base class constructor will call & then it comes to derived right.
The no-args constructor is called implicitly if you don't call one yourself, which is invalid if that constructor doesn't exist. The reason it is required to call a super constructor is that the superclass usually has some state it expects to be in after being constructed, which may include private variables that can't be set in a sub-class. If you don't call the constructor, it would leave the object in a probably invalid state, which can cause all kinds of problems.
It's not necessary to call the no-args constructor of super class. If you want to call a constructor with args, user super keyword like show below:
super(arg1, ...);
Related
In other words,
If a superclass does not have a default constructor, any subclasses extending it must make an explicit call to one of the superclass' parameterized constructors. why so?
It would be nice if you could try explaining it using Java.
Assume that your superclass has a field something and a constructor which initializes that field based on a passed parameter. You cannot create a child instance without properly initializing the super class. And if there is no default constructor the compiler cannot implicitly make the call. Instead it now it needs a parameter value to pass and the compiler cannot figure that value out on its own, instead you as the programmer need to explicitly state which parameter to pass to what super constructor.
This question already has answers here:
Why call super() in a constructor?
(8 answers)
Closed 5 years ago.
I'm a Java beginner learning about Java compiler rules as below:
If the class has no super class, extend it to Object class
If the class has no constructor, add a default no-parameter constructor
If the first line of the constructor is not "super()" or "this()", add "super()" to call the default constructor of the super class.
I understand that all objects we create are derived from the super class Object.
My question is what does the constructor in the Object class do when called?
Edit: My question is about what the constructor does in the class Object? I'm aware that subclasses call superclass's constructor by default.
For example, I have the following code (where I explicitly extend to Object and call super() to illustrate what the compiler does). My question is, what does the call to super() do?
public class Person extends Object
{
private String name;
public Person(String n)
{
super();
this.name = n;
}
}
My question is, what does the call to super() do?
It calls the default constructor for java.lang.Object. And to answer what you seem to be really asking, from the Java Language Specification, #8.8.9
8.8.9. Default Constructor
If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:
The default constructor has the same accessibility as the class (§6.6).
The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor implicitly declares one formal parameter representing the immediately enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
The default constructor has no throws clauses.
If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
Note the final paragraph.
All Java classes that don't have any explicit superclass, extend from Object, except for Object itself. There's no need to make it explicit in your code, the compiler will take care of.
Also, the super() call in the constructor will invoke the constructor of Object. If you look at the implementation, you'll see that Object doesn't have any constructor at all, so it'll use an implicit empty constructor which does nothing. Details such as constructing a vtable to make sure that the inherited methods are there to use or initialising the object's monitor are not part of the constructor but are performed by the JVM implementation when the new operator is called.
public Object() {
}
The Object class has few methods that come handy in most of the classes. For example, the infamous toString() is implemented in the Object class. Also, the hashCode() is implemented there.
I'd recommend you to have a deep look at the Object.class file to understand what methods are inherited in every single Java class.
Regarding your 3 rules at the top, are "good" for academic purposes but never used in reality. You'll never see an explicit extends Object, and only call the super() or this() when you need to overwrite the default behaviour.
Also, avoid abusing of inheritance and use more composition (implement an interface), although, it depends on the every use case.
For example, I have the following code (where I explicitly extend to
Object and call super()). My question is, what does the call do
super() do?
Actually, Object() does nothing.
Now you should not reduce the constraint to invoke super() (with args or not) for any subclass constructor to the case where you have a class that doesn't extend a class explicitly.
This case is the only one where invoking super() may seem not really useful.
But as soon a class extends a class distinct from Object, this constraint makes really sense as the child construction has to apply first its parent construction.
But the language specifies this point in a general way. It has no exception for classes that extend directly Object.
Probably because, it makes things more simple and that is not a real constraint as the compiler adds for you the call to the super default constructor : super().
I want to extend ArrayAdapter but call
ArrayAdapter.createFromResource(context,textArrayResId,textViewResId);
instead of
super(context,textArrayResId,textViewResId)
inside myArrayAdapter constructor, but I'm always getting a there is no default constructor available in android.widget.ArrayAdapter error.
It looks like that having to call super is obligatory, so when I use it instead, the code compiles fine. Is what I ask to do possible ?
public class myArrayAdapter<CharSequence> extends ArrayAdapter {
public myArrayAdapter(Context context, int textArrayResId, int textViewResId) {
// super(context,textArrayResId,textViewResId);
ArrayAdapter.createFromResource(context,textArrayResId,textViewResId);
}
}
Parent class constructor must be called explicitly in this scenario. You may create static factory method for this purpose.
What are static factory methods?
From the JLS, § 8.8.7:
The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass
[...]
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
This means that a superclass-constructor must be called. The implicit call always refers to super(). If this constructor does not exist, one has to call a superclass constructor explicitly.
To answer your question: you have to call a constructor explicitly. Calling the static method does not help. You could, however, look at the code of createFromResource(...), which should somewhere end in a constructor call of ArrayAdapter.
The problem is that when you delete that line the compiler tries to create the super object using default constructor and since in your case your super class doesnt have any default constructor this wont work.
You are extending an object while you are not going to let it to be created !!!
You cant do this. You must call the super constructor in order for that to create an instance.
In your case you can delete extend ArrayAdapter So that it gets kinda a factory class that creates an object of ArrayAdapter type for you ;)
In java, can a contructor in a class call an overloaded constructor of its superclass (say if we wanted to make that call explicitly and deliberately). I know that a constructor in a class makes implicit call to no-arg default constructor of superclass ( with super (); ) . but suppose I make a call to an overloaded superclass constructor (say super(String s); ) , then my question is, Is this possible? And if this is possible, then is a call to super() still made ahead of super(String s)or not and what are its implications? Also can two constructors from same class one no-arg and one overloaded call each other? Will they be caught in a loop if they do so?
You can get the answer in its official tutorial:
https://docs.oracle.com/javase/tutorial/java/IandI/super.html
Read this specifically:
The syntax for calling a superclass constructor is
super();
or:
super(parameter list);
With super(), the superclass no-argument constructor is called. With super(parameter list), the
superclass constructor with a matching parameter list is called.
Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the
no-argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem. If a subclass constructor invokes a
constructor of its superclass, either explicitly or implicitly, you
might think that there will be a whole chain of constructors called,
all the way back to the constructor of Object. In fact, this is the
case. It is called constructor chaining, and you need to be aware of
it when there is a long line of class descent.
So to answer your question:
Yes, it is possible, and doable. When you explicitly invoke super constructor with arguments, then only that constructor is invoked.
And, make sure the super constructor invocation is the first line in your constructor, otherwise a compiler error will show.
*****EDITED*****
And, you invoke one specific super class constructor, implicitly or explicit, only. When that superclass constructor is called no other superclass constructors are called, unless it is called within your called superclass constructor. Meanwhile, it is not possible to compile if in the same class multiple constructors call each other recursively - it will be rejected by your compiler.
Hope this helps.
I saw this question in one of my question papers:
Why should the derived class constructor always access base class constructor?
I'm wondering whether the question is valid?
So that you may have a valid object of type "Base" before you start messing with the inherited functionality in your derived object!
It's not valid. There's no 'should' about it: it must, and the compiler enforces it, by calling the base class's default constructor if it exists, and giving you a compile error if it doesn't, which forces you to call one of the existing constructors.
There is one exception to always, a default constructor in a superclass isn't usually called explicit.
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.
Because the base class may do work you are not aware of.
Because the base class may have members that require initialization.
Since the derived class constructor wants to inherits from the base class constructor, it is necessary to call the base class constructor. Otherwise, if you don't, you will not inherit values initialised in base class constructor.
Calling a superclass constructor is not a must but a should paired with a strong advise - as long as the superclass has a default constructor. Otherwise the compiler forces you to call at least one of the superclasses constructors.
If the default constructor is present, it's called anyway, even without an explicit super() statement in the subclasses construtor.
A visible part of class construction is the initialization of fields. But there's more under the hood (memory allocation, registration, etc). All this has to be done for all superclasses when a derived class is created.
You do not need to call constructor when there is a default constructor (i.e a no-argument constructor) present in the base class. When there is a constructor with arguments present and no default constructor, then you don't need to declare a constructor in the child class.
You only need to initialize the child class constructor when there is no default constructor present in the parent class.
Example :
class A {
public int aInstanceVariable;
public A(int aInstanceVariable) {
this.aInstanceVariable = aInstanceVariable;
}
}
class B extends A {
// In this case we have to call super in base class constructor
}
However, when public A() {} is present in class A, there is no need to initialize the child class constructor.