Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Object instantiation context - Odd behaviour - Is it PHP bug?

I am not asking a typical question about why some code failed, yet I am asking about why it worked.It has worked with me while coding, and I needed it to fail.

Case

  • a base abstract class with a protected constructor declared abstract
  • a parent class extends the abstract class with public constructor (Over ridding)
  • a child class extends the very same abstract class with a protected constructor

      abstract class BaseClass {
        abstract protected function __construct();
      }
    
      class ChildClass extends BaseClass {
        protected function __construct(){
          echo 'It works';
         }
      }
    
      class ParentClass extends BaseClass {
        public function __construct() {
          new ChildClass();
        }
      }
    
      // $obj = new ChildClass(); // Will result in fatal error. Expected!
    
      $obj = new ParentClass(); // that works!!WHY?
    

Question

Parent class instantiates child class object, and it works!! how come it does? as far as I know,object cannot be instantiated if its constructor declared protected, except only internally or from within any subclasses by inheritance.

The parent class is not a subclass of the child class,it doesn't inherit a dime from it ( yet both extend the same base abstract class), so how come instantiation doesn't fail?

EDIT

This case only happens with an abstract BaseClass that has also an abstract constructor.If BaseClass is concerete, or if its protected constructor is not abstract, instantiation fails as expected.. is it a PHP bug? For my sanity, I need really an explanation to why PHP behaves this way in this very specific case.

Thanks in advance

like image 626
Ahmad Farouk Avatar asked Feb 24 '12 05:02

Ahmad Farouk


1 Answers

Why it works?

Because from inside ParentClass you have granted access to the abstract method from BaseClass. It is this very same abstract method which is called from ChildClass, despite its implementation is defined on itself.

All relies in the difference between a concrete and an abstract method.

You can think like this: an abstract method is a single method with several implementations. On the other hand, each concrete method is a unique method. When it has the same name than its parent, it overrides the parent's one (it does not implement it).

So, when declared abstract, it is always the base class method which is called.

Think about a method declared abstract: Why the signatures of different implementations can't differ? Why can't the child classes declare the method with less visibility?

Anyway, you have just found a very interesting feature. Or, if my understanding above is not correct, and your expected behaviour is the truly expected behaviour, then you have found a bug.

like image 157
J. Bruni Avatar answered Sep 20 '22 04:09

J. Bruni