Default constructor can be overloaded in a subclass? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This is question (and answer) from OCJP test exam. And I was very confused about it.
Here is a question review (on Kaplan SelfTest site):
Reviewing Answered
Item 64 of 90Ref: 1Z0-803.6.5.6
Which statement is true about constructor overloading?
A default constructor can be overloaded in the same class.
A default constructor can be overloaded in a subclass.
The constructor must use a different name.
The constructor must use the this keyword.
Explanation:
A default constructor can be overloaded in a subclass. If no constructor is defined for a class, then the compiler will automatically provide the default constructor. Because a subclass can define its own constructors without affecting the superclass, a constructor with parameters can be defined that invokes the superclass constructor, implicitly or explicitly.
A default constructor cannot be overloaded in the same class. This is because once a constructor is defined in a class, the compiler will not create the default constructor. Thus, an attempt to overload the default constructor will effectively remove it from the class.
The constructor must not use a different name. In the same class, an overloaded constructor uses the same name. Because subclasses differ in name from their superclass, an overloaded constructor will have a different name.
The constructor does not need to use the this keyword. The this keyword allows a constructor to reference other constructor methods and/or instance context. Using the this keyword is not required in an overloaded constructor.
Objective:
Working with Methods and Encapsulation
Sub-Objective:
Create and overload constructors

