Php 使用相同的超类强制转换对象

Php 使用相同的超类强制转换对象,php,oop,Php,Oop,鉴于: 类X扩展了 类Y扩展了 我有一个类X的对象,希望创建一个类Y的对象,该对象与类X的对象共享所有字段(无论是深拷贝还是浅拷贝),它们通过类A共享这些字段 我可以将类X的对象强制转换为类Y,或者以其他方式复制它们的所有共同属性吗?如果您只是问:我如何轻松创建类Y的变量,该变量具有类X的变量的所有共同内容?那么我想你会得到一个更快的答案。但是你问了一个关于演员的问题 强制转换是一种“欺骗”编译器(或在本例中是解释器)将一种类型的变量解释为另一种类型的变量的方法。如果你知道你在做什么,这有时

鉴于:

  • 类X扩展了
  • 类Y扩展了
我有一个类X的对象,希望创建一个类Y的对象,该对象与类X的对象共享所有字段(无论是深拷贝还是浅拷贝),它们通过类A共享这些字段


我可以将类X的对象强制转换为类Y,或者以其他方式复制它们的所有共同属性吗?

如果您只是问:我如何轻松创建类Y的变量,该变量具有类X的变量的所有共同内容?那么我想你会得到一个更快的答案。但是你问了一个关于演员的问题

强制转换是一种“欺骗”编译器(或在本例中是解释器)将一种类型的变量解释为另一种类型的变量的方法。如果你知道你在做什么,这有时会派上用场。然而,大多数时候,这是一个坏主意

强制转换到对象不是,但如果是,您可以编写:

class A {
  public $foo = 1;  
}
class X extends A {
  public $bar  = "2";
}

class Y extends A {
  public $bom = 3;
}

$x = new X();
$y = (Y) x;
您希望PHP将变量
$y
视为y类型,还是希望它实际上是y类型?上述措施将实现第一个目标,而不是后一个目标。只要访问
$y->bom
,程序的执行就会出现问题,因为没有为
$bom
分配内存,也没有初始化它。在允许T的语言中,如C++,这可能会导致.< /p> 因此,你不需要施法,你不想施法,也不能一开始就施法。忘记铸造:)

您要做的是创建一些方法,将另一个对象的字段复制到您的对象实例。以下是一个例子:

class A {
  public $foo;  

  public function copy($cA) {
    $this->foo = $cA->foo;
  }
}
class X extends A {
  public $bar;

  public function copy($cX) {
    if ($cX instanceof A) parent::copy($cX);
    if ($cX instanceof X) {
      $this->bar = $cX->bar;
    }
  }
}
class Y extends A {
  public $bom;

  public function copy($cY) {
    if ($cY instanceof A) parent::copy($cY);
    if ($cY instanceof Y) {
      $this->bom = $cY->bom;
    }
  }
}

$x = new X();
$x->foo = "hello";
$x->bar = "world";

$otherX = new X();
$otherX->copy($x);
echo "$otherX->foo $otherX->bar \n"; // hello world 

$y = new Y();
$y->copy($otherX);
echo "$y->foo \n"; // hello
本例中的复制方法是通过赋值。但这不是很灵活,因为这意味着每次在这些类中添加属性或重命名属性时,都必须更新copy方法以反映更改

以下是实现同样目标的更灵活的方法:

class A {
  protected $foo;  

  public function copy($cA) {
    foreach (get_object_vars($cA) as $key => $value) {
      $this->$key = $value;
    }
  }

  public function setFoo($foo) {
    $this->foo = $foo;
  }
}
class X extends A {
  public $bar;

  public function out() {
    echo "$this->foo $this->bar \n";
  }
}
class Y extends A {
  public $bom;

  public function out() {
    echo "$this->foo $this->bom \n";
  }
}

// setup x
$x = new X();
$x->setFoo("hello");
$x->bar  = "world";

// setup otherX
$otherX = new X();
$otherX->copy($x);

$x->setFoo("hi"); 

$otherX->out(); // -> hello world

// setup Y
$y = new Y();
$y->copy($x);
$y->bom = "php";

$y->out();     // -> hi php
虽然这种方法灵活得多,但也有些粗糙

echo $y->bar; // has become "world"
之所以会出现这种情况,是因为
get\u object\u vars
没有查看每个类类型可以包含哪些变量。您可以使用ReflectionClass在某种程度上解决这个问题,但我猜此时您已经得到了所需的答案

希望这有帮助


祝你好运

最后一点是什么?可能重复的除非您键入提示,否则任何事情都是可能的。如果键入提示X,则Y不兼容。强制转换将不起作用,但是如果仍然有一个公共接口,那么也许您可以让它们同时实现一个接口以及扩展一个。。?有很多选择。这将取决于你的具体情况。你能提供一个最具体的例子吗?谢谢你的补充信息和澄清,但是为什么你需要一个副本?@TwiStar,没有重复,这些对象是通过公共超类关联的