首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以从现有的对象实例化吗?

可以从现有的对象实例化吗?
EN

Stack Overflow用户
提问于 2017-08-25 16:15:55
回答 2查看 94关注 0票数 2

我偶然发现了这件事,并想知道这是否是预期的行为:

代码语言:javascript
复制
Interactive shell

php > class dog {
php {   public $name='doggy';
php {   public function speak() {
php {     echo "bark, bark! (my name is " . $this->name . ")\n";
php {   }
php { }
php >
php > $puppy = new dog;
php > $puppy->speak();
bark, bark! (my name is doggy)
php >
php > $taffy = new $puppy;
php > $taffy->speak();
bark, bark! (my name is doggy)
php >
php > $taffy->name = "Taffy";
php > $taffy->speak();
bark, bark! (my name is Taffy)
php >
php > $puppy->speak();
bark, bark! (my name is doggy)
php >

我的问题是关于台词的,$taffy = new $puppy;

通常,我会编码$taffy = new dog;

我不希望通过实例化来创建一个新的对象.如果这有什么意义的话。

这是预期的功能,还是仅仅是一个愉快的意外?

我在构建一个需要与几个不同的db表对话的模型时发现了这一点,我使用依赖注入来传递数据库抽象:

代码语言:javascript
复制
class ShowConnectedTables {
  public function __constructor($db) {
    $this->modelOne = new ModelOne($db);
    $this->modelTwo = new ModelTwo($db);
  }
  // ... snip ...
}

$table = new ShowConnectedTables(new Database);

但是,有时候,在循环取取ModelOne的行的过程中,对ModelTwo的数据库调用可能会破坏ModelOne的行的取取。所以这能接受吗?

代码语言:javascript
复制
class ShowConnectedTables {
  public function __constructor($db) {
    $this->modelOne = new ModelOne($db);
    $this->modelTwo = new ModelTwo(new $db); // note new abstraction
  }
  // ... snip ...
}

$table = new ShowConnectedTables(new Database);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-25 16:31:29

我从来没见过这个也没做过这个。因此,我可能会避免它:如果它会导致其他开发人员查看它并抓伤他们的头(就像您所做的那样),那么它可能是不值得的。我看不出你为什么要这么做,毕竟。

不要惊慌失措地指出,虽然没有明确记录,但PHP文档中有这样做的例子。此页面上的示例5。

尽管如此,并没有克隆:

代码语言:javascript
复制
class dog {
    public $name='doggy';
    public function speak() {
        echo "bark, bark! (my name is " . $this->name . ")\n<br>";
    }
    public function __clone() {
        print 'This is not called!';
        parent::__clone();
    }
}
$class = 'dog';
$puppy = new dog;
$puppy->name = 'Puppy';
$taffy = new $puppy;
if ( spl_object_hash( $taffy ) != spl_object_hash( $puppy ) )
    print 'not the same object';
$taffy->speak();

如果您这样做,您将发现对象是不一样的,并且永远不会调用__clone方法。另外,您的taffy将被初始化为doggy,而不是Puppy。这似乎实际上是以下几个方面的缩写:

代码语言:javascript
复制
$class = get_class( $puppy );
$taffy = new $class;
票数 2
EN

Stack Overflow用户

发布于 2017-08-25 16:33:21

这不是创建对现有对象的新引用的问题。构造函数被执行,这意味着这是一个新的对象。我累了:

代码语言:javascript
复制
<?php

class dog {
   public $name;
   public function __construct($name = '') {
       $this->name = $name ?: 'doggy';
   }
   public function speak() {
     echo "bark, bark! (my name is " . $this->name . ")\n";
   }
}

$puppy = new dog;
$puppy->speak(); #bark, bark! (my name is doggy)

$taffy = new $puppy('Snuffels');
$taffy->speak(); #bark, bark! (my name is Snuffels)

$taffy->name = "Taffy";
$taffy->speak(); #bark, bark! (my name is Taffy)

$puppy->speak(); #bark, bark! (my name is doggy)
echo $puppy;

其原因是,您已经可以使用new selfnew parent之类的东西,请参阅http://php.net/manual/en/language.oop5.basic.php

在类上下文中,可以通过new selfnew parent创建一个新对象。

我假设,他们在new之后实现了类识别。但仍然是一个很好的WTF :)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45885608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档