__construct的可见性

3
如果我有以下内容:
abstract class AbstractSingleton
{
    protected static $instance;

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

    protected function __construct() { }
}

一个扩展类的用户能否重新定义 __construct 的可见性?

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

第二个问题是,如果在AbstractSingleton中将__construct定义为私有,那么对于子类会发生什么情况?是否根本没有构造函数?该类会提供一个新的默认构造函数吗?如果是,可见性是什么?


1
又是一个例子,说明单例模式不值得麻烦。 - Major Productions
2个回答

4

首先,你不需要从你的方法中返回一个引用 (&)。自 PHP 5 起,默认情况下对象按引用传递和返回。

对于你实际的问题,如果子类要访问父类的成员,它的访问修饰符至少应该是 protected。这也适用于构造函数。所以,在你的情况下,子类将能够执行以下操作:

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

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

        // more code
    }
}

为了避免这种情况,可以使用final关键字。参见:PHP文档
至于你的第二个问题,如果将AbstractSingleton的构造函数设为私有并尝试在其子类上调用,则将使用默认的public构造函数,就像以前一样。
编辑:话虽如此,Singletons几乎从来不是一个好主意,特别是在PHP中。很有可能,您可以通过利用PHP对象自动被传递/返回作为引用来解决问题。如果不行,依赖注入是一个更加面向对象友好的选择。

3
如果你将__construct()方法声明为final,那么子类将无法覆盖此方法。http://php.net/manual/en/language.oop5.final.php 在PHP中,您可以在子类中向上修改级别(例如,从父类的私有访问级别修改到子类公共访问级别),但不能反过来。
编辑 - 如果您将__construct()方法声明为私有,则除了该类内部,您无法执行new Class()

好的,谢谢!如果我将子类设为私有,会发生什么? - Virus721
@Virus721 除了在 AbstractSingleton 内部,你将无法调用新的 Singleton。 - aknosis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接