Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26652

Possible to avoid default call to super() in Java?

Assume for some reason that I don't want to implicitly call super() which is done by default.

class Animal {
    public Animal() {
        System.out.println("Constructing an animal.");
    }
}
class Dog extends Animal {
    public Dog() {
        System.out.println("Constructing a dog.");
    }
    public static void main(String[] a) {
        new Dog();
    }
}

Is there any way to "disable" the default behavior that super() is invoked when making a new Dog? Or would that be principally and conceptually wrong?

I mean there could be cases where you would want only the constructor of the subclass and not invoke the construction of the baseclass, and still inherit the baseclass.

Upvotes: 2

Views: 827

Answers (5)

Florian Salihovic
Florian Salihovic

Reputation: 3951

That's one of the reasons inheritance is a pain and usually misused:

public interface Animal {
  // define behaviour
}

public class Dog implements Animal { 
  // implement behaviour
}

Use interfaces and aggregation / decoration so you can avoid the struggle of bad design decisions in inheritance chains.

Upvotes: 0

Pavan Kumar
Pavan Kumar

Reputation: 4800

Agreeing with all the answers here on invoking the constructor which cannot be avoided, providing one more workaround which ensures a block of code in constructor that gets executed only when it is directly invoked and not when any sub class constructors are invoked.

public class Animal{
    public Animal() {
        if(this.getClass() == Animal.class){
            System.out.println("Animal");
        }
    }
}

public class Dog extends Animal{
    public Dog() {
        System.out.println("Dog");
    }
}

Upvotes: 2

Thomas
Thomas

Reputation: 88707

If I understand you correctly you want to override the behavior of the Animal constructor or just not call it. If so you're conceptually wrong: you always need to call a super constructor, the only thing you could to with the calls is provide a non-default constructor, i.e. one with arguments and provide appropriate arguments to influence the behavior of that constructor (e.g. by either selecting a different constructor, passing some sort of strategy/function object etc.)

Another way might be to provide some init() method that the default constructor is calling and which you can override but there are a few problems with it, e.g.:

  • If the overridden method tries to access anything only visible to the subclass (e.g. additional fields) you could run into problems because those haven't been initialized yet.
  • That method can't initialize any final field.

Upvotes: 6

davidxxx
davidxxx

Reputation: 131316

s there any way to "disable" the default behavior that super() is invoked when making a new Dog? Or would that be principally and conceptually wrong?

It is conceptually wrong since any class which invokes its constructor has to invoke the constructor of its parent : super() or super() with any arguments if the super constructor has not it.

If the constructor of the super class does some specific processing and that is not desirable for all concrete classes, you should change rather the implementation of the super constructor and move the specific behavior in a method of the super class or in a method of concrete classes.

Upvotes: 5

Bathsheba
Bathsheba

Reputation: 234645

You can't bypass the construction of a parent class, and perhaps you shouldn't attempt to circumvent this rule.

But, if you must do this then you could build a no-op constructor in Animal (that you mark as protected so only derived classes can see it):

protected Animal(Noop foo)
{
    /*do nothing explicit here*/
}

And call that one explicitly from your derived class using

super(new Noop())

Here I've invented a new class Noop (meaning "no operation") to enable the compiler to distinguish the constructor parameters.

Upvotes: 3

Related Questions