当前位置: 首页 > 知识库问答 >
问题:

如何重写trait函数并从被重写的函数调用它?

阎唯
2023-03-14

场景:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A;

    function calc($v) {
        $v++;
        return A::calc($v);
    }
}

print (new MyClass())->calc(2); // should print 4

这段代码不起作用,而且我找不到一种方法来调用一个像继承的那样的特性函数。我尝试调用self::calc($V)static::calc($V)parent::calc($V)A::calc($V)以及以下命令:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as traitcalc;
    }

    function calc($v) {
        $v++;
        return traitcalc($v);
    }
}

什么都不起作用。

是否有方法使其工作,或者我必须完全重写比这复杂得多的trait函数:)

共有2个答案

徐安康
2023-03-14

如果类直接实现方法,它将不会使用traits版本。也许你想到的是:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    function calc($v) {
        return $v+2;
    }
}

class MyChildClass extends MyClass{
}

class MyTraitChildClass extends MyClass{
    use A;
}

print (new MyChildClass())->calc(2); // will print 4

print (new MyTraitChildClass())->calc(2); // will print 3

因为子类不直接实现该方法,所以它们将首先使用该特征的方法,如果另外使用父类的方法。

如果需要,该特征可以在父类中使用method(假设您知道该方法会在那里)。

trait A {
    function calc($v) {
        return parent::calc($v*3);
    }
}
// .... other code from above
print (new MyTraitChildClass())->calc(2); // will print 8 (2*3 + 2)

您还可以提供重写的方法,但仍然可以访问trait方法,如下所示:

trait A {
    function trait_calc($v) {
        return $v*3;
    }
}

class MyClass {
    function calc($v) {
        return $v+2;
    }
}


class MyTraitChildClass extends MyClass{
    use A {
      A::trait_calc as calc;
    }
}


class MySecondTraitChildClass extends MyClass{
    use A {
      A::trait_calc as calc;
    }

    public function calc($v) {
      return $this->trait_calc($v)+.5;
    }
}


print (new MyTraitChildClass())->calc(2); // will print 6
echo "\n";
print (new MySecondTraitChildClass())->calc(2); // will print 6.5

您可以在http://sandbox.onlinephpfunctions.com/code/e53f6e8f9834aea5e038aec4766ac7e1c19cc2b5上查看它的工作情况

帅令雪
2023-03-14

你的最后一个就快到了:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as protected traitcalc;
    }

    function calc($v) {
        $v++;
        return $this->traitcalc($v);
    }
}

特质不是一个类。您不能直接访问其成员。基本上就是自动复制粘贴而已...

 类似资料:
  • 我有一个扩展类,在这里我扩展了,如下所示,它工作得很好。 但是现在,我需要为某个视图控制器更改它的标题,所以我想过它的重写,但是失败了。如何可以重写它,以便我可以更改它的?

  • 问题内容: 覆盖和过载之间有什么区别? 问题答案: 重载:在编译时根据指定参数的数量和类型选择方法 签名 覆盖:在执行时根据目标对象的实际类型(与表达式的编译时类型相对)选择方法 实现 例如: 这两个调用都是 重载的 示例。有两种方法,称为,编译器确定要调用的签名。 第一次调用是 覆盖 的示例。编译器选择签名“ foo(int)”,但是在执行时,目标对象的类型确定要使用的实现应为in中的一个。

  • 问题内容: 我正在寻找此代码将输出: 但是我得到了: 我了解在B的上下文中,A.f1(String)中的“ this”是B的实例。我是否可以选择执行新的链B1()。f1(String)->(A’s)f1(String)->(A’s)f1(int,String)? 这是一个理论问题,实际上,解决方案显然是在A中实现f1(String)和f1(int,String)都将调用的私有函数。 谢谢你, 马克

  • 我尝试在我的项目中使用主干。但我在尝试跳过主干的解析方法时遇到了问题。服务器发回的数据超出了我的需要。例如:我想要的是: 但服务器的结果是: 所以我希望在parse方法中得到处理结果,并只返回数组。我该怎么做?当我尝试时,我犯了错误。我该怎么办?

  • 我有一个hazelcast IMap,我已经重写了load、store等其他函数,这样备份也可以在MongoDB数据库中进行。因此,当hazelcast IMap增加时,MongoDB中也有相应的备份。但是如何重写replace函数呢?我希望每当hazelcast地图的现有条目有更新时,相应的MongoDB文档也应该有更新。 编辑:这是我的store方法的代码 当我从地图中获取一个对象时,它有mo

  • 问题内容: 当我探索问题的解决方案Python Use User Defined String Class时 ,我遇到了这种奇怪的python行为。 输出: 覆盖过去! 现在,如何才能恢复python解释器中的原始行为? 问题答案: 只需删除覆盖: 这将从字典中删除该名称,从而使搜索回落到内置函数。 您也始终可以通过模块直接引用内置函数: 在Python 3中,该模块已重命名为。