继承和多态

类的组合与继承

  • 假设我们有两个类,一个 person,另外一个是 family;在 family 类中我们创建 person 类中的对象,并且我们把这个对象视为 family 类的一个属性,并调用它的方法处理问题,那么这种复用方式也称为组合。
  • 类与类之间还有一种父与子的关系,子类可以继承父类的属性和方法,我们称之为继承。在继承里,子类拥有父类的属性和方法,同时子类也有自己的属性和方法。
<?php
class person{public $name = 'Tom';public $gender;static $money = 10000;public function __construct(){echo '这里是父类',PHP_EOL;}public function say(){echo $this->name,"\t is ",$this->gender,"\r\n";}
}class family extends person{public $name;public $gender;public $age;static $money = 1000;public function __construct(){parent::__construct();echo '这里是子类',PHP_EOL;}public function say(){parent::say();echo $this->name,"\t is \t",$this->gender,",and is \t ",$this->age,PHP_EOL;}public function cry(){echo parent::$money,PHP_EOL;echo '% >_< %',PHP_EOL;echo self::$money,PHP_EOL;echo "(*^_^*)";}
}$poor = new family();
$poor->name = 'Lee';
$poor->gender = 'female';
$poor->age = 25;
$poor->say();
$poor->cry();

返回结果

这里是父类
这里是子类
Lee  is female
Lee  is     female,and is    25
10000
% >_< %
1000
(*^_^*)%
  • 组合和继承都是提高代码可重用行的手段。在设计对象模型时,可以按照语义识别类之间的组合关系和继承关系。

例如:

  • 继承是一种 “是,像” 的关系,组合则是一种 “需要” 的关系 【父亲和儿子应该是继承关系,父亲和家庭应该是组合关系 】
  • 组合偏重与和局部的关系,继承偏重与父与子的关系。
  • 从方法复用的角度考虑,如果两个类具有很多相同的代码和方法,我们就可以从这两个类中抽象出一个父类,提供公共方法,然后两个类作为子类,提供个性方法,这时继承更好。
  • 组合的限制很少,组合之间的类可以关系很小 (体现为复用代码),设置没有关系。

编程中

  • 继承和组合的取舍往往都不是这么直接明了,很难说出二者是 “像” 的关系还是需要的关系。甚至说把它拿到现实世界中建模,更加无法决定是继承还是组合的关系了。这时,它该如何办,有什么标准?这个标准就是:低耦合

低耦合

  • 耦合是一个软件结构内不同模块之间互联程度的度量,也就是不同模块之间的依赖关系。
  • 低耦合是指模块和模块之间,尽可能地使模块间独立存在;模块与模块之间的接口尽量少而简单。现代的面向对象的思想不强调为真实世界建模,变得更加理性化一些,把目标放在解耦上。

解耦

  • 目的是为了解除模块与模块之间的依赖。
  • 继承和组合二者在语义上难以区分,但是我们更倾向于使用组合。
  • 继承存在的问题:
    • 继承破坏封装性;(鸟类为父类,而鸭子和鸵鸟作为子类,它们却拥有飞翔的方法)
    • 继承是紧耦合的,使得子类和父类捆绑在一起。组合仅是通过唯一接口和外部进行通信,耦合度低于继承。
    • 继承扩展复杂,随着继承层数的增加和子类的增加,将涉及大量方法重写。使用组合,可以根据类型约束,实现动态组合,减少代码。
    • 不恰当的使用继承可能违反现实世界中的逻辑;

组合

<?phpclass car{public function addoil(){echo "Add oil \r\n";}
}class bmw extends car{}
class benz{public $car;public function __construct(){$this->car = new car();}public function addoil(){$this->car->addoil();}
}
$bmw = new bmw();
$bmw->addoil();
$benz = new benz();
$benz->addoil();
  • 在创建组合对象时,组合需要一一创建局部对象,这一点程度上增加了一些代码,而继承不需要这一步,继承拥有父类的方法,可以直接使用

如何使用继承:

  • 精心设计专门用于被继承的类,继承树的抽象层应该比较稳定,一般不多于三层;
  • 对于不是专门用于被继承的类,禁止其被继承,也就是使用 final 修饰符。使用 final 修饰符即可防止重要方法被非法覆写,又能给编辑器寻找优化的机会;
  • 优先考了用组合关系提高代码的可重用性;
  • 子类是一直特殊的类型,而不只是父类的一个角色;
  • 子类扩展,而不是覆盖或者使父类的功能失效;
  • 底层代码多用组合,顶层 / 业务层代码多用继承。底层用组合可以提供效率,避免对象臃肿。顶层代码用继承可以提高灵活性,让业务使用更方便。

既要组合的灵活,又要继承的简洁

  • 多重继承,一个类可以同时继承多个父类,组合两个父类的功能;缺点:多重继承过于灵活,并且会带来 “零星问题”,故为其使用带来了不少困难,模型变得复杂起来。
  • traits php5.4 引入的新的语法结构,可以方便我们实现对象的扩展,是除 extend,implements 外的另外一种扩展对象的方式,traits 即可以使单继承模式的语言获得多重继承的灵活,又可以避免多重继承带来的种种问题

