阅读this question后 我的问题的一个想法是在子类中实现该方法,如:
class Child {
private $childField = "Want to see";
public $pubChildField = "Will see";
public function method()
{
$assoc = []; // a associative array
foreach ($this as $field => $value) {
$assoc[$field] = doStuff($value);
}
return $assoc;
}
}
var_dump((new Child())->jsonSerialize());
但是为此,我必须在每个子类中复制代码。为了便于阅读,我想将其重构为(已存在的)parentClass
,类似于:
abstract class parentClass {
public function method()
{
$assoc = []; // a associative array
foreach ($this as $field => $value) {
$assoc[$field] = doStuff($value);
}
return $assoc;
}
}
class Child extends parentClass {
private $childField;
public $pubChildField;
}
var_dump((new Child())->jsonSerialize());
foreach ($this as $k=>$v)
和get_object_vars()
都会从实例中获取公共字段。我需要获取它的私有字段,用于序列化。
<小时/> 编辑1:错字抽象方法 - 我在想什么
编辑2:澄清了示例
编辑3:重新提出问题,因为似乎存在误解
答案 0 :(得分:1)
抽象类是关于抽象方法,而不是继承。我假设这些 与问题无关(否则使其成为普通的默认/基类)。
private
限制了具体课程的可见性 - 使用protected
代替。
在我看来,您只需要代码重用。你可以在这个casse中找到特征 - 特征成为一个类的一部分,你可以迭代私有字段。
interface ArrayData {
public function toArray(): array;
}
trait ToArray {
public function toArray(): array {
$assoc = []; // a associative array
foreach ($this as $field => $value) {
$assoc[$field] = $value;
}
return $assoc;
}
}
class Foo implements ArrayData {
use ToArray;
private $childField = "Want to see";
public $pubChildField = "Will see";
}
$foo = new Foo();
var_dump($foo->toArray());
答案 1 :(得分:0)
正确的解决方案是将基类implements
声明为JsonSerializable
接口,并在所有子类中实现JsonSerializable::jsonSerialize()
方法。
您可以在基类中使其未实现以强制所有子类实现它,或者您可以在基类中为不需要序列化的子类提供默认实现(return array();
)。
每个类中的实现不应迭代对象属性列表。通常,并非所有对象属性都必须序列化,并且可序列化属性不等同。
abstract class parentClass implements JsonSerializable {
// You can remove this default implementation
// to force all children class implement the method
public function jsonSerialize()
{
return array();
}
}
class childClass extends parentClass {
private $childField;
public $pubChildField;
public function jsonSerialize()
{
return array(
'field1' => $this->childField,
'field2' => base64_encode($pubChildField),
// etc ...
);
}
}
var_dump((new Child())->jsonSerialize());
尝试编写更易于阅读和理解的代码。你以后会感谢自己。