Trait 同名|学习笔记

简介: 快速学习 Trait 同名,本节课学习 trait 同名问题。如果有不同的 trait 来解决不同的公共代码。解决完之后会引入两个或多个 trait。这时 trait 里面就会出现同名的问题。例如:同名的方法、同名的属性。这时应该怎么办呢?就用到这节课学习的内容。本节课的目标是掌握trait同名的处理逻辑,应该在什么样的情况下选择什么样的处理方式。

开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第二阶段: Trait 同名】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/712/detail/12702


Trait 同名


主要内容

一、概念

二、步骤

三、示例

四、小结


一、概念

trait 同名是指一个类中可能引入多个 trait,而不同 trait 中可能出现同名。

1.trait 同名分为两类:

(1)属性同名:不允许出现同名属性,不管是多个 trait 还是类内部出现同名属性(trait 之间还是 trait 与类之间的同名属性)除非同名同值(就是一个属性,就不存在多个属性的情况。)

(2)方法同名:有两种对应的解决方案。

①不允许同名出现,但是已经出现可以使用替代方法,确定要用哪一个然后把一个作为主要的然后去替换另一个,那就意味在类里面使用时都只会用到其中一个。

语法:

Use trait 名1、trait 名2...{

trait 名1::方法名 insteadof(替换) trait 名2;

}

发现在使用整个 trait 类里面,只能用 trait1 的对应名,而 trait2 永远用不到,因为已经 trait1 替换掉了 trait2。

②不允许同名出现,如果出现了两个都要用,就使用别名,让两个都可以使用(使用别名前需要知道谁先代替谁,对被代替的使用别名)上面的只确定用一个,而下面的两个都可以用。

语法类似:将 trait2 的文件名替代 trait1 的文件名,就说明 trait1 的没有用了。将trait1as 一个别名之后会出现:trait1 方法可用,但是名字不可用。(别名使用)

图片1.png

以上是同名的处理;属性不能同名,除非同名同值;方法可以同名但是解决方案分为两类,一个是只用一个,一个是两个都要用(用别名)。


二、具体步骤:

1、定义多个 trait,里面存着同名方法。

2、在某个类中引入多个 trait(引入之后立马会报错,因为产生冲突了)

3、同名冲突后

(1)明确要用哪一个,insteadof 替换

(2)需要两个都用,使用别名临时修改同名中的一个。(不会改变原来 trait 中的名字,只是在类里面换了名字)


三、示例

1、trait 属性必须同名同值,否则报错

T1 里面有一个 public name的true,T2 里面也有 public name 叫 true。但是T1里面age=0,T2 里面 age=1,这就代表同名不同值。而 name 是同名同值的。

在一个类里面出现了同名问题,会出现的情况:

图片2.png

将上图的代码复制:

09trait-same

trait 同名成员问题

理论上没有这个的时候,是不会报错的。因为此时这两个同名是没有关系的,只要外面不同名就可以了。因为没有放在一起,所以不存在同名的问题。但是如果两个放在一起,就会出现问题。相当于将四行代码放在类里面,第一覆盖第二个 name都无所谓。但是第二个覆盖第一个是不可以的。

图片3.png

当再次测试的时候,就会出现 T2 define the sameproperty(age)只说了 age,但是在这里面不允许存在不同,因为系统不知道怎么区分。此时就需要用到别名来解。属性没有别名也没有替换的概念,所以就只能让它不存在。不允许同名出现,要换一个出现。例如可以将 age 改为 old,这样才能解决对应的问题。

以上是属性的问题,接下来为方法。方法如果又时也会出现冲突。将方法放进去,第一个方法是 eat。第二个方法也叫 eat,但是里面实现的业务是不一样的。此时的 Hume 不是对应上面的两个方法去的,或者是对其中一个方法的。但是另外的东西在上面还存在,用到了一个东西,这个只是其中的一部分,而这一部分恰恰影响了代码的整体性,因为显示已经存在了同样的问题。

图片4.png

所以系统解决不了同名的问题,需要使用别名。

(1)#trait 同名元素:替换使用其中一个

用到 insteadof 语法,需要用到 T2 的,因此直接 T2::eat insteadof T1 即可。

图片5.png

Use t2 t1{}

t2::eat insteadof t1

刷新之后发现没问题了。没问题之后自然就可以用了。

$H=new human

$h->eat

刷新后明显发现 t2 的 eat 被触发。因为上面明确指出用了 t2::eat insteadof t1

(2)两个都要使用。使用别名处理;保证两个方法都能使用。但是先要确定用哪一个,然后再去替换另外一个。

用 t1::eat insteadof t2;

T2::eat as show; 改为 show2 或者 show 都可以。

图片6.png

将第一种方案注释掉。

#trait 同名元素:别名保留两个方法。

