Skip to main content

Java Constructor Inheritance


I was wondering why in java constructors are not inherited? You know when you have a class like this:




public class Super {

public Super(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
this.serviceA = serviceA;
//etc
}

}



Later when you inherit from Super , java will complain that there is no default constructor defined. The solution is obviously something like:




public class Son extends Super{

public Son(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
super(serviceA,serviceB,serviceC);
}

}



This code is repetitive, not DRY and useless (IMHO)... so that brings the question again:



Why java doesn't support constructors? is there any benefit in not doing it?



Thanks.


Source: Tips4allCCNA FINAL EXAM

Comments

  1. Suppose constructors were inherited... then because every class eventually derives from Object, every class would end up with a parameterless constructor. That's a bad idea. What exactly would you expect:

    FileInputStream stream = new FileInputStream();


    to do?

    Now potentially there should be a way of easily creating the "pass-through" constructors which are fairly common, but I don't think it should be the default. The parameters needed to construct a subclass are often different from those required by the superclass.

    ReplyDelete
  2. when you inherit from Super this is what in reality happens:

    public class Son extends Super{

    // If you dont declare a constructor of any type, adefault one will appear.
    public Son(){
    // If you dont call any other constructor in the first line a call to super() will be placed instead.
    super();
    }

    }


    So, that is the reason cause you have to call to your unique constructor, cause "Super" doesnt have a default one.

    Now, trying to guess why Java doesn't support constructor inheritance, probably cause a constructor only have sense talking about concrete instances, and you shouldn't be able to create an instance of something that you don't know how is defined (by polymorphism).

    ReplyDelete
  3. Because constructors are an implementation detail - they're not something that a user of an interface/superclass can actually invoke at all. By the time they get an instance, it's already been constructed; and vice-versa, at the time you construct an object there's by definition no variable it's currently assigned to.

    Think about what it would mean to force all subclasses to have an inherited constructor. I argue it's clearer to pass the variables in directly than for the class to "magically" have a constructor with a certain number of arguments just because it's parent does.

    ReplyDelete
  4. Because constructing your subclass object may be done in a different way from how your superclass is constructed. You may not want clients of the subclass to be able to call certain constructors available in the superclass.

    A silly example:

    class Super {
    protected final Number value;
    public Super(Number value){
    this.value = value;
    }
    }

    class Sub {
    public Sub(){ super(Integer.valueOf(0)); }
    void doSomeStuff(){
    // We know this.value is an Integer, so it's safe to cast.
    doSomethingWithAnInteger((Integer)this.value);
    }
    }

    // Client code:
    Sub s = new Sub(Long.valueOf(666L)): // Devilish invocation of Super constructor!
    s.doSomeStuff(); // throws ClassCastException


    Or even simpler:

    class Super {
    private final String msg;
    Super(String msg){
    if (msg == null) throw new NullPointerException();
    this.msg = msg;
    }
    }
    class Sub {
    private final String detail;
    Super(String msg, String detail){
    super(msg);
    if (detail == null) throw new NullPointerException();
    this.detail = detail;
    }
    void print(){
    // detail is never null, so this method won't fail
    System.out.println(detail.concat(": ").concat(msg));
    }
    }
    // Client code:
    Sub s = new Sub("message"); // Calling Super constructor - detail is never initialized!
    s.print(); // throws NullPointerException


    From this example, you see that you'd need some way of declaring that "I want to inherit these constructors" or "I want to inherit all constructors except for these", and then you'd also have to specify a default constructor inheritance preference just in case someone adds a new constructor in the superclass... or you could just require that you repeat the constructors from the superclass if you want to "inherit" them, which arguably is the more obvious way of doing it.

    ReplyDelete
  5. David's answer is correct. I'd like to add that you might be getting a sign from God that your design is messed up, and that "Son" ought not to be a subclass of "Super", but that, instead, Super has some implementation detail best expressed by having the functionality that Son provides, as a strategy of sorts.

    EDIT: Jon Skeet's answer is awesomest.

    ReplyDelete
  6. Constructors are not polymorphic.
    When dealing with already constructed classes, you could be dealing with the declared type of the object, or any of its subclasses. That's what inheritance is useful for.
    Constructor are always called on the specific type,eg new String(). Hypothetical subclasses have no role in this.

    ReplyDelete
  7. I don't know any language where subclasses inherit constructors (but then, I am not much of a programming polyglott).

    Here's a discussion about the same question concerning C#. The general consensus seems to be that it would complicate the language, introduce the potential for nasty side effects to changes in a base class, and generally shouldn't be necessary in a good design.

    ReplyDelete
  8. A derived class is not the the same class as its base class and you may or may not care whether any members of the base class are initialized at the time of the construction of the derived class. That is a determination made by the programmer not by the compiler.

    ReplyDelete
  9. Because a (super)class must have complete control over how it is constructed. If the programmer decides that it doesn't make sense to provide a default (no args) constructor as part of the class's contract, then the compiler should not provide one.

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex