Virus721
Virus721

Reputation: 8315

Visibility of __construct

If I have:

abstract class AbstractSingleton
{
    protected static $instance;

    public static function & getInstance()
    {
        if(null === static::$instance) static::$instance = new static();
        return static::$instance;
    }

    protected function __construct() { }
}

Can a user who extends the class redefine the visibility of __construct?

class Singleton extends AbstractSingleton
{
    public function __construct() { } // That would be a problem
}

And second question, what happens for subclasses if __construct is defined as private in AbstractSingleton? Is there not constructor at all? Is a new default constructor provided to the class, and if yes, with what visibility?

Upvotes: 3

Views: 3495

Answers (2)

aknosis
aknosis

Reputation: 4308

If you make __construct() final then the sub classes cannot override this method. http://php.net/manual/en/language.oop5.final.php

In PHP you can modify the level upwards in sub classes (you can go from private in the parent to public in the sub class) but you cannot go in reverse.

Edit - If you make __construct() private than no where other than inside that class you can do new Class().

Upvotes: 3

Major Productions
Major Productions

Reputation: 6042

Well, for starters, you don't need to return a reference (&) from your method. Since PHP 5, objects are passed and returned by reference by default.

To your actual question, for a child to access a member of a parent, its access modifier needs to be at least protected. That counts for constructors as well. So, in your case, a subclass would be able to do:

abstract class AbstractSingleton
{
    protected __ construct() {}
}

class Singleton extends AbstractSingleton
{
    public __construct()
    {
        parent::__construct();

        // more code
    }
}

The way to get around that is to use the final keyword. See: PHP documentation.

For your second question, if you make AbstractSingleton's constructor private and try to invoke one on its child, then a default, public constructor will be used instead, just like always.

EDIT: With all that said, Singletons are hardly ever a good idea, especially in PHP. Chances are, you can solve your problem with merely taking advantage of PHP objects automatically being passed/returned by reference. If not, Dependency Injection is a far more OOP friendly alternative.

Upvotes: 4

Related Questions