75142913在线留言
【PHP进阶】向面向对象中的高级概念总结_PHP技术_网络人

【PHP进阶】向面向对象中的高级概念总结

Kwok 发表于:2022-06-29 12:29:33 点击:147 评论: 0

在以前的文章里针对PHP面向对象有过基本知识的说明:http://www.55mx.com/post/193 ,本文将针对在实际开发中会使用到的面向对象高级功能的一些概念总结说明:

PHP进阶向面向对象中的高级概念总结

一、类的继承

PHP作为从面向过程半路出家到面向对象的语言(依然可以面向过程)。在和其它语言相比有很多不同的地方,PHP不支持同时继承多个类,只能一层一层的链式继承。我们也可以通过trait 方式来弥补这个缺点。

1、基本继承(单一继承)

通常情况下,我们都是在父类定义一些子类会使用到的方法,然后让子类去extends继承本类。比如:我们写api时,可以定义一个基本的控制器类,里面定义了要返回的数据 data,状态码,成功消息、失败消息等。这些公共属性与方法后。让子类去继承使用。

在这个过程中,我们需要学习下面的知识点:

a. 父类的所有属性(包括私有属性)都可以被继承。

b.父类的定义为protected的主要目的就是为了让子类去继承。

c.通过parent关键字执行重写方法里的父类方法。

d.self:: 访问方法/属性时是编译就定死了的,所以称为静态绑定。

e.static:: 访问方法/属性时是谁new就绑定给谁,所以称为动态绑定(一般配合重新方法时使用)。

f.使用final修饰后,将不能被继承,可以防止被破坏。

2、链式继承(多个继承)

PHP不支持同时继承多个类,所以我们需要一层一层的继承下去。路径为:生物->动物->人类->男人->行走方法、生物->动物->大象->行走。这样的层级在维护和开发时会产生严重的耦合性。也会影响执行效率,所以我们开发中应该避免太多的链式继承。更好的方法是使用下面的trait 方式。

3、trait 高级继承(多个继承)

trait 主要就是解决PHP不能同时继承多个类的痛点。我们只需要在 类里使用 use trait1,trait2,trait2 ...;方式就可以引用多个trait提供的方法。

trait 是将公共代码抽离出来,存储到trait中,比如:大象可以行走、吃饭、睡觉等特点,男人、女人也都有这些共同特点。这样我就可以将这些共同的特点使用trait规集在一起。并在class里使用use 关键字引用并调用。

trait 其实本质上也还是一个class,区别为 不能使用类常量(const)和直接实例化。和抽象类相同的是,trait只能被继承,不能直接实例化。与抽象类不同的是,trait 可以实再方式。而抽象类只能定义方法。

trait 是一个介于 类与抽象类 之间的东西。既可以定义抽象方法。也可以定义类方法与类属性。最重要的还是,我们可以在子类里同时继承多个trait。

在子类里使用trait类似于面向过程中的Incloud把trait里的代码引用进来。一个子类可以使用多个trait(执行多个incloud),但是要注意同名问题。方法可以使用insteadof替换或者as取个别名(不处理则会被后引入的trait里的方法所替代掉,类似重写了)。属性则不能同名(除非同名同值)。

trait的特点总结:

a、因为不能被实例化,所以不能包括类常量;

b、trait里可以定义抽象方法。也可以定义类方法。

c、在子类里可以同时继承多个trait。

d、trait 主要用于解决有公共需求,但不属于同一类型的代码复用问题(汽车可以有发动机、轮船、火箭、飞机都可以有)。

e、使用insteadof 替代trait以解决方法同名的问题。

f、使用 as 对trait用别名以解决替代同名的问题(相当于复制了一个别名方法)。

g、既然as 是复制了一份别名方法,我们也可以通过public private等修改其权限。

h、同名时use的优先级高于extends关键字。但子类里的同名方法优级级最高(重写了)

i、trait在引入过程中有可能参与到类的继承中去。如果没有处理同名方法,就会就覆盖(重写),可以使用parent 关键字访问父级方法。

二、开发规范

 1、抽象类 abstract

 抽象类abstract 是为了规范开发的。我们定义了抽象类。就需要被继承的子类实现里面的方法。

抽象类可以继承父级的抽象类。但不能被直接实例化使用。因为抽象类里的方法不需要写实现。

子类class继承了抽象类后。必须实现里面的抽象方法。

子类使用extends来继承抽象类。

抽象类里可以实现里面的普通方法。当子类继承后可以使用已实际的普通方法,并且必须实现里面的抽象方法。

2、接口

接口用于大型构架的开发。专门用来规范一些共性类必须实现的方法(命名规范为主)。 

接口不是类。但是与类有类似的结构(接口不能有属性)。

接口成员中只能定义公有抽象方法和接口常量。

接口不能实例化,需要被类实现。

class使用implements 关键字来实现接口。

class类实现接口的成员时,不允许重写接口中的常量的。也不允许增加接口方法的控制权限(只能public)。

接口是一个与类相似的结构,目的是为了规范一些类的必要行为的。一般用于大型项目的开发。所以接口会使得项目的开发变得不那么的灵活。我们需要根据实际情况选择是否使用接口。

接口会很好的规范团队的协作能力。小团队、小项目开发,基本上没有必要使用到接口。

接口可以多继承,一个接口可以同时继承多个接口(用逗号隔开)

3、总结

抽象类与接口有着很明显的区别,而我们在开发过程中又容易将其搞混淆。所以下面我列出来他们的共同点与不同点以供参数。

共同点:

  • 用于规范开发。
  • 不能被直接实例化。
  • 提供一些行为规范(方法、属性)
  • 接口与抽象类里都可以有抽象方法。
  • 接口可以继承接口,抽象类也可以继承抽象类。

不同点:

  • 抽象类是继承 extends ,接口则是需要实现 implements。关键字不同。
  • 实现接口必须实现里面所有的方法(接口里没有普通方法)。
  • 继承抽象类可以使用里已实现的普通方法。接口只有抽象方法。
  • 接口里不能定义属性。
  • 接口里的所有方法必须为public权限。
  • 接口里只有抽象方法。不能有普通方法,且不需要使用abstract修饰方法。
  • 抽象类可以实现接口。反之不可以。

三、重载 Overload 

在强类型语言中,我们可以在class里定义同名的方法(需要不同的参数),当我们调用时,会根据参数来判断应该调用那个方法。

而PHP是弱类型语言,根本 不支持传统意义上的重载,在php里的重载是为了容错处理。当调用了不存在的属性、方法时。自动触发一个魔术变量来处理这个请求。

1、属性重载魔术方法

  • __get(属性名):访问不存在或者权限不够的属性时触发
  • __set(属性名,属性值):设置不存在或者权限不够的属性时触发
  • __isset(属性名):判定不存在或者权限不够的属性时触发
  • __unset(属性名):删除不存在或者权限不够的厲性时触发
  • __toString(): 输出对象时触发

2、方法重魔术方法

  • __call(方法名,方法参数列表):调用不存在或者权限不够的方法时触发。
  • __callStatic(方法名,方法参数列表):调用不存在或者权限不够的静态方法时触发。

 

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/232
标签:php进阶面向对象Kwok最后编辑于:2022-06-29 16:29:43
0
感谢打赏!

《【PHP进阶】向面向对象中的高级概念总结》的网友评论(0)

本站推荐阅读

热门点击文章