traits 的用法

  • 通过在类中使用 use 关键字声明要组合的 Trait 名称,而具体某个 Trait 的声明使用 trait 关键词,Trait 不能直接实例化
<?php
trait Drive {public $carName = 'BMW';
public function driving() {echo "driving {$this->carName}\n";
}
}
class Person {public function age() {echo "i am 18 years old\n";
}
}
class Student extends Person {use Drive;
public function study() {echo "Learn to drive \n";
}
}
$student = new Student();
$student->study();
$student->age();
$student->driving();
Learn to drive
i am 18 years old
driving BMW
  • Student 类通过继承 Person,有了 age 方法,通过组合 Drive,有了 driving 方法和属性 carName。

如果 Trait、基类和本类中都存在某个同名的属性或者方法,最终会保留哪一个呢

<?php
trait Drive {public function hello() {echo "hello 周伯通\n";
}
public function driving() {echo "周伯通不会开车\n";
}
}
class Person {public function hello() {echo "hello 大家好\n";
}
public function driving() {echo "大家都会开车\n";
}
}
class Student extends Person {use Drive;//trait 的方法覆盖了基类Person中的方法,所以Person中的hello 和driving被覆盖
public function hello() {echo "hello 新学员\n";//当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,所以此处hello会覆盖trait中的hello
}
}
$student = new Student();
$student->hello();
$student->driving();
hello 新学员
周伯通不会开车
  • 当方法或属性同名时,当前类中的方法会覆盖 trait 的 方法,而 trait 的方法又覆盖了基类中的方法。

如果要组合多个 Trait,通过逗号分隔 Trait 名称:

use Trait1, Trait2;
<?php
trait Hello {public function sayHello() {echo "Hello 我是周伯通\n";
}
}
trait World {use Hello;
public function sayWorld() {echo "hello world\n";
}
abstract public function getWorld();
public function inc() {static $c = 0;
$c = $c + 1;
echo "$c\n";
}
public static function doSomething() {echo "Doing something\n";
}
}
class HelloWorld {use World;
public function getWorld() {return 'do you get World ?';
}
}
$Obj = new HelloWorld();
$Obj->sayHello();
$Obj->sayWorld();
echo $Obj->getWorld() . "\n";
HelloWorld::doSomething();
$Obj->inc();
$Obj->inc();
Hello 我是周伯通
hello world
do you get World ?
Doing something
1
2

语言中得多态

  • 多态准确的含义是:同一类的对象收到相同消息时,会得到不同的结果。而这个消息是不可预测的。多态:顾名思义,就是多种状态,也就是多种结果
  • 多态性是一种通过多种状态或阶段描述相同对象的编程方式。它真正的意义在于:实际开发中,只要关心一个接口或基类的编程,而不必关心一个对象所属于的具体类

案例

  • 通过判断传入的对象所属的类不同来调用其同名方法来实现 ’ 多态 ’
<?php
class employee{protected function working(){echo '本方法需要重载才能运行';
}
}
class teacher extends employee{public function working(){echo '教书';
}
}
class coder extends employee{public function working(){echo '敲代码';
}
}
function doprint($obj){//get_class 获取当前对象调用的类名
if(get_class($obj)=='employee'){echo 'Error';
}else{$obj->working();
}
}
doprint(new teacher());
doprint(new coder());
doprint(new employee());
  • 通过接口实现多态
<?php
interface employee{public function working();
}
class teacher implements employee{public function working(){echo '教书';
}
}
class coder implements employee{public function working(){echo '敲代码';
}
}
function doprint(employee $i){$i->working();
}
$a=new teacher;
$b=new coder;
doprint($a);
doprint($b);
  • 在这段代码中,doprint 函数的参数为一个接口类型的变量,符合 ’ 同一类型,不同结果 ’ 这一条件,具备多态的一般特征。

总结

  • 多态指同一类对象在运行时的具体化。
  • php 语言是弱类型的,实现多态更简单,更灵活。
  • 类型转换不是多态。
  • php 中父类和子类看作 ’ 继父 ’ 和’ 继子 ’ 关系,他们存在继承关系,但不存在血缘关系,因此子类无法向上转型为父类,从而失去多态最典型的特征。
  • 多态的本质就是 if – else – ,只不过实现的层次不同。

更多学习内容可以访问【对标大厂】精品PHP架构师教程目录大全,只要你能看完保证薪资上升一个台阶(持续更新)

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的PHP技术交流群953224940

进阶PHP月薪30k>>>架构师成长路线【视频、面试文档免费获取】

