PHP具有称为 late static bindings 的功能,其中static
关键字在运行时解析,并且引用当前正在执行代码的类。考虑以下PHP代码:
class Collection
{
protected $items;
public function __construct(array $items = [])
{
$this->items = $items;
}
public function map(Closure $closure)
{
return new static(array_map($closure, $this->items));
}
}
class CatCollection extends Collection {}
如果我们要创建Collection
的实例,则可以调用其map
方法,这将返回Collection
的实例。同样,我们可以创建CatCollection
的实例并调用其map
方法,这将产生一个CatCollection
的新实例(而不是Collection
)。
$collection = new Collection([1, 2, 3]);
$doubled = $collection->map(function ($item) {
return $item * 2;
}); // Returns an instance of Collection containing items 2, 4, 6.
$cats = new CatCollection(['Keyboard', 'Grumpy']);
$titled = $cats->map(function ($cat) {
return 'Mr. ' . $cat;
}); // Returns an instance of CatCollection containing items 'Mr. Keyboard', 'Mr. Grumpy'.
答案 0 :(得分:0)
您可以使用一些通用的傻瓜来做类似的事情...
(在下面; E
是MyCollection
的 elements 的类型,而C
是 extension MyCollection个)。
abstract class MyCollection<E, C extends MyCollection<E, C>> {
private final List<E> elements;
MyCollection(final List<E> elements) {
this.elements = new ArrayList<>(elements);
}
C map(final UnaryOperator<E> mapper) {
final List<E> mappedElements = new ArrayList<>(this.elements.size());
for (final E element : this.elements) {
mappedElements.add(mapper.apply(element));
}
return this.create(mappedElements);
}
abstract C create(final List<E> mappedElements);
}
class SubCollection<E> extends MyCollection<E, SubCollection<E>> {
SubCollection(final List<E> elements) {
super(elements);
}
@Override
SubCollection<E> create(final List<E> mappedElements) {
return new SubCollection<>(mappedElements);
}
}
我想不起来我曾经不得不做这种事情的时间...