You are getting your terminology wrong.
Overloading only takes place for methods with the same name but different parameters within a specific class.
Overriding takes place for subclasses which have methods with the same "signature" (same name and parameters) as a method in the Superclass.
Note that constuctors aren't "Overridden" (by definition they have different signatures than methods in the superclass).
Instead, the compiler makes a constructor implicitly call the default constructor of its superclass (if one exists) unless you explicitly call a specific constructor of a superclass using the super keyword.
Similarly you cannot "Overload" the constructor of a superclass in a subclass (overloading doesn't work across inheritance), but you can "overload" another constructor within your specific class.
Here is an example of implicit and explicit calls to superclass constructors and overloading constructors:
public class X {
// no default constructor defined so
// compiler adds implicit default constructor here: public X(){}
}
public class Y extends X {
// explicitly declared default-constructor for class Y
public Y() {
// compiler automatically calls implicit X default constructor here
System.out.println("constructing a Y instance");
}
// explicitly declared constructor which overloads the default constructor for Y
public Y(String s) {
// compiler automatically calls implicit X default constructor here
System.out.println("constructing a Y instance with param " + s);
}
}
public class Z extends Y {
// explicitly declared default constructor for Z
public Z() {
super("Z"); // explicitly call the non-default constructor in Y here
System.out.println("constructing a Z instance");
}
}
thus constructing a Z ends up calling X(), then Y("Z") and results in this output:
Z z = new Z();
// outputs: constructing a Y instance with param Z
// constructing a Z instance
And from the docs: (http://docs.oracle.com/javase/tutorial/java/IandI/super.html)
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.
Hope that helps clarify things for you. If in doubt read the docs, write some code, and use System.out.println() to see what's happening.

Constructors are not technically member functions, so they aren't really inherited, and thus cannot be "overloaded". However, they can still be called from the subclass using the super keyword.
//the class being inherited
public class superclass
{
//the constructor
public superclass(some_parameter)
{
//do stuff
}
}
public class subclass extends superclass
{
public subclass(some_parameter)
{
//the super keyword here is used to access the inherited class
super(some_parameter); //this calls the constructor of the inherited class;
}
}

First, overload is not the same as override. Example:
class Foo {
void overloadedMethod() {}
void overloadedMethod(int i) {}
void overridenMethod() {}
}
class Bar extends Foo {
#Override
void overridenMethod() {}
}
Constructor can be overloaded, just as ordinary methods, but cannot be overriden.
For more info see here: link

Related

super class not having a no-argument constructor [duplicate]

This question already has answers here:
I don't understand this part in Oracle docs?
(4 answers)
Closed 3 years ago.
According to Oracle's documentation https://docs.oracle.com/javase/tutorial/java/IandI/super.html, its written that If the super class does not have a no-argument constructor, you will get a compile-time error.
But in my case, I have a super class without any constructor. In my baseclass, I am writing super() in its no-arg constructor. Here, I don't have a no-arg constructor in super class, but its not showing any error.
class Person {
}
/* subclass Student extending the Person class */
class Student extends Person {
Student() {
// invoke or call parent class constructor
super();
System.out.println("Student class Constructor");
}
}
// Driver class
class Practice {
public static void main(String[] args) {
Student s = new Student();
}
}
This assumption is wrong:
Here, I don't have a no-arg constructor in super class, but its not showing any error.
If a class has no explicit constructor then it will have an implied no-argument constructor.
Please check out this related Stack Overflow question for more: Java default constructor
Also check out the Java Language Specification: §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.

Does the JVM internally instantiate an object for an abstract class?

I have an abstract class and its concrete subclass, when I create an object of subclass it automatically calls the super constructor. Is the JVM internally creating an object of the abstract class?
public abstract class MyAbstractClass {
public MyAbstractClass() {
System.out.println("abstract default constructor");
}
}
public class ConcreteClass extends MyAbstractClass{
public static void main(String[] args) {
new ConcreteClass();
}
}
then how constructor exists without an object in JVM ?? (In case of abstract class)
Also constructor gets executed after object is being created then without creating the object of abstract class how the default constructor get executed ?? (This is mentioned in Java Doc)
Is it true that you can't instantiate abstract class?
Yes.
Is JVM internally create object of abstract class ?
No, but it's a common misunderstanding (and that wouldn't be an unreasonable way for it to be done; prototypical languages like JavaScript do it that way).
The JVM creates one object, which is of the class you created (in your case, ConcreteClass). There are aspects of that one object that it gets from its superclass (MyAbstractClass) and from its subclass (ConcreteClass), but there is only one object.
The object is an aggregate of all of its parts, including parts that seem to have the same name, such as a method of the superclass that is overridden by the subclass. In fact, those methods have different fully-qualified names and don't conflict with one another, which is why it's possible to call the superclass's version of an overridden method.
So if it's just one object, why do you see the call to MyAbstractClass's constructor? Before we answer that, I need to mention a couple of things the Java compiler is doing that you don't see in the source code:
It's creating a default constructor for ConcreteClass.
In that constructor, it's calling the MyAbstractClass constructor.
Just to be thorough: In the MyAbstractClass constructor, it's adding a call to the superclass's (Object) constructor, because there's no super(...) call written within the MyAbstractClass constructor.
Here's what the code looks like with the bits the Java compiler adds for you filled in:
public abstract class MyAbstractClass {
public MyAbstractClass() {
super(); // <== The Java compiler adds this call to Object's constructor (#3 in the list above)
System.out.println("abstract default constructor");
}
}
public class ConcreteClass extends MyAbstractClass{
ConcreteClass() { // <== The Java compiler adds this default constuctor (#1 in the list above)
super(); // <== Which calls the superclass's (MyAbstractClass's) constructor (#2 in the list above)
}
public static void main(String[] args) {
new ConcreteClass();
}
}
Okay, with that out of the way, lets touch on a point TheLostMind very usefully mentioned in a comment: Constructors don't create objects, they initialize them. The JVM creates the object, and then runs as many constructors (they really should be called initializers) against that one object as necessary to give each superclass a chance to initialize its part of the object.
So in that code, what happens (and you can step through this in a debugger to fully understand it) is:
The JVM creates an object
The ConcreteClass constructor is called
The first thing that constructor does is call its superclass's constructor, in this case MyAbstractClass's constructor. (Note that this is an absolute requirement: The Java compiler will not allow you to have any logic in the constructor itself prior to the superclass constructor call.)
The first thing that constructor does is call its superclass's constructor (Object's)
When the Object constructor returns, the remainder of the MyAbstractClass constructor runs
When the MyAbtractClass constructor returns, the remainder of the ConcreteClass constructor runs
The object is returned as the result of the new ConcreteClass() expression.
Note that the above would get more complicated if there were instance fields with initializers. See the JLS and JVM specs for the full details.
JVM doesn't create object of abstract class. it is calling its super constructor
JVM will create one object, an instance of the concrete class which inherits fields and methods of abstract class

Java error: Implicit super constructor is undefined. Must explicitly invoke another constructor [duplicate]

