2

I have a class like this:

public class BaseClass
{
  public BaseClass(URL url, String something, String whatever)
  {
    // Do some stuff with URL, something and whatever
  }

  public List ImportantFunction()
  {
    // Some important stuff here
  }
}

I want to use this class, however I want to do different stuff in the constructor. The things that the constructor does I need to do them differently. But I want to use all the functionality of the other class methods.

I figured the easiest would be to extend the class. However when I do this, the constructor requires me to call the parent constructor:

super(url, something, whatever);

Is it possible to extend the base class but have a completely different constructor? I don't want the BaseClass constructor to be called at all...

Jake Wilson
  • 88,616
  • 93
  • 252
  • 370

4 Answers4

8

You must invoke a constructor of the superclass. If you don't explicitly call one, Java will attempt to call the no-argument constructor automatically; if there is no such, you will get a compile error. The constructor you call does not need to correspond to the arguments passed to the subclass' constructor.

This is mandatory - objects' member variables can be initialized in a constructor, and not calling one of them could violate the superclass' internal assumptions.

There is no way around this short of using JNI to break the JVM.

Borealid
  • 95,191
  • 9
  • 106
  • 122
  • 1
    So lets say there is this class you want to customize. And lets say this Class is from somewhere online. Obviously just editing the original code in order to customize it seems like a bad idea. So instead, you would extend the class and make the customizations. That way, if a new version of the Class is released online, you don't have to go in and make all your changes in the code all over again. You simply extend it with your custom class. What you are saying is that if someone wants to customize a class, they are FORCED to call the parent class's constructor?? – Jake Wilson Jan 31 '12 at 04:50
  • 1
    @Jakobud If a class is `final`, you can't subclass it, and if it doesn't have a constructor you want to call, you can't use it. That's how Java works - it's not like Python where you can monkey-patch a fix in place. – Borealid Jan 31 '12 at 04:52
  • @JakeWilson ... You _may_ make your default constructor `private`, in which case you are assured that it CAN NOT be used. However as @Borealid says, you must call **_A_-constructor**. – will Jun 14 '17 at 12:54
2

You will land up calling the base class constructor. If you dont want to call this particular constructor, you will have to define a default constructor

public BaseClass(){ }

Then when you extend, this constructor will be called by default first. Only then the constructor in your SubClass will be called.

sethu
  • 8,181
  • 7
  • 39
  • 65
  • 1
    So, ultimately I'm going to end up changing the code of the `BaseClass` either way? This class is not my code. I'm attempting to customize it without changing the actual code itself. Are you saying I might as well just change it's code? – Jake Wilson Jan 31 '12 at 04:46
  • If you have to extend BaseClass then you have to either call the constructor already defined or you have to define a new default one. Unfortunately, there is no other way. – sethu Jan 31 '12 at 09:01
  • Would you say that the `BaseClass` was written poorly because it doesn't have an empty default constructor? Because if it had that, then I could extend it and allow that empty constructor to run and know that it's not going to do anything. – Jake Wilson Jan 31 '12 at 16:05
0

You don't have to call that particular constructor in parent. If parent has a default constructor defined then you can do:

public class ChildClass extends BaseClass {
    public ChildClass(URL url, String something, String whatever) {
        // implicit call to the Parent's default constructor if next line is commented
        super(); // explicit call to the default constructor of ParentClass

        // now do stuff totally specific to your ChildClass here
    }
 }
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    If you have a default constructor in the parent class, the call to super() is implied and is not required. – Jeshurun Jan 31 '12 at 04:52
  • 1
    Definitely not required, I just wanted to highlight that fact in comments that code can make implicit or explicit call to the default constructor of ParentClass. – anubhava Jan 31 '12 at 04:56
0

I'm afraid not, there is no way you can get around not editing the super class's constructor. However, if you are worried that this might affect existing code, you can use do the following, although I wouldn't normally recommend it:

  1. Move all the constructor code to a protected method in BaseClass, say something like protected void init(URL url, String something, String whatever){\\constructor code}
  2. Call this method from the constructor

    public BaseClass(URL url, String something, String whatever) { init(URL url, String something, String whatever); }

  3. Override this protected method in the subclass.

Jeshurun
  • 22,940
  • 6
  • 79
  • 92
  • I'm kinda new to Java, but it seems kinda dumb that you can't extend a class without calling it's constructor. The whole point of extending classes is to be able to add to or change the functionality of the base class. But if you are forced to call the base constructor then what's the point??? – Jake Wilson Jan 31 '12 at 04:59
  • @Jakobud: Because the state of the object is inconsistent during the constructor call, and can cause unexpected behavior. For an explanation, see [this](http://stackoverflow.com/a/3404369/473637) answer. – Jeshurun Jan 31 '12 at 05:12