什么是 parent:: trait 的作用域
What is parent:: scope for a trait
我有一个使用特征 MyTrait 的 class MyClass。它们都有一个方法 getName()(MyClass 继承自 MyParentClass)。
MyTrait::getName() 的父作用域是什么?在 MyTrait 上下文中调用 MyClass::getName() 和 MyParentClass::getName() 的正确方法是什么?
参考下面的代码。
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyParentClass {
public function getName(): string
{
return "MyName";
}
}
class MyClass extends MyParentClass {
use MyTrait;
}
特征方法的行为就像它们在 class 中使用特征声明,即
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyClass extends MyParentClass {
use MyTrait;
}
在功能上与
相同
class MyClass extends MyParentClass {
public function getName() : string
{
return parent::getName() . '_special';
}
}
应该清楚,在这种情况下parent
指的是MyParentClass
。如果有任何疑问,请使用以下代码:
<?php
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyParentClass {
public function getName(): string
{
return "MyName";
}
}
class MyClass extends MyParentClass {
use MyTrait;
}
$instance = new MyClass();
echo $instance->getName();
产生以下输出:
MyName_special
这可以进一步 tested/demonstrated 在 trait 方法中使用 return parent::class;
(ref),其中 returns MyParentClass
.
您需要在子类中定义一个 getName()
方法。根据 manual,traits 的先例是:
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.
这意味着因为您的子类中没有 getName()
方法,所以 trait 方法优先,覆盖父方法。在子类中有一个getName()
方法,它优先。
因此您需要执行以下操作,请注意特征用法中 getName()
方法的别名:
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyParentClass {
public function getName(): string
{
return "MyName";
}
}
class MyClass extends MyParentClass {
use MyTrait {
MyTrait::getName as getTraitName;
}
public function getName(): string
{
return parent::getName();
}
}
$myClass = new MyClass();
var_dump($myClass->getName()); //string(6) "MyName"
var_dump($myClass->getTraitName()); //string(14) "MyName_special"
我有一个使用特征 MyTrait 的 class MyClass。它们都有一个方法 getName()(MyClass 继承自 MyParentClass)。
MyTrait::getName() 的父作用域是什么?在 MyTrait 上下文中调用 MyClass::getName() 和 MyParentClass::getName() 的正确方法是什么?
参考下面的代码。
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyParentClass {
public function getName(): string
{
return "MyName";
}
}
class MyClass extends MyParentClass {
use MyTrait;
}
特征方法的行为就像它们在 class 中使用特征声明,即
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyClass extends MyParentClass {
use MyTrait;
}
在功能上与
相同class MyClass extends MyParentClass {
public function getName() : string
{
return parent::getName() . '_special';
}
}
应该清楚,在这种情况下parent
指的是MyParentClass
。如果有任何疑问,请使用以下代码:
<?php
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyParentClass {
public function getName(): string
{
return "MyName";
}
}
class MyClass extends MyParentClass {
use MyTrait;
}
$instance = new MyClass();
echo $instance->getName();
产生以下输出:
MyName_special
这可以进一步 tested/demonstrated 在 trait 方法中使用 return parent::class;
(ref),其中 returns MyParentClass
.
您需要在子类中定义一个 getName()
方法。根据 manual,traits 的先例是:
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.
这意味着因为您的子类中没有 getName()
方法,所以 trait 方法优先,覆盖父方法。在子类中有一个getName()
方法,它优先。
因此您需要执行以下操作,请注意特征用法中 getName()
方法的别名:
trait MyTrait {
public function getName() : string
{
return parent::getName() . '_special';
}
}
class MyParentClass {
public function getName(): string
{
return "MyName";
}
}
class MyClass extends MyParentClass {
use MyTrait {
MyTrait::getName as getTraitName;
}
public function getName(): string
{
return parent::getName();
}
}
$myClass = new MyClass();
var_dump($myClass->getName()); //string(6) "MyName"
var_dump($myClass->getTraitName()); //string(14) "MyName_special"