This question already has answers here:
Java error: Implicit super constructor is undefined for default constructor
(12 answers)
Closed 4 years ago.
I have a BaseClass in a external jar, it has a constructor setting Implementation class(JerseyClientImpl) to jerseyClient.
public BaseClass(AuthDetails auth, String ID) {
setListID(D);
this.jerseyClient = new JerseyClientImpl(auth);
}
I am extending the BaseClass to set my own Implementation class to jerseyClient , but i am getting the error mentioned. Changing the BaseClass to add default constructor is not in my control as i said its an external jar.Can you suggest how can i overcome this error.
Since BaseClass has a non default constructor, it doesn't have the automatically generated parameterless default contstructor.
Therefore your sub-class can't rely on the default constructor (since it won't be able to call the non-existing default constructor of the base class), so your sub-class must have an explicit constructor that calls the constructor of the base class.
Either a constructor with the same parameters :
public SubClass(AuthDetails auth, String ID) {
super(auth,ID);
...
}
Or a constructor without parameters that gives default values for the base-class's constructor :
public SubClass() {
super(null,"something");
...
}
In Java, if you don't explicitly provide a call to a superclass constructor as the first statement in a constructor, then it will insert an implicit call to the default superclass constructor. If there is no default superclass constructor, then you get the error you have mentioned.
The JLS, Section 8.8.7, states:
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.
You must explicitly call the superclass constructor, passing all arguments, with something like this:
public JerseyClientImpl(AuthDetails auth, String ID) {
super(auth, ID);
// Rest of constructor code
}
First of all, if you are writing some parameterized constructor in a class...the default no arg constructor of the class does not exist anymore.
And, when you try to create constructor of its child class, the no-arg constructor of parent class is always called first.If it doesn't exist, you get compiler error.
So, define the no arg constructor in your parent class, OR just call the parameterized constructor of parent class with some value inside the child class constructor.

Behavior when a Subclass doesn't invoke superclass constructor

According to my text book:
If the execution of any constructor in a subclass does not invoke a
superclass constructor, Java automatically invokes the no-parameter
constructor for the superclass.
Does that mean all the superclass data field(superclass variables) would be set to null(because the constructor is a no-parameter constructor)?
No, if the supers constructor with no arguments initializes some objects - this initialization will be done.
class A {
public int x;
A () {
x = 1;
}
}
class B extends A {
B() {
}
}
The B's constructor will still invoke super() as the first line (even though it is not explicitly written), and will initialize x=1 in the process.
No:
class A {
public int x;
public A() {
x = 42;
}
}
class B extends A {}
assert(new B().x == 42)
The "no-parameter constructor" does not have to be an empty constructor.
It means that superclass's fields will be set to whatever the non-parameter constructor sets them.
This may or may not be null. If the non-parameter superclass constructor is not defined and if the subclass's constructor doesn't set the superclass fields, then yes they will be null.
if the person is careless and doesn't specify them, would we get an error?
You haven't said what "them" refers to, but ...
If a class constructor relies (explicitly or implicitly) on a no-args constructor that its superclass does not provide (explicitly or implicitly), then that is a compilation error.
If the programmer accidentally leaves out the constructors in a class and its reference fields are (only) default initialized to null as a result, you won't get a compilation error. (The code is valid. The compiler cannot determine the intent of the programmer; i.e. whether the constructor was omitted accidentally or deliberately.) But you may get a runtime error later on if some code uses the field / field value assuming it to be non-null.
If the programmer defines a constructor but the constructor fails to initialize some field, then the outcome is that same as 2. No compilation error, and possible runtime error.

Why can't we have this() and super() together in Java? [duplicate]

This question already has answers here:
Why can't this() and super() both be used together in a constructor?
(11 answers)
Closed 5 years ago.
I have this program:
public class A
{
public A(){
System.out.println("I am in A");
}
public static void main(String args[]){
B a = new B("Test");
}
}
class B extends A
{
public B(){
System.out.println("I am in B");
}
public B(String s){
this();
super();
System.out.println("I am in B as " + s);
}
}
Now why can't I call the this constructor of B to invoke the default constructor? This is giving me compile time error.
this and super must be the first line in a constructor.
EDITED:
Language spec
8.8.7. Constructor Body
The first statement of a constructor body may be an explicit
invocation of another constructor of the same class or of the direct
superclass (§8.8.7.1).
this() calls another constructor in the same class.
super() calls a super constructor.If no super() is explicitly written,the compiler will add one implicitly. Hence, you will end up calling super() twice.
So, both are not allowed.
EDIT
In context of your code : remember, super() should always be the first line in a constructor.
Upon further reflection my answer as it was below is basically correct but lacking some nuance. Essentially, you can call a super constructor once. This is to ensure your super class is only constructed once. This means that the first line of a given constructor can be a call to another constructor in the current class or a call to a constructor in the super class. This also means that you can only call another constructor once in any given constructor; you must choose to call one in the current or super class. This ensures that all super classes will be fully constructed before the current object is.
Old explanation:
The fundamental reason is that all super classes must be constructed before the subclass can be. To this end, Java will implicitly call super() if no such invocation exist on the first line of a constructor. The only way to override this behavior is to explicitly call a different constructor in your super class. Basically, Java must create your hierarchy before you can be created.
Putting your constructor first violates this requirement and therefore is illegal.
According to Java this() and super() should be the first statement in constructor.Now the point is we can not write both at once as a first line.If u write this() and not super,dont expect that super will be called implicitly.
It is as simple as it is.U have no option to write them together in single constructor body

Categories