We all Know that the JVM provides us a default constructor in the every java program.
But if we declare any other type of constructor then it does not provide the any type of default constructor.
So, my question is that is it compulsory to declare default constructor when we declare any other type of constructor in our program.
If YES then explain Why?
If NO then also explain Why?
Give the Solution with proper suitable example.
No, it's not compulsory at all. There are loads of classes with no default constructor, and there's nothing stopping you from writing your own. One that springs to mind is java.awt.Color.
Declaring the default constructor depends on the business requirement and technically its not compulsory.
If you want a class to be initialized only with a set of parameters, then you can skip the default constructor, which indeed forces you -- to give the required values to create the object
For instance,
public class ClassA {
String name;
ClassA(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
For the above class, if you want to do,
ClassA obj = new ClassA();
This is not possible as there is not default constructor.
ClassA obj = new ClassA("name");
The above is the only way to create object, as name is the parameter should be given.
If you want both to be created, add default constructor as
ClassA() {}
Which provides way to create the object with out name.
No, it's not cumpolsory.
class Dog {
Dog(String name)
{
system.out.println("Dog :" + name);
}
public static void main(String[] args)
{
Dog d = new Dog("dollar"); // works fine
Dog d2 = new Dog() // error , no default constructor defined for Dog
}
}
So, my question is that is it compulsory to declare default
constructor when we declare any other type of constructor in our
program.
No, It's not necessary to have a default constructor.
If NO then also explain Why ?
Default Constructor will be provided by Compiler, only if you don't defined any no argument Constructor. But, Keep in mind the following, Check mode from JLS
8.8.9. Default Constructor
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
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.
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.
It is not necessary to create the default constructor, but it is good practice to create the default constructor.
If your class is to be reused then not creating the default constructor will limit the re-usability of your class.
Like if a class is extending that class, then the derived class must have an explicit super call.
consider the following example:-
class Base
{
public Base(int x){
//some statements
}
/*
some methods
*/
}
class Derived
{
// only one of the following will be used
public Derived(){ // This will cause a compile-time error
//some statements
}
public Derived(){ // This will work fine
//some statements
super(x);
}
/*
some methods
*/
}
The reason behind this is, if the base class do not have default constructor than derived class must call the appropriate super() in all its constructor declarations. But if we have a default constructor in base class then the call to super() is not mandatory.
No, it's not compulsory!
But then if you dont have a default constructor(No-argument constructor) and if you want the to create the object of your class in this form
A ref = new A();
then you might not be able to do it.
No this is not necessary.
let me explain why this is not necessary
The question which you've asked is seems like constructor overloading.
If you create an or many parameterized constructor in java then you do need need to be worried for the default constructor.
Basically constructor is used to initialize the instance variables or class members or for performing the preliminary tasks and if you have already done with this by using the another constructor then there is no need for another but you can do if you want.
public class base {
int a;
public base(int x)
{
this.a=x;
System.out.println(x);
}
public base()
{
System.out.println("abc");
}
public static void main(String []a)
{
base b=new base();
b=new base(4);
}
}
The output is :-
abc
4
Related
I have created an upcasting demo and i don't understand how this code is working or i can more specifically say why is constructor of base class also called while the dispatching is done with the Derived class.And there is even not a call to the constructor of the base class.I haven't even used super keyword anywhere than how is the constructor of the base class also called.
class Base{
int value =0;
Base(){
addValue();
}
void addValue(){
value+=10;
}
int getValue(){
return value;
}
}
class Derived extends Base{
Derived()
{
addValue();
}
void addValue(){
value+=20;
}
}
class Test{
public static void main(String args[]){
Base b=new Derived();
System.out.println(b.getValue());
}
}
When you create a new Derived object, its constructor will be called. Since Derived has a superclass Base, its construtor will be called first. In the constructor, the overridden method addValue will be called, which leads to the temporary value of 20. After that, addValue of Derived is called and adds another 20 to value. The final result is 40.
Since, you did not call the constructor of the superclass using super yourself, Java will do that automatically:
Derived() {
super();
addValue();
}
A Derived object is-a Base object, plus more. Java, like most languages, needs to construct the whole object, including the parts initialized by the Base constructor.
Look at is this way: What's doing the initial setting of value to 0? Isn't that part of the code for Base too?
Java lets you specify which base-class constructor to use with super if you want to, but if you don't specify one, it'll pick one. Those rules can be complicated, but in this case they're simple: The no-arguments Base constructor is called from the no-arguments Derived constructor.
As a test, set the Base() constructor private and see what the compiler tells you.
I'm trying to learn Java and I've got everything setup and I'm running. I created a constructor for my first model and went to setup a constructor function that accepts a parameter. I added this function:
public Guest(String name) {
this.name = name;
this.signingDate = new Date(System.currentTimeMillis());
}
Netbeans threw an error saying I needed a default constructor. The error went away when I changed it to:
public Guest() {
}
public Guest(String name) {
this.name = name;
this.signingDate = new Date(System.currentTimeMillis());
}
I can't imagine that this is how you create optional parameters within Java. So it brings up 2 questions:
Why do I need a default constructor?
How do I create optional parameters?
An entity class must have a no-argument public or protected constructor.
Another scenario where you'd need no-arg constrcutors is when you have subclasses.
For example,
class Car {
Engine engine;
Car(Engine e)
{
// do something
}
}
And you have a subclass,
class Benz extends Car
{
Benz()
{
}
}
Now you can't instantiate a Benz object. The reason is, when a new Benz() instantiation is attempeted, the parent constructor is first invoked.
i.e,
class Benz extends Car
{
Benz()
{
super(); //implicitly added
}
}
By default, it tries to invoke a no-arg constructor of the super-class. So you'd need one, unless you have an explicit super(arg) call like this:
class Benz extends Car
{
Benz()
{
super(new Engine());
}
}
Note: A simple Java rule to remember
A no-arg constructor is provided by default as long as you don't have another constructor with argument.
i.e class Car{} is equivalent to class Car{ Car() }
But when you write,
class Car{ Car(Engine e){} } there is no no-arg constructor provided by default. You'll have to explicitly code class Car{ Car(){} Car(Engine e)} if you needed it.
Yes. Java supports method / constructor overloading.
You don't "need" the default constructor. However, NetBeans is being helpful to you, and informing you that you need one because it assumes you are creating a bean - which requires the option to be created without a constructor requiring parameters - because the calling code wouldn't know what to populate into these.
For "optional" parameters, you can define as many constructors as you would need - with each one omitting one or more of the "optional" parameters.
Why do I need a default constructor?
I think you are trying to call new Guest() and have only one constructor in Guest class that is Guest(String arg). And that's why it is showing error that you need to create a constructor with no arguments that is default constructor of a class.
How do I create optional parameters?
If you want to make a constructor with 0 more arguments you need to use ... in argument.
Ex:
public class Testing {
public Testing(String... str) {
}
public static void main(String[] args) {
Testing testing = new Testing();
Testing testing1 = new Testing("1");
Testing testing2 = new Testing("2","1");
}
}
If you're using a POJO (Plain Old Java Object) than you need a default constructor only if you create an instance of this object by invoking no-argument constructor like Guest g = new Guest().
That's pretty obvious - you want to use no-argument constructor - you need to have one.
If you don't specify any constructor, the compiler will generate one (default, no-argument) for you. If you specify at least one constructor by yourself - the compiler won't generate any as it assumes that you know what you're doing.
However, if you're creating a JPA entity (so you have #Entity at the top of your class) than you need a default constructor as it's a JPA requirement.
It's because instances of your class are created by the JPA provider when you fetch them from the database. The JPA provider has to have a way to instantiate your Entity.
If you'd have only parametrized constructor - how the JPA would know what parameters should it pass?
There are no optional parameters in Java like there are in i.e. PHP world where you can define myMethod($var1, $var2 = null, $var3 = 2);. In Java world we use overloaded methods and varargs.
What i know is, the compiler writes a default no argument constructor in the byte code. But if we write it ourselves, that constructor is called automatically. Is this phenomena a constructor overriding?
What you describe isn't overriding. If you don't specify a default constructor, the
compiler will create a default constructor. If it's a subclass, it will call
the default parent constructor(super()), it will also initialize all instance variables to
a default value determined by the type's default value(0 for numeric types, false for booleans, or null
for objects).
Overriding happens when a subclass has the same name, number/type of parameters, and
the same return type as an instance method of the superclass. In this case, the subclass
will override the superclass's method. Information on overriding here.
Constructors are not normal methods and they cannot be "overridden". Saying that a constructor can be overridden would imply that a superclass constructor would be visible and could be called to create an instance of a subclass. This isn't true... a subclass doesn't have any constructors by default (except a no-arg constructor if the class it extends has one). It has to explicitly declare any other constructors, and those constructors belong to it and not to its superclass, even if they take the same parameters that the superclass constructors take.
The stuff you mention about default no arg constructors is just an aspect of how constructors work and has nothing to do with overriding.
It is never possible. Constructor Overriding is never possible in Java.
This is because,
Constructor looks like a method but
name should be as class name and no
return value.
Overriding means what we have declared
in Super class, that exactly we have
to declare in Sub class it is called
Overriding. Super class name and Sub
class names are different.
If you trying to write Super class
Constructor in Sub class, then Sub
class will treat that as a method not
constructor because name should
not match with Sub class name. And it
will give an compilation error that
methods does not have return value. So
we should declare as void, then only
it will compile.
Have a look at the following code :
Class One
{
....
One() { // Super Class constructor
....
}
One(int a) { // Super Class Constructor Overloading
....
}
}
Class Two extends One
{
One() { // this is a method not constructor
..... // because name should not match with Class name
}
Two() { // sub class constructor
....
}
Two(int b) { // sub class constructor overloading
....
}
}
You can have many constructors as long as they take in different parameters. But the compiler putting a default constructor in is not called "constructor overriding".
Cannot override constructor. Constructor can be regarded as static, subclass cannot override its super constructor.
Of course, you could call protected-method in super class constructor, then overide it in subclass to change super class constructor. However, many persons suggest not to use the trick, in order to protect super class constructor behavior. For instance, FindBugs will warn you that a constructor calls a non-final method.
No it is not possible to override a constructor. If we try to do this then compiler error will come. And it is never possible in Java. Lets see the example. It will ask please write a return type o the method. means it will treat that overriden constructor as a method not as a constructor.
package com.sample.test;
class Animal{
public static void showMessage()
{
System.out.println("we are in Animal class");
}
}
class Dog extends Animal{
public void DogShow()
{
System.out.println("we are in Dog show class");
}
public static void showMessage()
{
System.out.println("we are in overriddn method of dog class");
}
}
public class AnimalTest {
public static void main(String [] args)
{
Animal animal = new Animal();
animal.showMessage();
Dog dog = new Dog();
dog.DogShow();
Animal animal2 = new Dog();
animal2.showMessage();
}
}
But if we write it ourselves, that
constructor is called automatically.
That's not correct. The no-args constructor is called if you call it, and regardless of whether or not you wrote it yourself. It is also called automatically if you don't code an explicit super(...) call in a derived class.
None of this constitutes constructor overriding. There is no such thing in Java.
There is constructor overloading, i.e. providing different argument sets.
Because a constructor cannot be inherited in Java and Method Overriding requires inheritance. Therefore, it's not applicable.
Constructor overriding is not possible because of following reason.
Constructor name must be the same name of class name. In Inheritance practice you need to create two classes with different names hence two constructors must have different names. So constructor overriding is not possible and that thought not even make sense.
Your example is not an override. Overrides technically occur in a subclass, but in this example the contructor method is replaced in the original class.
Constructor looks like a method but name should be as class name and no return value.
Overriding means what we have declared in Super class, that exactly we have to declare in Sub class it is called Overriding. Super class name and Sub class names are different.
If you trying to write Super class Constructor in Sub class, then Sub class will treat that as a method not constructor because name should not match with Sub class name. And it will give an compilation error that methods does not have return value. So we should declare as void, then only it will compile.
It should also be noted that you can't override the constructor in the subclass with the constructor of the superclass's name. The rule of OOPS tells that a constructor should have name as its class name. If we try to override the superclass constructor it will be seen as an unknown method without a return type.
While others have pointed out it is not possible to override constructors syntactically, I would like to also point out, it would be conceptually bad to do so. Say the superclass is a dog object, and the subclass is a Husky object. The dog object has properties such as "4 legs", "sharp nose", if "override" means erasing dog and replacing it with Husky then Husky would be missing these properties and be a broken object. Husky never had those properties and simply inherited them from dog.
On the other hand, if you intend to give Husky everything that dog has, then conceptually you could "override" dog with Husky, but there would be no point in creating a class that is the same as dog, it's not practically an inherited class but a complete replacement.
method overriding in java is used to improve the recent code performance written previously .
some code like shows that here we are creating reference of base class and creating phyisical instance of the derived class.
in constructors overloading is possible.
InputStream fis=new FileInputStream("a.txt");
int size=fis.available();
size will return the total number of bytes possible in a.txt
so
I found this as a good example for this question:
class Publication {
private String title;
public Publication(String title) {
this.title = title;
}
public String getDetails() {
return "title=\"" + title + "\"";
}
}
class Newspaper extends Publication {
private String source;
public Newspaper(String title, String source) {
super(title);
this.source = source;
}
#Override
public String getDetails() {
return super.getDetails() + ", source=\"" + source + "\"";
}
}
class Article extends Publication {
private String author;
public Article(String title, String author) {
super(title);
this.author = author;
}
#Override
public String getDetails() {
return super.getDetails() + ", author=\"" + author + "\"";
}
}
class Announcement extends Publication {
private int daysToExpire;
public Announcement(String title, int daysToExpire) {
super(title);
this.daysToExpire = daysToExpire;
}
#Override
public String getDetails() {
return super.getDetails() + ", daysToExpire=" + daysToExpire;
}
}
It works fine when constructors are not defined, but gives errors if I define a parameterized constructor and not a default one and not passing any values while creating an object. I thought constructors are predefined.
Why do I need to define a default constructor if I've defined a parameterized constructor? Ain't default constructor predefined?
A default (no-argument) constructor is automatically created only when you do not define any constructor yourself.
If you need two constructors, one with arguments and one without, you need to manually define both.
While all the answers above are correct, it's a bit difficult for new-comers to wrap it in their head. I will try to answer the question anew for new-comers.
The problem that Ayush was facing was in trying to instantiate an Object for a class via a no-arg constructor. This class however has one or more parameterized constructor and this results in a compile time error.
For example, let us create a class Student with a single parameterized constructor and try to instantiate it via the no-arg constructor.
public class Student {
private String name;
private int rollNo;
public Student(String name, int rollNo) {
this.name = name;
this.rollNo = rollNo;
}
public static void main(String[] args) {
// The line below will cause a compile error.
Student s = new Student();
// Error will be "The constuctor Student() is undefined"
}
}
Woha! But when we remove the public Student(String name, int rollNo)
constructor all-together, the error is gone and the code compiles.
The reason behind this seeming anomaly lies in the fact that Java only
provides us with the default (no-arg) constructor when we do not define any
constructor for that class on our own.
For example, the following class is supplied with a default contructor:
public class Student {
private String name;
private int rollNo;
}
becomes:
public class Student {
private String name;
private int rollNo;
//Default constructor added by Java.
public Student() {
super();
}
}
In other words, the moment we define any parameterized constructor,
we must also define a no-arg constructor if we want to instantiate
the object of that class via a no-arg constructor.
Also in case of inheritance, a sub-class with no constructors; is supplied one
default constructor. This default constructor supplied by Java as above calls the super class's no-arg constructor. If it can't find one, then it will throw an error.
So yes it's always a good choice to define a no-arg/default constructor.
Ref : Oracle Java Tutorial
A no-arg constructor is automatically inserted for you, if you don't write one. This means, if you write a constructor with some parameters, it will be the only constructor you have, so you must pass some values for those parameters to create an instance of it.
This is exactly the expected behavior.
Java automatically generates a default (no arguments constructors) for classes that don't have any constructor.
If you define another constructor (with arguments), default constructor will not be generated. If you still want one, you need to define it yourself.
Whenever you class is complied, if compiler does not find any valid constructor in class (default,parametrized) only then it will substitute auto generated default constructor for your class.
You must have noticed, you can create objects without any default constructor defined in your class, there comes the concept of auto-generated default constructor.As whenever object is created,default constructor is called.
But, If you define Parametrized constructor in your class, that means you restrict the objects to have that parameters
Example:Every employee must have an id.
So,at that time, Compiler will not insert any default constructor there as there is valid constructor in a class.If you need default constructor too, you have to define by yourself.
There is also one curious case when you must define non argument constructor.
As the other wrote, if you don't specify default constructor - Java will do it for you. It's good to understand how "default generated by Java" constructor looks like.
In fact it calls constructor of the super class and this is fine.
Let's now imagine one case.
You are creating Vehicle class:
public class Vehicle {
private String name;
private String engine;
public Vehicle(String name, String engine) {
this.name = name;
this.engine = engine;
}
public String makeNoise(){
return "Noiseee";
}
}
As we can see Vehicle class has got only one defined 2 arguments constructor.
Now let's create Car class which inheritates from Vehicle class:
public class Car extends Vehicle {
#Override
public String makeNoise() {
return "Wrrrrrrr....";
} }
Maybe it looks strange but only one reason why wouldn't it compile is fact that Java cannot create default constructor for Car class which call super Vehicle class. Vehicle class doesn't have no argument constructor and it cannot be generated automatically while 2 arg constructor already exists.
I know that it's very rare case, but I found it as a interesting to know.
I know abstract fields do not exist in java. I also read this question but the solutions proposed won't solve my problem. Maybe there is no solution, but it's worth asking :)
Problem
I have an abstract class that does an operation in the constructor depending on the value of one of its fields.
The problem is that the value of this field will change depending on the subclass.
How can I do so that the operation is done on the value of the field redefined by the subclass ?
If I just "override" the field in the subclass the operation is done on the value of the field in the abstract class.
I'm open to any solution that would ensure that the operation will be done during the instantiation of the subclass (ie putting the operation in a method called by each subclass in the constructor is not a valid solution, because someone might extend the abstract class and forget to call the method).
Also, I don't want to give the value of the field as an argument of the constructor.
Is there any solution to do that, or should I just change my design ?
Edit:
My subclasses are actually some tools used by my main program, so the constructor has to be public and take exactly the arguments with which they will be called:
tools[0]=new Hand(this);
tools[1]=new Pencil(this);
tools[2]=new AddObject(this);
(the subclasses are Hand, Pencil and AddObject that all extend the abstract class Tool)
That's why I don't want to change the constructor.
The solution I'm about to use is to slightly change the above code to:
tools[0]=new Hand(this);
tools[0].init();
tools[1]=new Pencil(this);
tools[1].init();
tools[2]=new AddObject(this);
tools[2].init();
and use an abstract getter to acces the field.
How about abstract getter/setter for field?
abstract class AbstractSuper {
public AbstractSuper() {
if (getFldName().equals("abc")) {
//....
}
}
abstract public void setFldName();
abstract public String getFldName();
}
class Sub extends AbstractSuper {
#Override
public void setFldName() {
///....
}
#Override
public String getFldName() {
return "def";
}
}
Also, I don't want to give the value
of the field as an argument of the
constructor.
Why not? It's the perfect solution. Make the constructor protected and offer no default constructor, and subclass implementers are forced to supply a value in their constructors - which can be public and pass a constant value to the superclass, making the parameter invisible to users of the subclasses.
public abstract class Tool{
protected int id;
protected Main main;
protected Tool(int id, Main main)
{
this.id = id;
this.main = main;
}
}
public class Pencil{
public static final int PENCIL_ID = 2;
public Pencil(Main main)
{
super(PENCIL_ID, main);
}
}
How about using the Template pattern?
public abstract class Template {
private String field;
public void Template() {
field = init();
}
abstract String init();
}
In this way, you force all subclasses to implement the init() method, which, since it being called by the constructor, will assign the field for you.
You can't do this in the constructor since the super class is going to be initialized before anything in the subclass. So accessing values that are specific to your subclass will fail in your super constructor.
Consider using a factory method to create your object. For instance:
private MyClass() { super() }
private void init() {
// do something with the field
}
public static MyClass create() {
MyClass result = new MyClass();
result.init();
return result;
}
You have an issue in this particular sample where MyClass can't be subclassed, but you could make the constructor protected. Make sure your base class has a public / protected constructor also for this code. It's just meant to illustrate you probably need two step initialization for what you want to do.
Another potential solution you could use is using a Factory class that creates all variants of this abstract class and you could pass the field into the constructor. Your Factory would be the only one that knows about the field and users of the Factory could be oblivious to it.
EDIT: Even without the factory, you could make your abstract base class require the field in the the constructor so all subclasses have to pass in a value to it when instantiated.
Also, I don't want to give the value of the field as an argument of the constructor.
Is there any solution to do that, or should I just change my design ?
Yes, I think you should change your design so that the subclass passes the value to the constructor. Since the subclass portion of your object isn't initialized until after the superclass constructor has returned, there's really no other clean way of doing it. Sure, this'd work:
class Super {
protected abstract int abstractField();
protected Super() { System.out.println("Abstract field: " + abstractField); }
}
class Sub {
protected int abstractField(){ return 1337; }
}
... since the implementation of abstractField() doesn't operate on object state. However, you can't guarantee that subclasses won't think it's a great idea to be a little more dynamic, and let abstractField() returns a non-constant value:
class Sub2 {
private int value = 5;
protected int abstractField(){ return value; }
public void setValue(int v){ value = v; }
}
class Sub3 {
private final int value;
public Sub3(int v){ value = v; }
protected int abstractField(){ return value; }
}
This does not do what you'd expect it to, since the initializers and constructors of subclasses run after those of the superclass. Both new Sub2() and new Sub3(42) would print Abstract field: 0 since the value fields haven't been initialized when abstractField() is called.
Passing the value to the constructor also has the added benefit that the field you store the value in can be final.
If the value is determined by the type of subclass, why do you need a field at all? You can have a simple abstract method which is implemented to return a different value for each subclass.
I think you need a factory (aka "virtual constructor") that can act on that parameter.
If it's hard to do in a given language, you're probably thinking about it incorrectly.
If I understand you correctly: You want the abstract class's constructor to do something depending on a field in the abstract class but which is set (hopefully) by the subclass?
If I got this wrong you can stop reading ...
But if I got it right then you are trying to do something that is impossible. The fields of a class are instantiated in lexical order (and so if you declare fields "below", or "after", the constructor then those will not be instantiated before the constructor is called). Additionally, the JVM runs through the entire superclass before doing anything with the subclass (which is why the "super()" call in a subclass's constructor needs to be the first instruction in the constructor ... because this is merely "advice" to the JVM on how to run the superclass's constructor).
So a subclass starts to instantiate only after the superclass has been fully instantiated (and the superclass's is constructor has returned).
And this is why you can't have abstract fields: An abstract field would not exist in the abstract class (but only in the subclass) and so is seriously(!) "off limits" to the super (abstract) class ... because the JVM can't bind anything references to the field (cause it doesn't exist).
Hope this helps.