Question:
What's the philosophy behind having to call constructor methods before all else?
?
2018-05-06 03:51:57 UTC
I'm currently a CS student working with Java, and I was wondering if anyone knew the reason why the constructor of the base class has to be the first statement in the constructor of a derived class. I'm aware of the issue of derived class data relying on that from the base, but what about having the derived class conform to more specific standards than the base class?

I ask because I'm working on a HW assignment where we have to create a Quadrilateral base class with a Trapezoid derived class. While the arguments of the base constructor are the four points, I wanted to try to make the arguments of the trapezoid things like height, and length of the two sides. This way, the constructor could derive the points and ensure all trapezoid methods work properly. In this case, it's easy to do all the computation in the method call itself, but it seems like a problem in more complex scenarios.

Sorry for the long question, but I just can't figure out the rationale behind some of the design philosophies in OOP.
Five answers:
husoski
2018-05-06 10:26:43 UTC
It's not as mysterious as "things work better that way" or anything.



The primary duty of a constructor is to make sure that an object is in a valid state before any methods are called. That's the answer to your question on top. Without a constructor, the methods of an object have no way to know whether fields have meaningful values.



Java has two ways to initialize objects, other than running a constructor, but those always run even before the constructor is called, so the same principle applies. Initialization happens before any method calls. (Yes, you can violate this on purpose by calling methods in the constructor before all critical fields have been set. A good IDE or compiler might warn you about that.)



The same principle applies with inheritance. The private fields defined in the superclass must be initialized before any superclass methods are called. The super() constructor call makes sure that the inherited part of the object is valid, so that inherited methods may be called.



The super() statement looks like a function call, but it's really more of a declaration. What it does is allow arguments to be passed to the the superclass constructor. If you don't provide a super() statement, one (with no arguments) is generated for you.



Back to your problem: If you can use "setter" methods to set the vertex coordinates, then you can use those instead of super() arguments to get the information into the base class fields.



If the base class is immutable (meaning you can't change the contents after creation...String objects are immutable, for example) then you have a problem. One solution is to use factory methods. That's a static method that *returns* a reference to a newly created object. That method can do as much computation as needed to get the vertex coordinates and then use new Trapezoid(vertexA, vertexB, ...) to construct a new Trapezoid object, given all values needed for the Quadrilateral superclass constructor call, plus values for any extra fields you have for the Trapezoid (like precomputed base and height.)



The user then calls Trapezoid.create(...arguments...) instead of new Trapezoid(...arguments...), which is almost as easy to type and gets the same thing done.
AJ
2018-05-07 13:35:46 UTC
The constructor is there to ensure required properties are populated.
?
2018-05-06 21:50:12 UTC
It sounds like your Quadrilateral class only has a constructor like



public Quadrilateral (Point a, Point b, Point c, Point d)



As soon as you provide a custom constructor, Java no longer adds the default, argument-less constructor. So to avoid having to call super( ... ) with four meaningless arguments, all you need to do is add a minimalist Constructor to the base class:



public Quadrilateral() {}



Now, in your Trapezoid constructor, you can just call

super();

then actually calculate the points.



You still need to have super() as the very first statement in your constructor, but it's no longer weird.
Shadow Wolf
2018-05-06 07:59:12 UTC
It's really simple. Your derived class can't access a class that doesn't exist yet. So you call the constructor to link up your derived class with the base class and create an instance of the base class when the derived class is created. This is how any OOP language has to work.



There has to be a mechanism that tells the compiler or interpreter that your derived object is really just an extension of the base object. You have the same basic problem with any OOP language. Somehow the derived class is linked to the base class in such a way that the compiler or interpreter knows to call the base class when needed. You could get roughly the same results if you could simply declare a class is derived from or connected to a base class. The compiler would have to be smart enough to create the code to make a base instance for you. The same constructor calls would still be there except now it's hiding and you don't explicitly need to declare it in your constructor. The compiler sticks it in there for you.



I'm not sure there is any philosophy there. It is simply a language design choice. I gave an alternate method of getting the same results but then it might not be Java any more. Maybe it's C++ or some other language.
L. E. Gant
2018-05-06 03:57:36 UTC
Without the constructor methods, you can't instantiate an object.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...