PHP - Class that can be instantiated only by another class
Imagine this scenario:
class Page {}
class Book {
private $pages = array();
public function __construct() {}
public function addPage($pagename) {
array_push($this->pages, new Page($pagename));
}
}
Is there anyway i can make sure on开发者_C百科ly objects of my class Book can instantiate Page? Like, if the programmer tries something like:
$page = new Page('pagename');
the script throws an exception?
Thanks
It's a bit contrived, but you could use this:
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 );
Well, I see your point, but with the tools provided by the language, this is not possible.
One thing you could do, is require a Book object when constructing a Page:
class Page {
public function __construct( Book $Book ) {}
}
class Book {
public function addPage() {
$this->pages[] = new Page( $this );
}
}
I think that the most you can get, is to have Page
demand Book
as one of it's constructor arguments, and have it add page to this instance of Book. This way you never have Page
s floating around, but they're always bound to some book (although it's still possible to have same Page
in many Book
s.
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);
}
}
That looks ugly though... :/
No. In PHP, it's not possible. Even if it would be possible, developer could modify to his own needs and disable your exeption...
精彩评论