USEt1,t2{ // 这两个顺序没有关系

t1::eat insteadof t2  #具体使用 t1::eat 方法//这是保留的。

t2::eat as show   #t2::eat 临时改名为 show。

有了以上操作之后,看看代码能否运行。刷新之后发现没有问题,此时访问的是 t1的 eat,但是想要使用另一个方法就只能使用 show 了,已经有别名替代了。发现两个方法都可以用了。

以上就是解决方案,此部分解决完之后如果将 t1 引入的只有一个 trait 但是要给它改别名,也是可以的。

(4)补充:

Class animal{}

Use t1

$a=new animal

$a->eat()

运行之后发现没有问题,但是此时运行的时候是强行别名的。

T1::eat as show

图片7.png

在没有报错的情况下,调用 eat,说明将 eat 改为 show 这个 eat 的方法还在。先调用 show 发现也是可以访问的。

本质逻辑:

trait 别名不会改变原来方法的存在,而是相当于复制了一个别名的方法(相当于定义了一个 show 的方法,但是用的是 eat 方法的内容)前面的代码本质也是如此。只不过规定了 t1 的 eat 比谁都大,外部调用的时候只能使用它,因此会发现 t2 的 eat 并没有消失。只是取了一个别名,多了一个方法而已。以上就是别名使用。


四、小结

1、trait 同名概率出现比较小,但是要警惕出现同名(在写代码的时候不愿意让这个东西出现同名,因为同名之后会影响自己之后的操作。因此代码是自己写的,不会出现同名的问题。上面出现了 eat 下面就换成 person 或者 person animal-eat。下面的方法明显与上面的方法不同名)

2、解决 trait 同名(不能修改上面的代码,因此需要来处理它)

属性同名,除非同值,不然只能改源码。

方法本身可以进行同名处理

只要用到一个替换的方式明确使用其中一个。如果说需要用到两个,让另外一个与当前的不冲突,只是使用别名也需要提前明确使用哪一个。这是 trait 特性。

3、如果出现了同名,需要考虑用什么样的方式来解决。根据业务来支撑。

上述代码出现了很多同名的东西,本身里面:class animal 把 t1::eat as show这时允许自己有一个 eat function。Echo”animal“

自己有自己的 eat 方法,但是与其他又同名了。其他的取别名不影响。第一个调用的 eat 是自己的。

所以别名使用之后优先级就会降低,当然这里涉及到重写的问题,也就是可能会存在同名的情况出现的概率

以上是 trait 出现同名的问题。

相关文章
|
Java Linux 程序员
linux实现定时备份文件到百度网盘详细教程
作为一个程序员,数据备份尤为重要,本文主要介绍的是将服务器上的某文件定时备份到百度网盘中。主要实现思路是:安装pip、byp --> 百度网盘进行授权登陆 --> 使用crontab+bypy实现定时自动数据备份。
1558 0
|
负载均衡 Ubuntu 应用服务中间件
|
网络协议 Unix Linux
服务器实现端口转发的N种方式
服务器实现端口转发的N种方式
1862 0
|
Rust 自然语言处理 安全
【Rust日报】用 Rust 从头实现一个 C 编译器
【6月更文挑战第9天】使用 Rust 实现 C 编译器的挑战性项目,利用 Rust 的内存安全和高性能优势。涉及词法分析、语法分析等步骤,示例代码展示简单的词法分析过程。实际实现需处理更多复杂环节,如抽象语法树构建和代码生成。此项目能深化对编译器原理的理解,提升 Rust 技能,并有望推动更多高质量 Rust 编译器的诞生。
414 7
|
12月前
|
缓存 监控 持续交付
|
存储 缓存 资源调度
Monorepo(单体仓库)与MultiRepo(多仓库): Monorepo 单体仓库开发策略与实践指南
Monorepo(单体仓库)与MultiRepo(多仓库): Monorepo 单体仓库开发策略与实践指南
986 0
|
开发工具
教你如何将WSL系统更换国内源?+固定路径+国内镜像源+详细教程
教你如何将WSL系统更换国内源?+固定路径+国内镜像源+详细教程
16576 2
|
Docker 容器
哪位道友知道 Docker桌面客户端,用的是啥技术栈?
请教Docker for Mac 的客户端 也就是 Docker Desktop 是用什么框架写的?QT?Electron? 还是其他?
513 1
哪位道友知道 Docker桌面客户端,用的是啥技术栈?
|
存储 Kubernetes 安全
Docker 被禁?还有千千万万个 Docker 站起来!!
众所周知,在全球范围内,Docker已经发展成为云计算的核心技术之一。
1746 0
Docker 被禁?还有千千万万个 Docker 站起来!!
vscode插件快餐教程(7) - 从头开始写一个完整的lsp工程
有了一定的基础知识之后,我们就可以开始搭建一个client和server模式的lsp的插件了。
4304 0