-2

It is an error if you do anything in a constructor before calling the superconstructor. I remember that I had problems because of that. Yet, I do not see how this saves us from errors. It could save you from using uninitialized fields. But, the Java compiler that checks for using uninitalized variables does that and this stupid rule does not improve anything here.

The only serious consideration argument I remember was that we need it for OOP, because objects in real life are constructed this way: you create a cucumber by first creating a vegetable and then add cucumber attributes. IMO, it is opposite. You first create a cucumber and, by duck is a duck principle, it becomes a vegetable. Another argument was that it improves safety. Not writing the code improves the dependability much better, so I do not consider this as argument. Creating more complex code when you need to workaround a stupid restriction, is what makes the program more error-prone.

This rule creates a serious pain (at least for me). So, I want to hear the serious argument and serious example where it could be useful.

  • 8
    Well,copy pasting your title into google turned up this as the first result stackoverflow.com/questions/1168345/… – Daniel Gratzer Jul 31 '13 at 11:39
  • 10
    Don't assume that something you don't understand must be "stupid". – Michael Borgwardt Jul 31 '13 at 12:00
  • 2
    @Val As jozefg already linked an answer please read the answer first and don't flame around here (at Michael Borgwardt). There answer written on stack overflow is fine. – Uwe Plonus Jul 31 '13 at 12:28
  • 8
    @Val, I'm not sure if english is your first language, but you are coming across as very demanding and very rude. This probably explains why, as you've mentioned, you've been banned from a forum for asking what you think is a reasonable question. Step back and be a bit more careful with your words. You can only expect constructive feedback if you yourself are being constructive. – MetaFight Jul 31 '13 at 13:15
  • 2
    @Tombatron, What do you mean by "try C#"? The same thing is enforced in C#. Before the subclass constructor is executed, unless specified otherwise, the default (parameterless) public or protected superconstructor is invoked. Or am I wrong? – MetaFight Jul 31 '13 at 13:16
9

The object initialization sequence is complex enough as it is and already sometimes causes headaches. Allowing subclasses to run code before the superclass constructor would make it more complex and confusing still, with more potential for subtle bugs, especially if there is a hierarchy of multiple classes which all do this.

It also reduces the conceptual coupling between superclasses and subclasses. You look at the superclass and can see how it will be initialized before it is used. Allowing subclass code to do arbitrary stuff before the superclass initialization could easily break some assumptions made by the superclass code, and subclasses should, as much as possible, not have to depend on understanding of implementation details of the superclass.

All in all, not allowing subclass code to run before the superclass is fully initialized leads to code that is easier to understand and less error-prone. It may sometimes require workarounds, but just because a rule prevents you from doing what would be convenient in your immediate circumstances does not mean it's a bad or stupid rule.

|improve this answer|||||
  • Huh? I regularly use code before the inherited call and have yet to run into problems with that. Even use it as a feature to initialize members exposed by the super class before being used in the super constructor so descendants get a handle on that without having to break out parts of the constructor into separate functions. Anyway, could it be that this argument is language specific? I use Delphi and all instance memory has been allocated and initialized before any of the constructors in the hierarchy run. Does that mean I am spoilt rotten? :-) – Marjan Venema Jul 31 '13 at 18:19
  • 1
    @MarjanVenema question is tagged Java, and init sequence is indeed important (and strictly specified) there. Eg invoking an abstract method (yet to be defined in subclass) in superclass constructor throws NPE - that's one of my favorite coding mistakes (luckily it's easy to discover, even in unit tests) – gnat Aug 1 '13 at 5:49
  • It was tagget 'Java' to discuss the restriction we see in that language, not to prohibit comparison with other OOP implementations. – Val Aug 1 '13 at 7:24
  • 1
    @Gnat: thanks for the clarification. It helps me understand the question's significance. – Marjan Venema Aug 1 '13 at 8:16
  • 1
    @MichaelBorgwardt I'd rather avoid using words like horrendous, as these shift things into better-worse holy wars territory. It's unlikely that design choices are based on a reasoning like that, especially in scrupulously designed and specified language like Java. I'd rather bet there was sort of impartial evaluation involved here, like comparing and weighting benefits and drawbacks of various available options. Like flexibility vs simplicity, stuff like that... – gnat Aug 1 '13 at 10:04
4

When you inherit from an object, you may not be able to see the implementation of the constructor or underlying methods.

There may be more going on in the constructor than just initialization of variables. such as hardware access, database access, network communication, etc. Not saying this is good design or not - just saying you may not be aware of it.

But even if it was just variables. There may be member functions that rely on those variables being instantiated properly. There may be function calls that occur in the instantiation of those variables. Because of encapsulation you can't be sure that isn't the case, so to be safe you fully construct your base item first - otherwise your implementation may cause the super class to "break".

And it works the other way around to. If someone inherits from your class, you know that your construction code will execute properly. The programmer inheriting your class can never break your code, just his. If he is having a problem, he knows he should check his code.

