本文翻译自:How to override trait function and call it from the overridden function?

Scenario: 场景:

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

This code doesn't work, and I cannot find a way to call a trait function like it was inherited. 这段代码不起作用,我找不到像继承那样调用特征函数的方法。 I tried calling self::calc($v) , static::calc($v) , parent::calc($v) , A::calc($v) and the following: 我尝试调用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);}
}

Nothing works. 什么都行不通。

Is there a way to make it work or must I override completely the trait function which is much more complex than this :) 有没有办法使它工作或必须完全覆盖比这复杂得多的特征函数:)


#1楼

参考:https://stackoom.com/question/o5vC/如何覆盖trait函数并从重写函数调用它


#2楼

Your last one was almost there: 你的最后一个几乎就在那里:

trait A {function calc($v) {return $v+1;}
}class MyClass {use A {calc as protected traitcalc;}function calc($v) {$v++;return $this->traitcalc($v);}
}

The trait is not a class. 特质不是一个阶级。 You can't access its members directly. 您无法直接访问其成员。 It's basically just automated copy and paste... 它基本上只是自动复制和粘贴......


#3楼

If the class implements the method directly, it will not use the traits version. 如果类直接实现该方法,则不会使用traits版本。 Perhaps what you are thinking of is: 也许你在想的是:

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 4print (new MyTraitChildClass())->calc(2); // will print 3

Because the child classes do not implement the method directly, they will first use that of the trait if there otherwise use that of the parent class. 因为子类没有直接实现该方法,所以如果否则使用父类的那些,它们将首先使用该特征。

If you want, the trait can use method in the parent class (assuming you know the method would be there) eg 如果你愿意,trait可以在父类中使用方法(假设你知道方法会在那里),例如

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)

You can also provide for ways to override, but still access the trait method as follows: 您还可以提供覆盖的方法,但仍然可以按如下方式访问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

You can see it work at http://sandbox.onlinephpfunctions.com/code/e53f6e8f9834aea5e038aec4766ac7e1c19cc2b5 您可以在http://sandbox.onlinephpfunctions.com/code/e53f6e8f9834aea5e038aec4766ac7e1c19cc2b5上看到它的工作原理


#4楼

An alternative approach if interested - with an extra intermediate class to use the normal OOO way. 如果感兴趣的另一种方法 - 使用额外的中间类来使用普通的OOO方式。 This simplifies the usage with parent::methodname 这简化了parent :: methodname的用法

trait A {function calc($v) {return $v+1;}
}// an intermediate class that just uses the trait
class IntClass {use A;
}// an extended class from IntClass
class MyClass extends IntClass {function calc($v) {$v++;return parent::calc($v);}
}

#5楼

Using another trait: 使用另一个特征:

trait ATrait {function calc($v) {return $v+1;}
}class A {use ATrait;
}trait BTrait {function calc($v) {$v++;return parent::calc($v);}
}class B extends A {use BTrait;
}print (new B())->calc(2); // should print 4

如何覆盖trait函数并从重写函数调用它?相关推荐

  1. R语言常用基础函数:使用edit函数调用数据编辑器手动自定义编辑数据对象不改变原始数据对象内容、使用fix函数调用数据编辑器手动自定义编辑数据对象并直接覆盖原数据内容

    R语言常用基础函数:使用edit函数调用数据编辑器手动自定义编辑数据对象不改变原始数据对象内容.使用fix函数调用数据编辑器手动自定义编辑数据对象并直接覆盖原数据内容 目录

  2. 初识C++之函数重载、重写、重定义的区别

    在C++的学习中,慢慢接触了一些很容易混淆的名词,今天就来剖析几个容易混淆的名词. 1.函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同 ...

  3. C++函数重载和重写

    目录 函数重载 函数重写 函数重载 作用:函数名可以相同,提高复用性 函数重载条件: 1.同一个作用域下 2.函数名称相同 3.函数参数类型不同或者个数不同或者顺序不同 注意事项: 1.引用作为函数重 ...

  4. Windows PE导出表编程3(暴力覆盖导出函数)

    今天要尝试的导出表相关编程内容是:覆盖函数地址部分的指令代码. 这种覆盖技术,是将AddressOfFunctions指向的地址空间指令字节码实施覆盖,这种技术又繁衍出两种: 暴力覆盖,即将所有的代码 ...

  5. python中函数重载和重写

    python 中的重载 在python中,具有重载的思想却没有重载的概念.所以有的人说python这么语言并不支持函数重载,有的人说python具有重载功能.实际上python编程中具有重载的目的缺无 ...

  6. 使用函数指针实现父类函数调用子类函数的两种方式

    父子类关系 对于继承关系中的父类和子类,我们可以说子类是父类的一种,子类继承了父类的属性和行为.因此,子类可以访问父类的所有非私有成员.相反,父类一般情况下是不能访问子类成员的.然而,我们可以通过一些 ...

  7. 一文读懂C#中的抽象类、抽象方法、virtual虚函数、override重写函数及父类子类构造函数和析构函数的执行顺序

    // 父类 class People {public People(){Console.WriteLine("执行People构造函数!");}public virtual voi ...

  8. python函数的返回值是返回引用吗_python-函数(上):函数返回值、函数调用、前向引用...

    编程方法: 1.面向对象:类--class 2.面向过程:过程--def 3.函数式编程:函数--def #python中函数#函数的定义#打印一个佛祖镇楼 -> 一个功能点的解释 defpri ...

  9. mysql 如何调用函数结果_MySQL自定义函数调用不出结果

    自定义函数的代码: DROP FUNCTION IF EXISTS fn_HrStaffBase_GetNameFromidCard delimiter // CREATE FUNCTION fn_H ...

最新文章

  1. Mysql主主复制架构配置
  2. docker-compose部署常用服务
  3. SVN或其他网盘类软件同步图标不显示的异常
  4. MongoDB BI Connector 实战指南
  5. multipart/form-data
  6. (四)Java中的多线程之间实现同步+多线程并发同步
  7. pycharm怎么安装python3.6_【python】Mac在Pycharm中导入python3.6(简单易行)
  8. 新式类与经典类的比较
  9. 源码编译 Qt 6.2
  10. 锐浪报表 Grid++Report uniGUI Web表格打印
  11. NBIOT BC26 opencpu物联网应用案例详细解析
  12. 最新爱云发卡系统源码公益版
  13. 道可道,非常道 ---8个做事之“理”
  14. 玩纸牌游戏计算机教案,小班数学活动好玩的扑克牌教案
  15. 国内外IP黑名单查询网站和邮件相关DNS的查询大全
  16. OpenCL编程之二
  17. Android应用离线中文语音识别PocketSphinx (免费哦~)
  18. 2019应届生平均月薪6000左右!
  19. 2020中国大学生喜爱雇主榜单揭晓;宜家中国携手新裤子乐队发布合作单曲 | 美通企业日报...
  20. ReactJS教程导航

热门文章

  1. Webview--如何让加载进来的页面自适应手机屏幕分辨率居中显示
  2. 追根究底之追本溯源:光标
  3. Spark-Java算子
  4. Spark技术栈有哪些组件,每个组件都有什么功能,适合什么应用场景?
  5. java 包含汉字,【转载】Java判断字符串中是不是包含汉字
  6. mac 配置apache 服务器 实现手机pc 端局域网传输
  7. TCP listen()函数内幕
  8. CVE-2010-3333
  9. 使用MUI/html5plus集成微信支付需要注意的几点问题
  10. Java学习笔记之[ 利用扫描仪Scanner进行数据输入 ]