看完就能掌握的PHP核心技术 - ​​​​​​​​面向对象相关推荐

  1. 一口气看完 45 个寄存器,CPU 核心技术大揭秘

    作者 | 轩辕之风O 来源 | 编程技术宇宙(ID:xuanyuancoding) 头图 |  CSDN 下载自东方IC 序言 前段时间,我连续写了十来篇CPU底层系列技术故事文章,有不少读者私信我让 ...

  2. 一口气看完45个寄存器,CPU核心技术大揭秘

    作者 | 轩辕之风O 来源 | 编程技术宇宙 头图 | CSDN下载自视觉中国 自1946年冯·诺伊曼领导下诞生的世界上第一台通用电子计算机ENIAC至今,计算机技术已经发展了七十多载. 从当初专用于 ...

  3. 2万字看完腾讯最纯粹的一届WE大会:从黑洞、虫洞到克隆猴

    来源:虎嗅APP 腾讯还有梦想,因为腾讯还有WE大会. 5年来,腾讯从全世界邀请了几十位难得一见的科学家不远万里来到北京展览馆,比如去年邀请的剑桥大学教授.著名宇宙学家霍金(视频演讲),不想成为绝唱. ...

  4. 保洁阿姨看完都会了!java图形界面设计代码

    二.解析 1. 硬件层的并发优化基础知识 存储器的层次结构图如下: 各级缓存耗时对比: 采用分层缓存的层次结构会带来数据不一致问题,如下图: 那么如何保证数据的一致性,现代CPU处理办法有两种: (1 ...

  5. Java 知识总结大汇总!看完哪个都变大佬!

    免费编程资源大全项目:https://github.com/liyupi/free-programming-resources 大家好,我是鱼皮,今天分享 十几个 让人直呼 "哇塞" ...

  6. 看完这个故事,你就知道程序员为什么选公司就要去上升期的

    看完这个故事,你就知道程序员为什么选公司就要去上升期的 https://www.toutiao.com/i6948390604984402462/?tt_from=weixin&utm_cam ...

  7. 怎么看电脑有没有蓝牙_怎么选购电脑音响?挑选到性价比高的电脑桌面音箱,看完这篇推荐指南就懂了!...

    现在越来越多人使用电脑了,所以配上一台电脑桌面音箱就很有必要了,工作闲暇的时候可以听听音乐,玩游戏的时候更能开启小音箱助力,这样才能玩的更嗨.那么问题来了,怎么才能选购一款适合自己的电脑音响呢?在挑选 ...

  8. 2022年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多,看完你也可以了

    写在2022年初的蚂蚁.头条.拼多多的面试总结 文章有点长,请耐心看完,绝对有收获!不想听我BB直接进入面试分享: 准备过程 蚂蚁金服面试分享 拼多多面试分享 字节跳动面试分享 总结 说起来开始进行面 ...

  9. 超硬核Java学习路线图+学习资源+实战项目汇总,看完以后不用再问我怎么学Java了!

    之前写过很多次关于Java学习指南.Java技术路线图的文章.但是总还是有小伙伴来问我,Java怎么学,项目怎么做,资源怎么找,真是让人头秃. 于是这次黄小斜决定来一波狠的,把所有这些内容都整理起来, ...

最新文章

  1. vue怎么vw布局好用_vue 实现 rem 布局的 或者 vw 布局的方法
  2. hadoop 1.2.1 安装步骤 伪分布式
  3. 博弈论笔记:逆向选择与非对称信息
  4. GridView实战二:使用ObjectDataSource数据源控件
  5. Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作用
  6. 网上一个仿TP挂钩内核的源码
  7. [转]Fiddler模拟post四种请求数据
  8. 精简ABP的模块依赖
  9. android 广播唤醒应用,Android通过广播实现灭屏和唤醒
  10. oracle存储过程季度方法,Oracle存储过程、触发器实现获取时间段内周、月、季度的具体时间...
  11. 关于NSString和NSMutableString的retainCount
  12. 开榨油店的失败教训_开榨油坊风险大吗?该如何投资
  13. java虚拟机内存存储一个对象_java虚拟机在java堆中对象内存分配、布局、访问
  14. word太大解决方法------图片压缩和visio图片批量压缩
  15. 半导体中的电子运动 有效质量
  16. uva 473 - Raucous Rockers(dp)
  17. About Redistribute
  18. On-board Diagnostic(OBD)
  19. 基于51单片机制作超声波避障小车+舵机控制
  20. 日语 假名对应的汉字来源

热门文章

  1. VirtualBox无法全屏显示终极解决方案!
  2. 2019新的一年,美好的心情来源发现,给大家分享一个双显示器下显示不同的桌面背景
  3. 白鹭引擎拉伸高度_答疑汇总|白鹭引擎架构师开源中国社区分享微信小游戏开发技巧...
  4. 智能语音电话机器人 快速拨打Restful接口
  5. 仿生算法_糖尿病患者:说出仿生胰腺很有趣,但是现实检查怎么样?
  6. PO_全局一揽子采购协议(流程)
  7. 【表情识别】基于稀疏表示特征模板匹配算法实现人脸表情识别含Matlab源码
  8. Win软件 - Logitech G HUB 鼠标 DPI 突快突慢解决方案
  9. Ardunio开发实例-PAJ7620手势识别传感器
  10. 3.4 图像几何变换——图像错切