|improve this answer|||||
  • Ok, you say "do not call inherited methods before super is initialized". But, requirement for super() be the first is different. It says that I cannot initialize my own, newly introduced fields before calling the super(). Do you feel the difference? Secondly, your database may fail if the order of method calls is wrong. Preinitializing the parent object does not save from that. Right? The super object designer must specify the proper order of calls, including super(). That is why I say that super-first does not add anything. I do not see how your answer addresses these issues. – Val Jul 31 '13 at 12:42
  • 5
    By forcing the super() call first it assures that the base object is fully constructed. The goal here is to make sure nothing you do will break the super class's code. At least, that is the reason for it. Technically, even if the code you introduce works - but it causes the super class's code to not work the way it was intended - you broke it. And it doesn't matter if it does break it - it matters if it COULD break it. – Don Nickel Jul 31 '13 at 12:52
  • Do I break the supreclass if call first method_B then method_A whereas it required method_A then method_B? Could I brake it? – Val Jul 31 '13 at 13:59
  • @Val: If the superconstructor calls method_A which initializes a resource that method_B requires, but in your subclass constructor you call method_b before super(), then method_b might be expecting the resource to be ready to use, but it isn't and that could cause runtime errors. – FrustratedWithFormsDesigner Jul 31 '13 at 14:15
  • I say nothing about super(). I start with case where method A and B are called on initialized object. The workflow demands A first. You mistakenly call B first and break something in the object. Will this break the object? Could wrong order of calls break an initialized objects? Object constantly evolves. How can you say that it is completely initialized? Could wrong order of method invocations break the initialized object? – Val Jul 31 '13 at 14:28
3

You first create a cucumber and, by duck is a duck principle, it becomes a vegetable.

Except Java isn't a structurally (duck) typed language. It's a nominatively typed language.

If Java was a structurally typed language (or simply a dynamic one), then your mental picture of how it works would be good.

Since it is not, it needs to build the object layout in memory which is most efficiently done by layering the derived types around the base types (think Shrek's onion) so that the base type's layout can be reused for just the base type as well as its derived types.

Does it have to be that way? Not at all, and it often isn't for languages that are not nominatively typed (or can have multiple base types). But in Java it is, and frankly is one of the least onerous restrictions the language puts on you.

As for your question, you're getting pushback because you come off as a know-it-all who clearly does not. It's good to ask why, but to say that this design is completely stupid because it's causing you trouble (because you can't do object oriented design well) is ignorant at best.

And yes, if you're in a scenario where you want to do operations in the constructor before calling the base constructor that is a pretty solid indication that you're not so great at OOD.

|improve this answer|||||
  • Indeed, I ask this question because I am not great at OOD. But, those who defend the superconstructor produce logic like this, programmers.stackexchange.com/a/206657/63834 They say that vegetable must be built before cucumber because cucumber IS A vegetable and, similarly, 2nd floor is related with the 1st one! This nonsense makes me to think that learning perfect OO design destroys people minds. How do you prove that student's feeling that lang is wrong means that student is stupid? How do you prove that lang is wrong? By praising it first? – Val Jul 31 '13 at 14:38
  • @val - In general, the language is never wrong. It might do it weirdly, but there are many, many ways to model computation. – Telastyn Jul 31 '13 at 14:53
  • If language is never wrong then having superconstructor first is as good/bad as not doing it? – Val Jul 31 '13 at 14:56
  • 3
    @val - eh? Requiring the superconstructor first is a design choice. Many languages don't require it. Some do though, and do so for good reasons. It just happens that two of the most popular languages (Java, C#) have that constraint. – Telastyn Jul 31 '13 at 15:00
1

In layman's words:

An inheritance relationship is an "IS A" relationship.

If Human inherits from Ape, it means that a Human is, firstly, an Ape then a Human. ( I'm not saying humans descent from apes, but that they are apes ).

It makes sense that you first initialize your Ape self in order to built upon it and get to be your Human self.

The superclass is the base you built upon, meaning you have to have an instance of the supeclass to extend from.

It makes no sense to built the second story of your house prior to building the first story.

|improve this answer|||||
  • 4
    @Val Calm down and be nice. – yannis Jul 31 '13 at 15:35
  • You cannot create an instance of fruit before apple. You first create apple and it happens to be a fruit. In reality fruit does not exist alone, without apple. Changing fruits -> apes does not change this. Even the magic spelling IS A will not do it for you. Secondly, store2 IS NOT A store1. So, your theory of construction seems natural for an OOD practitioner, but is incompatible with reality. The fact that you have to use wrong analogy to support it just proves that. – Val Jul 31 '13 at 15:56
  • 3
    @Val: your previous comment was deleted because, while you were trying to point out problems with the answer in a reasonable fashion, you got kinda personal. I've corrected your last comment - please try to stick to critiques of the answer itself, not its author. – Shog9 Jul 31 '13 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.