一、多态
多态:多种形态 多态分为两种:方法重写和方法重载
1.1 方法重写
子类重写了父类的同名的方法
<?php
// 父类
class Person {
public function show () {
echo '这是父类<br/>';
}
}
// 子类
class Student extends Person {
// 子类重写了父类的同名方法
public function show () {
echo '这是子类<br/>';
}
}
// 测试
$stu = new Student;
$stu->show();
?>
效果: 注意事项:
- 子类的方法必须和父类的方法同名
- 参数个数要一致
- 子类修饰的不能比父类更加严格
1.2 方法重载
方法重载:在同一个类中,有多个同名的函数,通过参数的不同来区分不同的方法,称为方法重载。 注意:php不支持方法重载,但是PHP可以通过其他方法来模拟方法重载。
1.3 私有属性继承和重写
私有属性可以继承但不能重写。 例如:
<?php
class A {
private $name = 'Javascript';
}
class B extends A {
private $name = 'Java';
}
$obj = new B();
var_dump($obj);
?>
效果: 可以看出私有属性是可以被继承的,但是没有被重写。
例题:
<?php
class A {
private $name = 'Javascript';
public function showA () {
echo $this->name,'<br/>';
}
}
class B extends A {
private $name = 'Java';
public function showB () {
echo $this->name,'<br/>';
}
}
$obj = new B();
$obj->showA();
$obj->showB();
?>
效果: 分析:
二、方法修饰符
方法修饰符有: static、final、abstract
2.1 static (静态的)
- static修饰的属性叫静态属性、static修饰的方法叫静态方法
- 静态成员加载类的时候分配空间,程序执行完毕后销毁
- 静态成员在内存中就一份
- 调用语法
类名::属性
类名::方法名()
例:
<?php
class Person {
public static $add='厦门';
public static function show() { // 修饰符没有顺序一说,可以static先写再写public一样
echo '我是一个静态方法<br/>';
}
}
echo Person::$add,'<br/>';
Person::show();
?>
效果:
练习: 一、统计人数(来一个加一个) (错误代码)
<?php
class Student {
private $num = 0;
public function __construct() {
$this->num++;
}
public function show() {
echo "总人数是:{$this->num}";
}
}
$stu1 = new Student;
$stu2 = new Student;
$stu2->show();
?>
效果: 分析: 因为private 是普通的私有变量,实例化一次,重新赋值一次。所以不能这样写。
正确写法:
<?php
class Student {
private static $num = 0;
public function __construct() {
self::$num++;
}
public function show() {
echo '总人数是:'.self::$num,'<br/>';
}
}
$stu1 = new Student;
$stu2 = new Student;
$stu2->show();
?>
效果: self总是表示当前类的类名。
静态成员也是可以被继承的:
<?php
class Person {
public static $add='Amoy';
public static function show() {
echo '我是静态方法';
}
}
// 继承
class Student extends Person {
}
// 测试
echo Student::$add,'<br/>';
Student::show();
?>
效果:
静态延时绑定 static表示当前对象所属的类。 例:
<?php
class Person {
public static $type='人类';
public function show1 () {
echo static::$type,'<br/>';
}
}
class Student extends Person {
public static $type='学生';
public function show2 () {
echo static::$type;
}
}
$obj = new Student();
$obj->show1();
$obj->show2();
?>
效果: self就算代码不运行,也能看出它总是表示当前类,而static要运行了才知道表示的是哪个类,所以叫做静态延时绑定。
小结:
2.2 final(最终的)
final修饰的方法不能被重写 final修饰的类不能被继承
例:
<?php
class Person {
public static $type='人类';
final public function show () {
echo static::$type,'<br/>';
}
}
class Student extends Person {
public static $type='学生';
public function show () {
echo static::$type;
}
}
?>
效果: 作用: 1、如果一个类确定不被继承,一个方法确定不会被重写,用final修饰可以提高执行效率。 2、如果一个方法不允许被其他类重写,可以用final修饰。
2.3 abstract(抽象的)
- abstract修饰的方法是抽象方法,修饰的类是抽象类
- 只有方法的声明没有方法的实现称为抽象方法
- 一个类中只要有一个方法是抽象方法,这个类必须是抽象类
- 抽象类的特点是不能被实例化
- 子类继承了抽象类,就必须重新实现父类的所有的抽象方法,否则不允许实例化
- 类中没有抽象方法也可以声明成抽象类,用来阻止类的实例化
例:
<?php
// 抽象类
abstract class Person {
public abstract function setInfo(); // 抽象方法
public function getInfo () {
echo '获取信息<br/>';
}
}
//$obj = new Person(); // 不允许实例化
// 继承
class Student extends Person {
public function setInfo () {
echo '重新实现父类抽象方法<br/>';
}
}
$obj = new Student;
$obj->setInfo();
$obj->getInfo();
?>
效果: 抽象类的作用:
- 用来定义命名规范的
- 阻止实例化,如果一个类中所有的方法都是静态方法,这时没有必要去实例化,可以通过abstract来阻止实例化
三、类常量
类常量是const 例:
<?php
class Student {
public const ADD='地址不详'; // 7.1以后才支持访问修饰符
}
echo Student::ADD;
?>
效果: 问题1:define常量和const常量的区别? 答:const常量可以做类成员,define常量不可以做类成员。 问题2:常量和静态的属性的区别? 答:相同点: 都在加载类的时候分配空间 不同点:常量的值不可以更改,静态属性的值可以更改
四、接口
4.1 接口
- 如果一个类中所有的方法都是抽象方法,那么这个抽象类可以声明成接口
- 接口是一个特殊的抽象类,接口中只能有抽象方法和常量
- 接口中的抽象方法只能是public,可以省略,默认也是public
- 通过implements关键字来实现接口
- 不能使用abstract和final来修饰接口中的抽象方法
例:
<?php
// 声明接口
interface Person {
const ADD='中国';
function fun1 ();
function fun2 ();
}
// 接口实现
class Student implements Person {
public function fun1() {
}
public function fun2() {
}
}
// 访问接口中的常量
echo Person::ADD;
?>
效果:
4.2 接口的多重实现
类不允许多重继承,但是接口允许多重实现。 例:
<?php
// 声明接口
interface IPic1 {
function func1 ();
}
interface IPic2 {
function func2 ();
}
// 接口允许多重实现
class Student implements IPic1, IPic2 {
public function func1 () {
}
public function func2 () {
}
}
?>
例:
class Student extends Person implements IPic1,IPic2 {
}
五、匿名类
PHP7.0以上支持 例:
<?php
$stu = new class {
public $name = 'tom';
public function __construct () {
echo '构造函数<br/>';
}
};
echo $stu->name;
?>
效果: 小结: 如果类只被实例化一次就可以使用匿名类。 好处: 实例化完毕后,就回收了类的空间。
六、方法绑定
PHP7.0以上支持 作用: 将方法绑定到对象上。 语法:
(在php中匿名函数称为闭包)
例:
<?php
$lang='ch';
class Student {
}
if ($lang == 'ch') {
$fun = function () {
echo '我是一名学生';
};
}
else {
$fun = function () {
echo 'i am a student';
};
}
// 绑定
$stu = new Student;
$fun->call($stu)
?>
效果:
七、异常处理
集中处理在代码块中发生的异常。 在代码块中发生了异常直接抛出,代码块中不处理异常,将异常集中起来一起处理。
7.1 使用的关键字
语法结构:
<?php
try {
// 检测代码
}
catch (Exception $ex) {
// 捕获异常
}
finally {
// 无论是否有异常,都会执行,finally可以省略
}
?>
7.2 例题
例题:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<?php
if (isset($_POST['button'])) {
try {
$age = $_POST['age'];
if ($age == '') {
throw new Exception('年龄不能为空'); // 抛出异常
}
if (!is_numeric($age)) {
throw new Exception('年龄必须是数字'); // 抛出异常
}
if (!($age >= 10 && $age<=30)) {
throw new Exception('年龄必须在10到30之间'); // 抛出异常
}
echo '您的年龄合适';
}
catch (Exception $ex) { // 捕获异常
echo '错误信息:'.$ex->getMessage(),'<br/>';
echo '错误码:'.$ex->getCode(),'<br/>';
echo '文件地址:'.$ex->getFile(),'<br/>';
echo '错误行号:'.$ex->getLine(),'<br/>';
}
}
?>
<body>
<form action="" method="post">
年龄:<input type="text" name="age"><br/>
<input type="submit" name="button" value="提交">
</form>
</body>
</html>
效果: 注意:抛出异常后,try块终止执行,执行权限交给catch块。
八、自定义异常
场景:如何实现异常的分类处理?比如异常有三个级别对应三种处理方式。自定义三种异常即可。
所有异常的父类是Exception,Exception中的方法不允许重写。 例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<?php
// 自定义空异常类
class MyNullException extends Exception {}
// 自定义类型异常
class MyTypeException extends Exception {}
// 自定义的范围异常
class MyRangeException extends Exception {}
// 逻辑代码
if (isset($_POST['button'])) {
try {
$name=$_POST['name'];
$age=$_POST['age'];
if ($name == '') {
throw new MyNullException('姓名不能为空!');
}
if ($age == '') {
throw new MyNullException('年龄不能为空!');
}
if (!is_numeric($age)) {
throw new MyTypeException('年龄必须是数字!');
}
if ($age < 10 && $age > 30) {
throw new MyRangeException('年龄必须在10~30之间!');
}
echo '姓名:'.$name,'<br/>';
echo '年龄:'.$age,'<br/>';
}
catch (MyNullException $ex) {
echo $ex->getMessage(),'<br/>';
echo '错误记录在日志中';
}
catch (MyTypeException $ex) {
echo $ex->getMessage(),'<br/>';
echo '发送电子邮件';
}
catch (MyRangeException $ex) {
echo $ex->getMessage(),'<br/>';
echo '联系管理员修改';
}
}
?>
<form action="" method="post">
姓名:<input type="text" name="name"><br/>
年龄:<input type="text" name="age"><br/>
<input type="submit" name="button" value="提交">
</form>
</body>
</html>
效果:
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!