Reputation: 26652
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
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
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
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.:
Upvotes: 6
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
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