5

我可能在这里遗漏了一些明显的东西,因为这是其他 OOP 语言中的基本功能,但我正在努力使用 PHP 的方式来做到这一点。我知道 PHP 不是“真正的”OOP 语言,但仍然......

我所追求的是将实例化为派生类的对象转换为基类。类似于以下内容:

class Some{}

class SomeMock extends Some {}

function GetSomeMock(){
  $mock = new SomeMock();
  return (Some)$mock; //Syntax error here
}

我发现了一些关于将基类对象向下转换为派生的奇怪请求的问题,这可以通过一些讨厌的调整来实现,但是这个基本功能不必那么困难。我在这里想念什么?

编辑:似乎我想要实现的目标总是很重要。没问题。GetSomeMock() 是一个工厂方法,它将返回一个具有预期属性值的模拟对象存根(从基类派生,所有属性都预先填充在构造函数中)。然后我会将它与从数据库恢复的另一个基本类型的对象进行比较:

$this->assertEquals($mockObject, $realObject);

这会立即失败,因为 $mockObject 和 $realObject 是不同的类型。我可以想象有很多解决方法可以实现相同的目标,但我想尽可能简单。

4

4 回答 4

9

好的,简短的回答似乎是:这是不可能的。PHP 比我更清楚我需要什么类型。

于 2013-05-13T17:07:50.363 回答
4

在 PHP 中,您不能强制转换为特定的类,我什至看不出有任何需要。您可以强制转换为某些本机类型 - string, int, array, object. 但不是特定的类。

如果需要使用基类的某些功能,可以通过parent关键字来实现。

class Some {
  public function execute(){
    echo "I am some" ;
  }
}

class SomeMock extends Some {
  public function execute(){ //Override the function
    parent::execute() ; //Here you can execute parent's functionality and add some more
  }
}

编辑:

instanceof运营商可能会派上用场。比较对象时。例如:

$object = new SomeMock() ;
$status = ($object instanceof Some && $object instanceof SomeMock); //will return true here ;

子类继承非私有属性和方法。

比方说,你有你的功能:

function assertEquals($mockObject, $realObject){
  if ($mockObject instanceof Some && $realObject instanceof Some){
    //Both objects have the same base class - Some
    //That means they must have inherited the functionality and properties of Some class.
  }
}
于 2013-05-09T21:08:35.840 回答
2

您可以使用自定义函数来做到这一点:

private function castParameter(BaseClass $parameters) : DerivedClass {
    return $parameters;
}
于 2018-04-16T19:48:04.963 回答
0

当我需要将派生类转换为其基类时,我确实遇到过用例。我做了以下。

function castToParentClass($derivedClassInstance) {
    $parentClassName = get_parent_class($derivedClassInstance);

    $parentClassInstance = new $parentClassName();
    foreach ($parentClassInstance as $key => $value) {
        $parentClassInstance->{$key} = $derivedClassInstance->{$key};
    }

    return $parentClassInstance;
}
于 2018-05-19T13:38:29.403 回答