Default constructors in Java

66,323

Solution 1

Use the super constructor:

public Bar(int a, double b, ...) {
    super(a, b, ...);
}

Solution 2

So all nice and well, but how do I now get this to work without duplicating this constructor in every deriving class?

You do need to duplicate the constructor signatures - if you want the subclass to have constructors with the same signatures. But you don't need to duplicate the code - you just chain to the superclass constructor:

public Bar(int x, int y) {
    super(x, y);
    // Any subclass-specific code
}

Of course if you can work out the superclass parameters from a different set of parameters, that's fine. For example:

public Bar(int x) {
    super(x, x * 2);
    // Any subclass-specific code
}

You really need to work out what information is required to construct a Bar - that should dictate your constructors.

If this is a problem, it's possible that you're overusing inheritance. It's hard to say for sure without any idea of what your actual classes are, but you should look at using composition instead of inheritance. It's no panacea, but it can avoid this sort of thing.

Solution 3

No, there's no more "sane" approach. If your base class has no default constructor, then you must explicitly call the correct constructor from all the children classes.

Note this doesn't mean children classes need to have the exact same constructor than base class. For example this is perfectly valid:

class Foo {

    protected int a;
    protected int b;

    protected Foo(final int a, final int b) {
        this.a = a;
        this.b = b;
    }
}

class Bar extends Foo {

    protected Bar() {
        super(0,0);
    }
}

Solution 4

The problem is solved with this:

class Foo{
       Foo(int a, int b){}
}

class Bar extends Foo{
         //Here must be a constructor OR declare a constructor in Foo without parameters
         Bar(){super(1,1)} //this is an example

}

Other solution is:

class Foo{
   Foo(int a, int b){}
   Foo(){}
}

class Bar extends Foo{
}

Remember that if have a constructor with parameters in the SuperClass (in this case Foo), the implicit constructor on the child class (in this case Bar), always will have a implicit call to "Super()" (always have to be one unless explicit).

Solution 5

This error could also happen because you are calling your super constructor last. You might have to move it to be the first statement:

    public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
        mFragmentList  = fragmentList;
        super(manager);

    }

    public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
        super(manager); --> this should come first
        mFragmentList  = fragmentList;
    }
Share:
66,323
Jeroen De Dauw
Author by

Jeroen De Dauw

http://jeroendedauw.com/

Updated on November 29, 2020

Comments

  • Jeroen De Dauw
    Jeroen De Dauw over 3 years

    I know I'm asking some serious 101 question here...

    I have some class Foo and a class Bar that extends Foo. In Foo I have a constructor that takes a set of parameters that it sets to its fields. Deriving classes such as Bar will typically not need to modify this. Now my IDE is giving me "There is no default constructor available in Foo". From a bit of Googling this appears to be because "constructors are not inherited". So all nice and well, but how do I now get this to work without duplicating this constructor in every deriving class? I'm assuming there is a more sane approach?