The Oracle Java tutorial site has this paragraph that is confusing me:
All classes have at least one
constructor. If a class does not
explicitly declare any, the Java
compiler automatically provides a
no-argument constructor, called the
default constructor. This default
constructor calls the class parent's
no-argument constructor, or the Object
constructor if the class has no other
parent. If the parent has no
constructor (Object does have one),
the compiler will reject the program.
If all objects directly or indirectly inherit from Object how is it possible to elicit the compiler rejection spoken of? Does it have to do with the constructor being private?
If all objects directly or indirectly inherit from Object how is it possible to elicit the compiler rejection spoken of?
I think the basis is of your misunderstanding is that you are thinking that constructors are inherited. In fact, constructors are NOT inherited in Java. So consider the following example:
public class A {
public A(int i) { super(); ... }
}
public class B extends A {
public B() { super(); ... }
}
The class A:
does not inherit any constructors from Object,
does not explicitly declare a no-args constructor (i.e. public A() {...}), and
does not have a default constructor (since it does declare another constructor).
Hence, it has one and only one constructor: public A(int).
The call to super() in the B class tries to use a non-existent no-args constructor in A and gives a compilation error. To fix this, you either need to change the B constructor to use the A(int) constructor, or declare an explicit no-args constructor in A.
(Incidentally, it is not necessary for a constructor to explicitly call a superclass constructor ... as I've done. But a lot of people think it is good style to include an explicit call. If you leave it out, the Java compiler inserts an implicit call to the superclasses no-args constructor ... and that results in a compilation error if the no-args constructor does not exist or is not visible to the subclass.)
Does it have to do with the constructor being private?
Not directly. However, declaring a constructor private will prevent that constructor being called from a child class.
The key thing to understand is that the no-arg constructor will only be automatically generated if the class doesn't already have a constructor.
It's thus easy to create a class that doesn't have a no-arg constructor.
The simplest way to think of this problem is as follows:
The non-args constructor is provided as the default constructor by Java for any class you create.
The moment you create a custom constructor with arguments, Java says “hey, this class has got a custom constructor, so I am not going to bother creating/supplying the default non-args constructor!”
As a result now your class does NOT has the default non-args constructor.
This means when you create a subclass, based on your class, you need explicitly call the arguments based custom constructor that you created.
If you have a sub-class of a sub-class
class A
{
A(int i) {..}
}
class B extends A
{
}
Here the default constructor inserted into B will try to invoke A's no-argument constructor (which doesn't exist) as it only has a constructor taking one argument
The immediate superclass of the object must have a protected or public constructor (or no constructor at all, in which case one will be created). So, if I create a class that extends Object, with a private constructor only, then nothing will be able to extend my class.
Yes. A private contructor is a special instance constructor. It is commonly used in classes that contain static members only. If a class has one or more private constructors and no public constructors, then other classes (except nested classes) are not allowed to create instances of this class.
The declaration of a private constructor prevents the automatic generation of a default constructor.
EDIT:
A class defined within another class
is called a nested class. Like other
members of a class, a nested class can
be declared static or not. A
nonstatic nested class is called an
inner class. An instance of an inner
class can exist only within an
instance of its enclosing class and
has access to its enclosing class's
members even if they are declared
private.
What this means is that if you inherit from a line of class(es) that make the default no-arg constructor private (or it does not exist, for example), your sub-classes must declare a constructor in line with its parent's alternative constructor.
For example, the following declaration of Bar is not allowed:
public class Foo {
private Foo() { } // or this doesn't even exist
public Foo(int i) {
}
}
public class Bar extends Foo {
}
Let me append to all aforementioned one more interesting case where the default/no-arg constructor is infeasible, in the sense that unless it is explicitly declared, the compiler cannot assume it and yet it has nothing to do with subclassing. This is the case of having a class with a final field which expects a constructor to initialize it. For example:
class Foo extends Object {
private final Object o;
public Foo(Object o){
this.o = o;
}
}
Here it's easy to see that an instantiation of a Foo-object requires the initialization of the final field o so any invocation of Foo() - directly or not - is doomed to failure... Let me underline that the no-arg constructor in the super class (Object) exists and is publicly accessible but it is the presence of the final field (o) that deactivates it in Foo.
Related
Consider this code:
class Test {
Test() {
System.out.println("In constructor of Superclass");
}
int adds(int n1, int n2) {
return(n1+n2);
}
void print(int sum) {
System.out.println("the sums are " + sum);
}
}
class Test1 extends Test {
Test1(int n1, int n2) {
System.out.println("In constructor of Subclass");
int sum = this.adds(n1,n2);
this.print(sum);
}
public static void main(String[] args) {
Test1 a=new Test1(13,12);
Test c=new Test1(15,14);
}
}
If we have a constructor in super class, it will be invoked by every object that we construct for the child class (ex. Object a for class Test1 calls Test1(int n1, int n2) and as well as its parent Test()).
Why does this happen?
The output of this program is:
In constructor of Superclass
In constructor of Subclass
the sums are 25
In constructor of Superclass
In constructor of Subclass
the sums are 29
Because it will ensure that when a constructor is invoked, it can rely on all the fields in its superclass being initialised.
see 3.4.4 in here
Yes. A superclass must be constructed before a derived class could be constructed too, otherwise some fields that should be available in the derived class could be not initialized.
A little note:
If you have to explicitly call the super class constructor and pass it some parameters:
baseClassConstructor(){
super(someParams);
}
then the super constructor must be the first method call into derived constructor.
For example this won't compile:
baseClassConstructor(){
foo();
super(someParams); // compilation error
}
super() is added in each class constructor automatically by compiler.
As we know well that default constructor is provided by compiler automatically but it also adds super() for the first statement.If you are creating your own constructor and you don't have either this() or super() as the first statement, compiler will provide super() as the first statement of the constructor.
Java classes are instantiated in the following order:
(at classload time)
0. initializers for static members and static initializer blocks, in order
of declaration.
(at each new object)
create local variables for constructor arguments
if constructor begins with invocation of another constructor for the
class, evaluate the arguments and recurse to previous step. All steps
are completed for that constructor, including further recursion of
constructor calls, before continuing.
if the superclass hasn't been constructed by the above, construct the
the superclass (using the no-arg constructor if not specified). Like #2,
go through all of these steps for the superclass, including constructing
IT'S superclass, before continuing.
initializers for instance variables and non-static initializer blocks, in
order of declaration.
rest of the constructor.
That´s how Java works. If you create a child object, the super constructor is (implicitly) called.
In simple words if super class has parameterized constructor, you need to explicitly call super(params) in the first line of your child class constructor else implicitly all super class constructors are called untill object class is reachead.
The subclass inherits fields from it's superclass(es) and those fields have to get constructed/initialised (that's the usual purpose of a constructor: init the class members so that the instance works as required. We know that some people but a lot more functionality in those poor constructors...)
Constructor implements logic that makes the object ready to work. Object may hold state in private fields, so only its class' methods can access them. So if you wish instance of your subclass be really ready to work after calling constructor (i.e. all its functionality including inherited from base class is OK) the base class's constructor must be called.
This is why the system works this way.
Automatically the default constructor of base class is called. If you want to change this you have to explicitly call constructor of base class by writing super() in the first line of your subclass' constructor.
The base class constructor will be called before the derived class constructor. This makes sense because it guarantees that the base class is properly constructed when the constructor for the derived class is executed. This allows you to use some of the data from the base class during construction of the derived class.
When we create an object of subclass, it must take into consideration all the member functions and member variables defined in the superclass. A case might arise in which some member variable might be initialized in some of the superclass constructors. Hence when we create a subclass object, all the constructors in the corresponding inheritance tree are called in the top-bottom fashion.
Specifically when a variable is defined as protected it will always be accessible in the subclass irrespective of whether the subclass is in the same package or not. Now from the subclass if we call a superclass function to print the value of this protected variable(which may be initialized in the constructor of the superclass) we must get the correct initialized value.Hence all the superclass constructors are invoked.
Internally Java calls super() in each constructor. So each subclass constructor calls it's superclass constructor using super() and hence they are executed in top-bottom fashion.
Note : Functions can be overridden not the variables.
Since you are inheriting base class properties into derived class, there may be some situations where your derived class constructor requires some of the base class variables to initialize its variables. So first it has to initialize base class variables, and then derived class variables. That's why Java calls first base class constructor, and then derived class constructor.
And also it doesn't make any sens to initialize child class with out initializing parent class.
Constructor of Super class in called first because all the methods in the program firstly present in heap and after compilation they stores in to the stack,due to which super class constructor is called first.
There is a default super() call in your default constructors of sub classes.
//Default constructor of subClass
subClass() {
super();
}
"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."
(source: https://docs.oracle.com/javase/tutorial/java/IandI/super.html)
I'll try to answer this from a different perspective.
Suppose Java didn't call the super constructor for you automatically. If you inherit the class, you'd have to either call the super constructor implicitly, or rewrite it yourself. This would require you to have internal knowledge of how the super class works, which is bad. It would also require to to rewrite code, which is also not good.
I agree that calling the super constructor behind the scenes is a little unintuitive. On the other hand, I'm not sure how they could have done this in a more intuitive way.
As we know that member variables(fields)of a class must be initialized before creating an object because these fields represent the state of object. If these fields are explicitely not initilized then compiler implicitely provides them default values by calling no-argument default constructor. Thats why subclass constructor invokes super class no-argument default constructor or implicitely invoked by compiler .Local variables are not provided default values by compiler.
here your extending Test to your test1 class meaning u can access all the methods and variable of test in your test1. keep in note that u can access a class methods or variable only if memory is allocated to it and for that it need some constructor either a default or parameterized ,so here wen the compiler finds that it is extending a class it will try to find the super class constructor so that u can access all its methods.
Parents Exits First!!
And like real world Child Can't exist without the Parents..
So initialising parents(SuperClass) first is important in order to use thrm in the children(Subclass) Classes..
Can we override a constructor of super class in sub class of the same class.
If yes, how?
If no, why?
class Super{}
class Sub extends Super
{
//write code, if yes
}
No, you cannot override the constructor of the Super class. JVM will definitely call the super class constructor while creating the child class instance. So, whenever you create a subclass instance, it will invoke the baseclass constructor and then continue with the subclass constructor statements. Constructors are not Methods that can be overriden
Can we override a constructor of super class in sub class of the same class?
No.
With inheritance you can get/obtain instance members only. Constructor is not a member of class. Jvm treats it specially to construct an object . You can check that by seeing byte code instructions.
By ovveriding, what you acheive ?? A constructor must construct the current object.
Constructors cannot be overridden. The concept of constructor is to create an instance of class, and that behavior belongs to that class only and cannot be overidden.
You can sort of override the constructor. You cannot actually override one, but you can achieve some of the same results.
When you specify a constructor in the child class you can build that however you like. That constructor can then choose which super() constructor gets called.
So you can block some child constructors, you can modify the parameters to them, etc. The only limitation is that at least one super constructor must be called.
A { A(int i) {} A(String b) }
B extends A { B(int i) { super(i); doStuff() } }
C extends A { C(String b) { super(Integer.parseInt(b)) } }
So we have a class A with two constructors.
Class B on the other hand has no String constructor, and does extra stuff after the super constructor happens.
Class C has no int constructor - but when you call the String constructor in C it actually goes to the int constructor in A.
When you construct an object, any parent constructors are called before the constructor specific to that object. You cannot change this behaviour.
However, it is possible, with some trickery, to create an object without invoking any constructors. After which, of course, you can perform any initialisation that you need.
You can use objenesis to create the object for you. It's pretty low-level stuff; operating at the byte-code level.
Note that you can't do this using reflection.
overiding defines same name with parameter type, constructor overriding defins same named constructor in parent as well as in child which defines same named parent and child class which can't be possible ..so no we can not do constructor overriding hence we can do constructor overloading.
I know Constructors are not inheritable in java, we need to use super() - super must be the first statement in Constructors.
But why cant i use #Override annotation?
In example:
public class Foo extends Point2D.Double {
#Override // The annotation #Override is disallowed for this location
public Foo(){}
}
If i have a instance of Foo, i never ever can call Point2D.Double.Double() directly! This behave is compleatly like Overriding!
#Override is used when you are overriding a method (not a constructor!), which means that you are creating a method using the same name and parameters as one of the methods from superclass.
There is no constructor called Foo() in your superclass (obviously), because constructors aren't inherited from parent classes, so this is not overriding.
Overriding can be only applied to inherited methods which are not constructors and are not defined as final.
You cannot override a constructor.
Constructors are not inherited.
Yous subclasses constructor is completely different and independent from super class's constructor (language semantically, due to initializations etc it may depend. ).
While you can call super() to call the super class's constructor it's called chaining not overriding.
Because there is no previous implementation of Foo of which will be overridden.
#Override is denoted the place where override supper class(Parent class) method in child class. Constructor is NOT a method and can't override in that way. So you can't put #Override there.
Compiler checks overriding rules while compiling the java class. Constructors cannot be overridden so compiler generates an error if somebody tries to use #Override annotation for the constructor.
Because you do not ovverride a constructor. As you state constructors are not inheritable. Defining a constructor in a Subclass is not the same process as ovverriding a method. Therefore the JVM invokes automatically super(), or you have to do it yourself, when you define a constructor in a Subclass, which is not required when ovverriding a method.
You could override only when you have a method in your parent class. Since parent class does not have Foo() method.. hence no override is allowed.
I believe you are not asking about overriding a constructor like
public class Foo extends Point2D.Double {
public Double(){
}
}
this is simply not allowed. However, each subclass constructor has to chain either to another constructor within the subclass or to a constructor in the superclass. So for example:
public class Superclass
{
public Superclass(int x) {}
public Superclass(String y) {}
}
public class Subclass extends Superclass
{
public Subclass()
{
super(5); // chain to Superclass(int) constructor
}
}
The implication of constructors not being inherited is that you can't do this:
// Invalid
Subclass x = new Subclass("hello");
The case is that you do not perform override at all. That is why you can not use that annotation. When you declare the a new constructor you are assured that super() will be called by Java. You do not have to force it. What more you can not apply any additional operation before the super(). This lead to the conclusion that if you need to call default constructor from parent class you do not have to do anything special.
The case change when you enforce to use some parameterized constructor, then you have to add that call in child class. But if your parent class has no default constructor then you will always need to call that parameterized.
Why does Java disallow inheritance from a class whose constructor is private?
Java doesn't prevent sub-classing of class with private constructors.
public class Main {
static class A {
private A() {
System.out.println("Subclassed A in "+getClass().getName());
}
}
static class B extends A {
public B() {
}
}
public static void main(String... ignored) {
new B();
}
}
prints
Subclassed A in Main$B
What it prevents is sub-classes which cannot access any constructors of its super class. This means a private constructor cannot be used in another class file, and a package local constructor cannot be used in another package.
In this situation, the only option you have is delegation. You need to call a factory method to create an instance of the "super" class and wrap it.
Because a class must call its super class constructor always. If the super class constructor can't be accessed, then the sub class can't be initialized.
More info: JLS 8.8.10. Preventing Instantiation of a Class
Regarding Brian Roach's comments:
The call [to the parent class constructor] is only implicit if you don't do it explicitly and the parent has a public or protected no-arg constructor (or hasn't defined any in which case there's a default no-arg). It's required because ... that's how the language works. Children [classes] must call [their] parent's constructor.
Note that when you instantiate any class in Java, there's always a implicit call to Object constructor since it is the super class of all classes. It will execute its default constructor:
public Object() {
}
Note from the JLS link:
It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor (§6.6) that takes no arguments and has no throws clause.
If constructor of a class is private then child class cannot make call to super constructor.
Hence inheritance would fail.
If you have a subclass, you have 2 possiblities for child class(subclass) constructors :
1. Default Constructor(No argument constructor) : In this case default constructor will automatically try to call the parent class constructor : this will fail since parent class constructor is private.
2. Parameterized Constructor : When you try to create an object for a child class which has parameterized constructor, you need to mandatorily call parent class constructor from child class constructor by either passing parameters or not passing parameters : this will also fail since parent constructor is private.
Since child class will have either default constructor or parameterized constructor and its not possible to have either of them, you cannot have a subclass for a parent class with private constructor.
Yes adding something to Luiggi's answer this feature of java is used when creating the Singleton classes which allows only one instance of that class to be created.
This is because, When we do inheritance the job of the compiler is to make a direct or indirect relation of all the classes with the Object class by writing the super() at the very first statement of every class constructor .
when we make the constructor as private that means it shouldn't be accessed from outside the class but when we do inheritance compiler will implicitly write this type of statement.
class SubClassName extends SuperClassName {
public SubClassName() {
super(); // which will indirectly going to call the Parent class constructor from outside its scope
}
}
It is not possible to create an object by directly calling the constructor of an abstract class. The constructor of an abstract class can be called only from a derived class. It therefore seems to me that constructors of an abstract class must be either protected or package-private (the latter for the unusual cases of restricting use of a constructor to derived classes within the package). Yet Java allows the constructor of an abstract class to be public.
Are there any circumstances in which it is useful to declare the constructor of an abstract class to be public, rather than protected or package-private?
This is not quite a duplicate of the question "Abstract class constructor access modifier": clearly you can declare a constructor to be public; I want to know whether there is ever any good reason to do so. It seems to me that there is not. I see that C# has a similar peculiarity.
The answer is the same for java:
THere's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected. (source)
You can't call a constructor of an abstract class from anything other than a direct subclass.
So adding a special rule for access modifiers of constructors of abstract classes wouldn't add something useful to the language.
One thing that looks like an exception from this rule - if the abstract class only defines a default constructor, then the subclass does not have to implement a constructor: this is legal:
public abstract class A {
public A() {}
}
public class B extends A {}
So we can create a B by calling new B() - but note, that we still create a B and not an A. And, again, it doesn't matter if the constructor in A is public or protected. It just shouldn't be private, but the compiler will notice and complain...
Actually we invoke an "invisible" public default constructor on B which does a simple super() call...
The visibility also infuences what is shown in the javadoc (if it's selected to exclude certain visibility levels). As it doesn't matter otherwise, that could be a usage for a public constructor of an abstract class.
If you provide no constructor, then the default constructor is public if the class is public. Easiest option would be to allow that, rather than forcing protected constructors.
In that sense the reverse question may make it clear: why didn't they force protected constructors in abstract classes? Because public constructors won't change anything, so it would just take time and add complexity.
Call me a heretic, but ... I see at least one use for a constructor in an abstract class.
That is: to specify what the constructor parameters look like.
Specify an abstract constructor (thus making the class abstract). Derived classes have to implement this constructor with its specific signature to lose abstract status.
I see no other way to specify mandatory constructor signatures (help me out if you do).
You can have a public constructor if you do not define in a constructor in the sub-class.
example
abstract class Animal {
String name;
public void Animal(String name) {
this.name = name;
}
}
class Cat extends Animal{
public String sayMayName() {
return this.name;
}
}
myCat = new Cat("tester");
name = myCat.sayMyName();
if no constructor is defined the parent class constructor will be called, if it is not public it will not work. This I think is more elegantly done with a factory pattern, but I used it in practice in PHP and it works fine.