从父级移除特征 Class
Remove Trait from Parent Class
场景如下
我有一个登录特征...
trait LoginTrait {
public function login() {
// some login code here
}
public function someOtherFunction() {
// some elite code here
}
}
我有一个基本(父)控制器...
class BaseUserController {
use LoginTrait;
}
我有另一个特点,我正在覆盖登录功能...
trait MyLoginTrait {
use LoginTrait {
Traits\LoginTrait::login as oldLogin;
}
public function login() {
// some new elite login code
}
}
我有一个扩展 BaseUsersController 的控制器...
class UsersController extends BaseUserController {
use MyLoginTrait;
}
我的问题是,如何从 BaseUserController 中删除 LoginTrait?
现在,我正在尝试登录,LoginTrait 的登录功能正在启动,而不是具有新登录功能的 MyLoginTrait...
这可能对您有所帮助
<?php
trait LoginTrait
{
public function login()
{
echo 'in LoginTrait::login()' . '<br />';
// some login code here
}
public function someOtherFunction()
{
// some elite code here
}
}
trait MyLoginTrait
{
public function login()
{
echo 'in MyLoginTrait::login()' . '<br />';
// some new elite login code
}
}
class BaseUserController
{
use LoginTrait;
}
class UsersController extends BaseUserController
{
use LoginTrait, MyLoginTrait {
MyLoginTrait::login as myLogin;
LoginTrait::login insteadof MyLoginTrait;
}
}
$user = new UsersController();
$user->login();// output: in LoginTrait::login()
$user->myLogin();// output: in MyLoginTrait::login()
或使用:
class UsersController extends BaseUserController
{
use LoginTrait, MyLoginTrait {
MyLoginTrait::login insteadof LoginTrait;
}
}
$user = new UsersController();
$user->login(); // output: in MyLoginTrait::login()
很可能您的问题出在其他地方。用其他特征覆盖继承的特征应该是这样的:
<?php
trait A
{
public function doIt()
{
echo "DoIt from A." . PHP_EOL;
}
}
trait B
{
public function doIt()
{
echo "DoIt from B." . PHP_EOL;
}
}
class X
{
use A;
}
class Y extends X
{
use B;
}
$foo = new Y();
$foo->doIt();
输出(PHP 7.2):
DoIt from B.
您甚至可以使用 parent::doIt();
和 B::doIt
来调用相同的特征方法 A
- 而不必 "rename" 使用 as
覆盖的方法.
直接回答您的问题:您不能"remove" super class 的特征-您必须使用继承的方法,但可以覆盖它。备选方案:更改您的继承层次结构。
场景如下
我有一个登录特征...
trait LoginTrait {
public function login() {
// some login code here
}
public function someOtherFunction() {
// some elite code here
}
}
我有一个基本(父)控制器...
class BaseUserController {
use LoginTrait;
}
我有另一个特点,我正在覆盖登录功能...
trait MyLoginTrait {
use LoginTrait {
Traits\LoginTrait::login as oldLogin;
}
public function login() {
// some new elite login code
}
}
我有一个扩展 BaseUsersController 的控制器...
class UsersController extends BaseUserController {
use MyLoginTrait;
}
我的问题是,如何从 BaseUserController 中删除 LoginTrait?
现在,我正在尝试登录,LoginTrait 的登录功能正在启动,而不是具有新登录功能的 MyLoginTrait...
这可能对您有所帮助
<?php
trait LoginTrait
{
public function login()
{
echo 'in LoginTrait::login()' . '<br />';
// some login code here
}
public function someOtherFunction()
{
// some elite code here
}
}
trait MyLoginTrait
{
public function login()
{
echo 'in MyLoginTrait::login()' . '<br />';
// some new elite login code
}
}
class BaseUserController
{
use LoginTrait;
}
class UsersController extends BaseUserController
{
use LoginTrait, MyLoginTrait {
MyLoginTrait::login as myLogin;
LoginTrait::login insteadof MyLoginTrait;
}
}
$user = new UsersController();
$user->login();// output: in LoginTrait::login()
$user->myLogin();// output: in MyLoginTrait::login()
或使用:
class UsersController extends BaseUserController
{
use LoginTrait, MyLoginTrait {
MyLoginTrait::login insteadof LoginTrait;
}
}
$user = new UsersController();
$user->login(); // output: in MyLoginTrait::login()
很可能您的问题出在其他地方。用其他特征覆盖继承的特征应该是这样的:
<?php
trait A
{
public function doIt()
{
echo "DoIt from A." . PHP_EOL;
}
}
trait B
{
public function doIt()
{
echo "DoIt from B." . PHP_EOL;
}
}
class X
{
use A;
}
class Y extends X
{
use B;
}
$foo = new Y();
$foo->doIt();
输出(PHP 7.2):
DoIt from B.
您甚至可以使用 parent::doIt();
和 B::doIt
来调用相同的特征方法 A
- 而不必 "rename" 使用 as
覆盖的方法.
直接回答您的问题:您不能"remove" super class 的特征-您必须使用继承的方法,但可以覆盖它。备选方案:更改您的继承层次结构。