PHP继承构造函数的可见性不能声明为private

Gavin [PHP]

2009.04.06

近日在编写继承性的PHP代码时,遇到一个怪异的问题,就是继承于另外一个基类的继承类的构造函数不能声明为private(但可以是protected和public,没有继承时也是可以使用private的),问题详细描述如下:

原来正常工作代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
class ClassB {
 
	/**
	 * constructor
	 */
	private function __construct() {
 
        }
 
	/**
	 * destructor
	 */
	public function __destruct() {}	
 
	public function printit() {
		echo 'print it in ClassB.<br />';
	}
 
	private static $instance = null;
	public static function getInstance() 
	{
		if ( self::$instance==null ) {
			$c = __CLASS__;
			self::$instance = new $c;			
		}
		return self::$instance;
	}		
}
 
$objB = ClassB::getInstance();
$objB->printit();
?>

输出:
print it in ClassB.

加入继承后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
class ClassA {
 
	/**
	 * constructor
	 */
	protected function __construct() {}
 
	/**
	 * destructor
	 */
	public function __destruct() {}
 
	public function printit() {
		echo 'print it in ClassA.<br />';
	}	
}
 
class ClassB extends ClassA {  // <strong>加入继承</strong>
 
	/**
	 * constructor
	 */
	private function __construct(){
 
        }
 
	/**
	 * destructor
	 */
	public function __destruct() {}	
 
	public function printit() {
		echo 'print it in ClassB.<br />';
	}
 
	private static $instance = null;
	public static function getInstance() 
	{
		if ( self::$instance==null ) {
			$c = __CLASS__;
			self::$instance = new $c;			
		}
		return self::$instance;
	}		
}
 
$objB = ClassB::getInstance();
$objB->printit();
?>

输出:no work, 没有任何输出。

正确运行版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
class ClassA {
 
	/**
	 * constructor
	 */
	protected function __construct(){}
 
	/**
	 * destructor
	 */
	public function __destruct() {}
 
	public function printit() {
		echo 'print it in ClassA.<br />';
	}	
}
 
class ClassB extends ClassA {
 
	/**
	 * constructor
	 */
	public function __construct(){	// <strong>也可以用protected</strong>
 
	}
 
	/**
	 * destructor
	 */
	public function __destruct() {}	
 
	public function printit() {
		echo 'print it in ClassB.<br />';
	}
 
	private static $instance = null;
	public static function getInstance() 
	{
		if ( self::$instance==null ) {
			$c = __CLASS__;
			self::$instance = new $c;			
		}
		return self::$instance;
	}		
}
 
$objB = ClassB::getInstance();
$objB->printit();
?>

回顾三个成员变量和方法修饰符的作用:
public : 被修饰的成员变量或方法可以在任何范围内(通过对象引用符或者类限定符)被访问或调用
protected : 被修饰的成员变量或方法可在本类内继承类内被访问或调用,不能在本类和继承类被访问或调用
private : 被修饰的成员变量或方法仅可在本类内被访问或调用,不能从继承类中访问或调用

上述现象似乎并没有跟上面的规定相抵触,但在继承类中使用private于构造函数就是不行。具体原因我还不得而知,知道者还望告知一下,^_^


3 条评论

  1. 很简单, 构造函数是在你的类 new的时候, 就开始使用了, 如果,你在构造函数里使用private, 那么与他的理论就起冲突了。

  2. 嗯,有道理。。。thx

  3. 细想了一下,这样的解释似乎不对。
    的确,“构造函数是new类的时候”就开始调用了,但构造函数设定为private应该是可行的吖,因为就想限定调用者使用new生成ClassB的实例,只能使用getInstance来获得一个单例。
    这样做在非继承类里是可以的,如第一段代码所示。但在继承类里就不行了。

评论

输入后可按 Ctrl+Enter 提交评论.