无法将构造函数定义为protected或private!为什么?

时间:2011-01-17 10:35:19

标签: php

--- A.php ----
require_once 'B.php';

class A
{
    public function __constructor($x){...}

    public function foo()
    {
        $b = B::getInstance();
        ...
    }
}

--- B.php ----
require_once 'A.php';

class B extends A
{
    protected static $_instance = null;

    protected function __construct(){}

    public static function getInstance()
    {....}
}

PHP只要在到达行

时就停止解释代码
protected function __construct(){}

并输出之前的所有内容,之后不会发送任何内容。

我只要把这条线拿出去,就把它换成

// protected function __construct(){}

一切正常!?

我不明白。

有什么想法吗?

3 个答案:

答案 0 :(得分:12)

我刚刚创建了一个简单的测试文件来确认这是否也发生在我的机器上,我想我已经找到了答案。请使用以下代码:

<?php
error_reporting( E_ALL | E_STRICT );
class Foo {
    public function __construct( ) {
    }
}

class Bar extends Foo {
    protected function __construct( ) {
    }
}

当尝试执行该代码时,我收到一个致命的错误:“PHP致命错误:Bar :: __ construct()的访问级别必须是/home/berry/foo.php中的公共(如在类Foo中) 12.”这意味着你不能改变子类中的访问级别,如果父级已经定义了访问级别,这实际上很有意义:PHP我不会知道要调用哪个构造函数。

作为旁注:通过查看你的代码,B扩展A,A使用B.为什么这样,对我来说这似乎是一个奇怪的结构?我猜你真的想要的是composition, not inheritance

答案 1 :(得分:6)

可以将构造函数定义为protected或private。此代码编译 runs just fine since OOP was rewritten for PHP/5

<?php

class A{
    public function __construct(){
        echo 'Instance of A created' . PHP_EOL;
    }
}

class B{
    protected function __construct(){
        echo 'Instance of B created' . PHP_EOL;
    }
}

class C{
    private function __construct(){
        echo 'Instance of C created' . PHP_EOL;
    }
}

当然,私有构造函数会阻止您使用new关键字创建实例,但PHP会触发致命错误(它不会停止运行):

<?php

new A; // OK
new B; // Fatal error: Call to protected B::__construct() from invalid context
new C; // Fatal error: Call to private C::__construct() from invalid context

答案 2 :(得分:1)

您可以创建自定义静态启动器:

<?php

class FancyClass {
    public static function init() {
        new self();
    }

    protected function __construct() {
        echo 'Instance created!';
    }
}

# This will not work.
new FancyClass();

# But this will work.
FancyClass::init();