32

Fairly straightforward question. In C++ the parent constructor will be implicitly called before the child constructor, so what logic is there for PHP not to do things this way?

EDIT: I've got a good answer from Lukman, but I was hoping for more of a reason why there is a difference. Maybe the question should be why does C++ not allow custom calling of parent constructors? I guess that's another question though.

4
  • 2
    Yes, I understand that! I'm sure there are differences in the languages that have influenced the decision to either call or not call the parent - I want to know the reasons. Commented Dec 15, 2009 at 10:28
  • 8
    That's a bit like saying "Why do dogs not quack?": "Because they are not ducks." Commented Dec 15, 2009 at 10:30
  • 2Skilldrick: looks like this is the answer for the question :) Commented Dec 15, 2009 at 11:15
  • Because it's a terrible language that should be avoided. PHP is a fractal of bad design. - eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design . C++ does "kind of allow you to" by overloading the ctor with an empty one and inheriting through that signature instead. A constructor should do what it says on the tin, it should be called when the object is constructed and should construct the object, if it does not, then it is forgetting its purpose. PHP is full of quirks like this and just really don't have any good reason behind them, seriously. Need any help learning C#, just ask. Commented Jul 31, 2016 at 1:57

3 Answers 3

28

I think it's a good thing that PHP makes you call parent's constructor manually, because it allows child's constructor such as following:

public function __construct() {
   // set up variables that parent::__construct() requires
   $var1 = get_stuff_from_db();
   $var2 = get_stuff_from_webservice();

   parent::__construct($var1, $var2);

   // continue setting up $this var
   $this->default = 'Default';
   $this->do_some_secret_stuff();
}

Or even:

public function __construct($param) {
   // call differently based on condition
   if (is_array($param))
      $param['id'] = 0;
      parent::__construct($param);
   }
   else {
      parent::__construct($param, 0, TRUE);
   }

   // continue setting up $this var
   $this->default = 'Default';
   $this->do_some_secret_stuff();
}

Meaning, you are free to call the parent constructor anywhere within the child's and you are free to do stuff before and after the call. Ain't that a feature indeed?

Sign up to request clarification or add additional context in comments.

10 Comments

Notice that you could easily have the parent constructor be automatically called only when the constructor body didn't already contain an explicit call to it.
A base class that requires a child class to do initialization before it can initialize itself... :O I would strongly recommend anyone in that scenario to reconsider their application design. Then again, there's no limit to the potential kludge factor with PHP.
It's bad because the constructor should always be called when an object is instantiated. Through the inheritance cycle, the inherited object type is instantiated and yet has a flag stating the constructor should not be fired. This breaks the general constructor rule and leads to confusion (proof is in the OP). On the other hand, languages such as C# or C++ allow delayed execution of constructors by implicitly asking for it, rather than breaking the default rule of constructors being called on instantiation. This is a really stupid part of PHP and should be resolved.
@developerbmw - Think again. Why would you create a function to "Instantiate required objects" if you are supplied with a constructor for that very task. In fact even the PHP documentation states: "it is suitable for any initialization that the object may need before it is used.". Please do not make any recommendations to others as you may be misguiding them. This is a fundamental oversight of PHP and it's confusing for newcomers to the language. It should be resolved and set as a configuration for PHP so that legacy code is not broken.
@developerbmw: Perhaps you are forgetting that there are two types of Inheritance; Generalization and Specialization. When you extend a Parent Class using Child Class, this is Specialization which does not make the child class constructor to call parent class constructor explicitly. However, when you implement Generalization (factoring out common functionality in base class) then the same can be a valid use-case. Second, in ORMs entity-object is hydrated without calling constructor. I see wisdom in the flexibility that PHP provides to its programmers.
|
12

When you don't have a constructor in the child class, then the parent one is automatically called.

If you decided to add a constructor to the child class, then of course you need to explicitly call the parent constructor. If you are already taking the time to add a constructor to your child class, then adding one more line of code parent::__construct(); doesn't seem to be a big deal. But the overriding is actually a convenient flexibility.

5 Comments

PHP is the only language that bad design can be called "A convenient flexibility" :D
Not sure what you are saying here? I think it's actual better design to have only one constructor responsible for getting the object into a valid state. By mixing between child and parent constructor I would say there is more to keep track of. Or otherwise, just don't create a child constructor. So PHP is conveniently encouraging the use of a single constructor.
@Brett what kind of bad design are you talking about; care to explain?
@Kyslik having to call the parent constructor explicitly could lead to problems if it is forgotten. You could argue that it may be helpful to be able to omit calling the parent constructor but in this case you should reconsider your class design.
In this case you can make some kind of "throw new exception: hey constructor wasn't called" (or something simmilar in parent class) and problem is solved... I want to be my code DRY therefore I use abstract parent and work with children only if it makes any sense.
1

to avoid tight coupling that's why inheritance (extend keyword in java) is evil and interface class is prefered see Javaworld article: http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html

Still it would be great if there was some instruction to call the parent at some point with a special keyword like forward but I have not yet seen this in any language (even Rebol) except in an unknown language invented by Paul Allen (yeah the co-founder of Microsoft) which is Openscript.

7 Comments

calling parent's method? lots of OOP languages have that. Like parent prefix in PHP, super() in Python, super in Java and even using the parent class name like BaseClass::method() in C++.
ALL OOP have that that's part of OOP :). That doesn't mean you should overuse it.
Inheritance is evil? What? So you're saying that the very fact a snake and a giraffe are animals, you should not inherit any attributes of an animal class, but rather... what? create an interface that has a method that denotes pointers to an animal? What? How is that even correct? Sheesh. And don't get me onto people saying "multiple inheritance shouldn't exist", there are real life cases where it makes logical sense. They are rare cases, but they do exist.
@Jimmyt1988 For the particular case of animals, it's perfectly valid to use inheritance. However, when coding real world applications, it is not common to have that kind of domain objects. In those scenarios, devs often say "I will extend this class so I dont need to re implement this logic". That's exploiting inheritance in a way it's not meant to be used
@Fermin Silva - so you're saying when you make a game about animals, or alien species, or ships, or any other off of this world object, you don't find it useful or even... meaningful? What about materials, like Titanium and Alloy, you don't want to inherit from metal? or Apparel like Trousers and skirt doesn't want to inherit from Clothes? This is what it's for buddy, and it occurs in almost every program / game i write. See the difference, A car does not inherit from engine, it doesn't make sense. It contains an engine, that's when you have pointers.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.