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
}

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

4

2 回答 2

4

好吧,对于初学者来说,您不需要&从您的方法中返回引用 ( )。从 PHP 5 开始,对象默认通过引用传递和返回。

对于您的实际问题,要让孩子访问父母的成员,其访问修饰符至少需要受到保护。这对构造函数也很重要。因此,在您的情况下,子类将能够执行以下操作:

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

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

        // more code
    }
}

解决这个问题的方法是使用final关键字。请参阅:PHP 文档

对于第二个问题,如果您将 AbstractSingleton 的构造函数设为私有并尝试在其子级上调用一个,则将使用默认的公共构造函数,就像往常一样。

编辑:话虽如此,单例几乎不是一个好主意,尤其是在 PHP 中。很有可能,您只需利用通过引用自动传递/返回的 PHP 对象即可解决您的问题。如果不是,依赖注入是一种对 OOP 更友好的替代方案。

于 2012-12-04T21:08:00.463 回答
3

如果你使 __construct() final那么子类不能覆盖这个方法。http://php.net/manual/en/language.oop5.final.php

在 PHP 中,您可以在子类中向上修改级别(您可以从父类中的私有变为子类中的公共),但不能反过来。

编辑 - 如果您将 __construct() 设为私有而不是在该类内部以外的任何地方,您都可以这样做new Class()

于 2012-12-04T21:05:57.113 回答