PHP类的基础常识及异常处理

一、多态

多态:多种形态
多态分为两种:方法重写和方法重载

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. 参数个数要一致
  3. 子类修饰的不能比父类更加严格

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();
?>

效果:
在这里插入图片描述
分析:

showA( ) 和 showB() 中的 $this 都表示B的对象,B中继承了A的私有属性,所以B中有两个 $this。在showA()
中只能访问A中的 $name ,不能访问B中的 $name。在showB() 中只能访问B中的 $name,不能访问A中的 $name

二、方法修饰符

方法修饰符有: static、final、abstract

2.1 static (静态的)

  1. static修饰的属性叫静态属性、static修饰的方法叫静态方法
  2. 静态成员加载类的时候分配空间,程序执行完毕后销毁
  3. 静态成员在内存中就一份
  4. 调用语法 类名::属性 类名::方法名()

例:

<?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要运行了才知道表示的是哪个类,所以叫做静态延时绑定。

小结:

1.static在内存中就一份,在类加载的时候就分配空间
2.如果有多个修饰符,修饰符之间是没有顺序的
3.self表示所在类的类名
4.static表示当前对象所属的类
5.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(抽象的)

  1. abstract修饰的方法是抽象方法,修饰的类是抽象类
  2. 只有方法的声明没有方法的实现称为抽象方法
  3. 一个类中只要有一个方法是抽象方法,这个类必须是抽象类
  4. 抽象类的特点是不能被实例化
  5. 子类继承了抽象类,就必须重新实现父类的所有的抽象方法,否则不允许实例化
  6. 类中没有抽象方法也可以声明成抽象类,用来阻止类的实例化

例:

<?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();
?>

效果:
在这里插入图片描述
抽象类的作用:

  1. 用来定义命名规范的
  2. 阻止实例化,如果一个类中所有的方法都是静态方法,这时没有必要去实例化,可以通过abstract来阻止实例化

三、类常量

类常量是const
例:

<?php
    class Student {
    
    
       public const ADD='地址不详'; // 7.1以后才支持访问修饰符
    }

    echo Student::ADD;
?>

效果:
在这里插入图片描述
问题1:define常量和const常量的区别?
答:const常量可以做类成员,define常量不可以做类成员。
问题2:常量和静态的属性的区别?
答:相同点: 都在加载类的时候分配空间
不同点:常量的值不可以更改,静态属性的值可以更改

四、接口

4.1 接口

  1. 如果一个类中所有的方法都是抽象方法,那么这个抽象类可以声明成接口
  2. 接口是一个特殊的抽象类,接口中只能有抽象方法和常量
  3. 接口中的抽象方法只能是public,可以省略,默认也是public
  4. 通过implements关键字来实现接口
  5. 不能使用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 () {
    
    
            
        }
    }
    
?>

注意:
1、在接口的多重实现中,如果有同名的方法,只要实现一次即可。
2、类可以继承的同时实现接口。

例:

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以上支持
作用: 将方法绑定到对象上。
语法:

闭包->call(对象):将闭包绑定到对象上并调用
(在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 使用的关键字

try:检测代码块
catch:捕获异常
throw:抛出异常
finally:无论有无异常都会执行,可以省略
Exception:异常类

语法结构:

<?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>

效果:
在这里插入图片描述

在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。

猜你喜欢

转载自blog.csdn.net/weixin_44103733/article/details/107645687
今日推荐