想象一下这种情况:
class Page {}
class Book {
private $pages = array();
public function __construct() {}
public function addPage($pagename) {
array_push($this->pages, new Page($pagename));
}
}
无论如何,我可以确保只有我班级的对象可以实例化页面吗? 就像,如果程序员尝试类似的东西:
$page = new Page('pagename');
脚本会抛出异常吗?
由于
答案 0 :(得分:4)
嗯,我明白你的观点,但是使用该语言提供的工具,这是不可能的。
您可以做的一件事是,在构建Page时需要Book对象:
class Page {
public function __construct( Book $Book ) {}
}
class Book {
public function addPage() {
$this->pages[] = new Page( $this );
}
}
答案 1 :(得分:4)
这有点做作,但你可以使用它:
abstract class BookPart
{
abstract protected function __construct();
}
class Page
extends BookPart
{
private $title;
// php allows you to override the signature of constructors
protected function __construct( $title )
{
$this->title = $title;
}
}
class Book
extends BookPart
{
private $pages = array();
// php also allows you to override the visibility of constructors
public function __construct()
{
}
public function addPage( $pagename )
{
array_push( $this->pages, new Page( $pagename ) );
}
}
$page = new Page( 'test will fail' ); // Will result in fatal error. Comment out to make scrip work
$book = new Book();
$book->addPage( 'test will work' ); // Will work.
var_dump( $book );
答案 2 :(得分:2)
我认为你能得到的最多,就是让Page
要求Book
作为其中一个构造函数参数,并将它添加到这个Book实例中。这样你就不会有Page
个浮动,但它们总是绑定到某本书(尽管在许多Page
中仍然可以使用相同的Book
。
class Book {
public function addPage($page) {
if(is_a($page,'Page') {
$this->pages->push($page);
} else if (is_string($page)) {
new Page($this,$page)
} else {
throw new InvalidArgumentException("Expected string or 'Page' - ".gettype($page)." was given instead");
}
}
}
class Page {
public function __construct(Book $book, $pagename) {
$book->addPage($this);
}
}
虽然看起来很难看......:/
答案 3 :(得分:1)
没有。在PHP中,它是不可能的。即使有可能,开发人员也可以根据自己的需要进行修改并禁用您的执行...