惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
博客园_首页
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
N
News | PayPal Newsroom
S
Security Archives - TechRepublic
量子位
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Cisco Blogs
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
Scott Helme
Scott Helme
S
Securelist
Security Latest
Security Latest
爱范儿
爱范儿
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
L
LINUX DO - 最新话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
月光博客
月光博客
T
Tailwind CSS Blog
Cloudbric
Cloudbric
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
D
DataBreaches.Net
博客园 - 【当耐特】
有赞技术团队
有赞技术团队

博客园 - 银翼

【MySQL】Windows下如何彻底卸载MySQL? 【MySQL】Windows下如何重置root账号密码? 【Java】Task07实验4第5题解析 【辅导】Task12 类的定义与继承练习 【辅导】Task11 如何获取文件上传错误信息 PHP开发环境配置 XAMPP更换Apahce服务端口号 《Web应用开发技术(PHP)》往届学生优秀作业 【辅导】Task19 实现用户登录 主要知识点 【辅导】Task18 更新与插入删除操作 主要知识点 【辅导】Task17 查询数据 主要知识点 【辅导】Task16 使用MySQL数据库 主要知识点 【辅导】Task15 熟悉错误与异常处理 主要知识点 【辅导】Task14 使用正则表达式 主要知识点 【辅导】Task13 使用会话管理 主要知识点(2) 【辅导】Task13 使用会话管理 主要知识点(1) 【辅导】Task12 使用类和对象 主要知识点(1) 【辅导】Task11 熟悉PHP文件操作 主要知识点 【辅导】Task10 掌握PHP表单处理 主要知识点
【辅导】Task12 使用类和对象 主要知识点(2)
银翼 · 2020-04-08 · via 博客园 - 银翼

这次辅导主要是对类的多态性进行讲解。由于PHP是弱类型语言,所以导致在有些特征上有与Java等语言不同的地方,但总体上是差不多的。

1、实现类多态的三种途径

类的多态,就是用基类(父类)去管理派生类(子类),这些父类与派生类具有一致的行为,当父类对象指向子类对象的时候,具有的是子类的行为。

可以通过以下三种方式实现类的多态:

(1)重写父类方法

(2)使用抽象类

(3)实现接口

2、重写父类方法

从父类继承,你会得到父类的所有属性和方法,只不过受保护级别限制,public成员,你可以使用,别人也可以访问;protected成员,你自己和自己的子类可以访问,别人不能访问;private成员,你看不到,也使用不了(这一点有分歧,有人认为私有属性和方法不继承)。

在子类中,重新定义一个与父类同名的方法,称为方法重写。

方法重写时的注意事项:

(1)方法名与参数个数必须相同。参数不一致,会有warning提示。这一点与Java稍有不同。

(2)重写的方法的保护级别必须小于等于父类的方法。父类方法是public的,重写方法可以public、protected、private都可以;父类方法是protected,重写方法可以是protected和private。父类方法是private的,那子类可以定义一个新方法(这个方法正好与父类方法同名)。

(3)如果类的方法被声明为final,那这个方法不能被重写。如果类被声明为final,那这个类不能被继承了。

子类调用父类成员使用范围运算符:parent::成员名,前提是保护级别允许(public或protected)。

3、这真的是多态吗?

 

上面的foreach循环中,$shape是什么类型的变量? 在循环中加个调试语句试一下:

var_dump($shape);

会发现$shape变量分别是Point、Circle、Rectangle、Cylinder和Cube类型对象。主要是因为PHP是弱类型,它是通过赋值的数据推断类型的。

这意味着,如果不使用继承来完成这些类,只要保证这些类都有同样的getArea()和getVolume()方法,也可以实现这个功能。Java这类强类型不行,因为每个变量要有明确的类型,所以只能通过基类去管理派生类。

但你如何保证呢?从另一种形式说,通过继承和方法重写(即多态),你可以保证一组类具有相同的行为,从这一点说,这也是多态。

4、instanceof运算符

instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例。

子类属于父类的实例,所以如果 $c是Circle类对象,$c instacneof Point的结果是true。

instanceof也可以用来判断类对象是否实现了某个接口。

6、抽象类

抽象类用abstract定义。类中只要有一个方法是抽象方法,这个类就必须定义为抽象的。如果全是实体方法,这个类也可以定义为抽象类。

抽象类只能由子类来继承,不能用来实例化对象。因为不能实例化,所以没有构造函数与析构函数。

子类从抽象类继承,必须实现(重写)所有抽象方法。其它实体方法可以重写也可以不重写,没有重写就继承过来。

子类实现了抽象方法就是实体方法了,它的子类可以继承过来,可以重写也可以不重写。

使用抽象类,主要是因为有些方法不好定义具体的行为,就交给子类来定义的,同时也保证子类具有一致的行为。

方法重写规则与前面一致。

7、接口

接口使用interface定义。同类一样,不定义访问属性,都是public。

接口名称建议是i开头,如iCountable。

接口中可以定义方法和常量,都必须是public的。

接口中定义的所有方法都是空方法(只是说明没有实现)。

接口中可以定义构造函数。(工厂模式时有用,与Java不同)

一个类要实现接口,使用implements关键字。一个类只能从一个父类继承,但可以实现多个接口。

实现接口的类,必须实现接口中所有方法(不然会有致命错误Fatal error),并且实现时,方法的定义形式要与接口中的定义一致(方法名与参数名称均要完全相同)。

接口也可继承自一个或多个接口,使用extends关键字。

PHP没有完全解决好接口中的名称冲突问题。如果一个类实现多个接口,这些接口中可以有同名的方法,但这些方法的定义必须签名相同。

接口中可以定义常量。常量使用方法与类的常量相同,后面讲。

8、类的静态成员

类中可以定义静态字段和静态方法,使用static关键字。

在类的内部,使用self关键字来引用,如:self::$count

在类的外部,使用类名来引用,如:Student::getCount()

9、理解浅复制

 

将一个类的对象(已经用new 实例化)赋值给一个变量,得到的是这个对象的引用(两个变量指向同一个对象),不管有没有用&运算符。

使用clone运算符,可以将对象复制一份给变量(可以说是2个对象了)。但是如果这个对象里面的有字段是其它类的对象(比如学生对象里面有课程字段,它是Course类的对象),这些字段克隆过去仍然是引用(浅复制)。除非你去定义__Clone魔术函数(自己决定这些字段如何复制过去)。

10、类的常量

可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。使用const关键字来定义(不是使用define函数)。

 

在类的内部,使用self关键字来引用,如:self::constant

在类的外部,使用类名来引用,如:MyClass::constant

11、trait简介

trait是PHP提供的一种代码复用的方法,他主要用于类的组合(接口也是组合的一种方式,但接口中只有抽象方法)。

trait的定义与class一样,除了关键字是使用trait而不是class。

trait不能用来实例化对象,只能在定义类时,通过use语句引用到类中。(个人感觉没什么用,仅仅是方便程序员复用代码)。

可以这么理解,继承是纵向组合代码,trait是横向组合代码。

12、类型约束:方法的参数可以指定类型

看下面的例子:

 

为函数ShowArea指定了参数必须为Point类型,那么,Point类的子类都可以作为参数传递给它,结果是:

 

但Student类对象不能传递给它,会有错误:

 

 

类类型、接口、数组、Callable(函数)可以作为类型约束,但标量类型(如int,string)不能作为类型约束(因为能自动进行类型转换)。

类中的方法也支持类型约束。

13、练习一下

将我们在Java中学习的,使用抽象类和接口方式实现的多态性演示,在PHP中实现一下。