PHP面向对象编程

PDO面向对象编程

概述

  • 面向对象编程是一种编程思想

  • 面向对象编程是以事物(对象)为中心的编程思想

  • 面向对象编程是以功能来划分问题,而不是步骤

类和对象的关系

  • 类是具有相同属性和行为的一组对象的集合,它为属于类的全部对象提供了统一的抽象描述,其中内部包含属性和行为的两个部分。
  • 类的两个要素:属性(Attribute)和行为(Behavior)
  • 对象是类的实例,类是对象的模板
  • 类是抽象的,几乎不占用内存,而对象是具体的,占用存储空间

类的定义

  • 定义语法格式:class 类名称{...}

    • 关键字 class
  • 属性 某个类具有公共的特征和特性,与普通变量的区别,类成员必须带权限修饰符。

    • 方法 某个类的公共行为或动作,与普通函数的区别,类方法带权限修饰符,权限修饰符可以省略,默认值为public
    • 权限修饰符:public 、private、protected修饰
    <?php
    //定义一个学生类
    class Student{
       	public $name = "张三";
        private $age =28;
        //构造函数
        public function __construct(){
            
        }
        //方法
      public function showInfo(){
            echo "{$this->name}的年龄是{$this->age}岁!";
        }
    }
        
     ?>
    

实例化对象

  • 使用关键字 new创建

  • 实例: o b j = n e w S t u d e n t ( ) ; 或 obj = new Student();或 obj=newStudent();obj = new Student;

  • 访问对象属性和方法: o b j − > n a m e ; obj->name; obj>name;obj->showInfo();

    <?php
    	$obj = new Student();//实例化对象
    	echo $obj->name;//调用属性 $obj->age会报权限不足,只有public修饰符修饰的属性或方法可以在外部调用
    	$obj->showInfo();//调用方法
    ?>
        
    

对象属性操作

  • 添加或赋值:对象->属性 = 值;如:$obj->name = "李四";存在的属性会重新赋值,不能操作的属性,会添加
  • 删除属性:unset(对象->属性);如:unset($obj->name);
  • 读取属性:对象->属性;如:$obj->name;

对象方法操作

  • 调用:对象->方法();如:$obj->showInfo();

$this关键字

  • $this指当前实例化的对象,只能在对象内使用;
  • $this是当前对象的一个引用
  • 在方法内调用对象时,可以使用 t h i s 调 用 , 如 : ‘ this调用,如:` thisthis->name`
  • 只有创建对象后,$this变量才会存在,类不会自动调用。

__construct()构造方法

  • 当使用new 实例化对象是,系统默认调用的第一个方法。

  • 构造方法固定写法,_construsct(){},类默认有一个参数为空的构造方法!

  • 作用:对象初始化,如给对象属性赋值

  • 构造方法不需要手动调用,会自动被调用;

    <?php
    class Student{
        public $name;
        public $age;
        public $height;
        
        public function __construct($n,$a,$h){
            $this->name = $n;
            $this>age = $a;
            $this->height = $h;
        }
        
        public function showInfo(){
            echo "<br>姓名:".$this->name;
            echo "<br>年龄:".$this->age."岁";
            echo "<br>身高:".$this->height."cm";
        }
    }
        
        
    $student = new Student('张三',20,172);
    $student->showInfo();   
        
    ?>
        
    

    打印结果:

    姓名:张三
    年龄:20岁
    身高:172cm
    

__destruct()析构方法

  • 定义:对象销毁前自动调用的方法,方法名称是固定的__destruct(void){}
  • 作用:垃圾回收工作,释放内存,如断开Mysql数据库连接
  • 执行时间:程序执行完毕时,对象会自动销毁;或使用unset删除对象时;
    • 正常销毁执行是在网页执行完毕后,销毁对象时才会执行__destruct()
    • 如果使用unset()方法删除对象时,unset()之后,会马上执行__destruct()

类常量

  • 类介绍

    • 可以把类中始终保持不变的值定义为常量
    • 常量的值必须是一个定值,不能修改,也不能删除
    • 类常量是类的常量,是与类相关,与对象无关
    • 类常量在内存中只有一份,不管创建多少个对象
    • 类常量可以极大节约服务器内存,可以被所有对象共享
  • 类常量的定义和调用格式

    • 类常量没有权限
    • 使用const来定义类的常量(局部常量),只能在类的局部作用域下使用。define()定义的是全局变量,在任意地方可以使用
  • 语法:const 常量名 = 常量值;

    • 常量名建议全大写
    • const定义的常量必须赋值
    • 常量的值必须为定值
    • 常量没有权限修饰符
    • 常量调用:ClassName::常量名;(使用静态化调用)
    • 注意:类常量不是变量,在使用是不能像变量一样在双引号中被解析,如果需要使用,请按一下方式"班级名称为".Student::CLASSNAME;
    <?php
    class Student{
        const CLASSNAME = "中一班";
        public $name = "张三";
        private $age = 4;
    }
        
    //访问
    echo Student::CLASSNAME;
        
    ?>
        
    

静态属性和静态方法

  • 关键值 static 修饰的属性或方法就是静态属性或方法

  • 静态属性和静态方法时类的属性和方法,与对象无关

  • 调用静态属性和静态方法,需要使用类名::$属性类名::方法()方式

  • 静态属性或静态方法,在内存中只有一份,被所有对象共享。

  • 静态属性和类常量的区别:类常量在一次http请求过程中值保持不变,但静态属性可以改变

  • 静态属性和静态方法都可以加权限修饰符,类常量没有权限。

    <?php
    class Student{
        public function $count = 60;
    }    
        
    echo Student::$count;    
        
    ?>
    
    

self关键字

  • self是当前类的指针,$this是当前对象的指针

  • self用来调用类常量、静态属性和静态方法

  • t h i s 不 一 样 , this不一样, thisthis是调用对象的属性和方法,且$this关键字只能在成员方法中使用。

  • self可以在成员方法和静态方法中使用

  • static修饰的方法,不能出现$this

    <?php
    class Student{
        public $name = "张三";
        public static $class_name = "中一班";
        public static function test(){
            echo self::$class_name;
            //echo $this->name;//错误调用
        }
        
    }
        
    Student::test();    
        
    ?>
        
    

学生类实例

  • 要求:定义一个学生类,该类包含姓名,性别,年龄等基本信息,并且至少包含一个静态属性和一个常量,以及包括构造方法和析构方法。该对象还可以调用一个方法来进行自我介绍,显示该学生对象的所有属性。构造方法可以自动初始化一个学生的基本信息,并显示’‘欢迎某某新同学加入中一班大家庭,当前班级共有xx个学生”。

    <?php
    class Student{
        const CLASS_NAME = '中一班';//类常量
        private static $count = 0;//静态属性
        private $name;
        private $age;
        private $sex;
    
        public function __construct($n,$a,$s){
            $this->name = $n;
            $this->age = $a;
            $this->sex = $s;
            self::$count++;
            echo "<br>欢迎".$n."同学加入".self::CLASS_NAME."大家庭,当前班级人数为".self::$count;
            self::showInfo();
        }
    
        public function showInfo(){
            echo "<br>班级:".self::CLASS_NAME;
            echo "<br>姓名:".$this->name;
            echo "<br>年龄:".$this->age;
            echo "<br>性别:".$this->sex;
        }
    
        public function __destruct(){
        }
    }
    
    $student = new Student('张三',4,'男');
    $student2 = new Student('李四',3,'男'); 
        
    ?>
    
  • 输出结果

    欢迎张三同学加入中一班大家庭,当前班级人数为1
    班级:中一班
    姓名:张三
    年龄:4
    性别:男
    欢迎李四同学加入中一班大家庭,当前班级人数为2
    班级:中一班
    姓名:李四
    年龄:3
    性别:男
    

对象内存分布情况

  • 分布

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WBfOv8Mx-1573031277933)(E:\学习笔记\PHP学习\images\opp内存分布情况.png)]

  • 使用var_dump()打印对象时,只看到对象的属性;

对象属于引用传递

  • 把对象赋值给另一个变量时,会把对象的引用地址赋予

    <?php
    class Student{
        public $name;
        public $age;
        public $sex;
        public function __construct($n,$a,$s){
            $this->name = $n;
            $this->age = $a;
            $this->sex = $s;
        }
    
    }
    
    $student = new Student('张三',4,'男');
    $student2 = $student;
    $student2->name = "李四";
    echo "<pre>";
    var_dump($student);
    
    
  • 输出结果

    object(Student)#1 (3) {
      ["name"]=>
      string(6) "李四"
      ["age"]=>
      int(4)
      ["sex"]=>
      string(3) "男"
    }
    

类的特性

类的三大特性封装、继承和多态

封装性

  • public 公共权限 在任意地方都可以调用,包括类内、类外、子类均可以调用

  • private 私有权限 只能在类中调用

  • protected 受保护的 类中和子类中可以条用,类外不能调用

  • 简单实现数据库类连接

    class Db{
        //私有配置属性
        private $db_host;//主机名
        private $db_user;//用户名
        private $db_pass;//密码
        private $db_name;//数据库名称
        private $charset;//字符集
        private $link;//连接对象
    
    
        //构造方法实现数据库对象初始化
        public function __construct($config = array()){
            $this->db_host = $config['db_host'];
            $this->db_user= $config['db_user'];
            $this->db_pass= $config['db_pass'];
            $this->db_name= $config['db_name'];
            $this->charset= $config['charset'];
    
            $this->connectDb();//连接数据库服务器
            $this->selectDb();//选择数据库
            $this->setCharset();//设置字符值
        }
    
        //连接数据库
        private function connectDb(){
            if(!$this->link = @mysqli_connect($this->db_host,$this->db_user,$this->db_pass)){
                echo "连接Mysql服务器失败";
                die();
            }
        }
    
        //选择数据库
        private function selectDb(){
            if(!mysqli_select_db($this->link,$this->db_name)){
                echo "选择数据库失败";
                die();
            }
        }
    
        //设置字符在
        private function setCharset(){
            mysqli_set_charset($this->link,$this->charset);
        }
    
        //关闭数据库连接
        public function __destruct(){
            mysqli_close($this->link);
        }
    
    }
    
    $arr = array(
        'db_host'=>'127.0.0.1',
        'db_user'=>'root',
        'db_pass'=>'root',
        'db_name'=>'shitu',
        'charset'=>'utf8',
    );
    $db = new Db($arr);
    var_dump($db);
    
    ?>
    

继承性

  • 关键字extends

    <?php
    class Student{
     	public $name;
        public $age;
    }   
    
    class English extends Student{
        public $className;
    }
    
    ?>
    
  • 如果多个类拥有相同的属性和方法,可以把相同的属性和方法提取出来,放到一个 “父类”中,然后再创建子类通过extends关键字进行继承父类。

  • 子类拥有父类中所属性和方法(除了private权限修饰符修饰的),子类中可以直接调入属性和方法;

  • 子类可以扩展新功能和对父类中的功能进行完善,实现功能的升级和完善

  • 类只能单继承,某一个子类有且只有一个直接父类;

parent 关键字

  • self代表当前类,parent代表父类

  • self用来调用本类的内容,包括:类常量、静态属性、静态方法、成员方法等

  • parent 用来调用父类的内容,包括:类常量、静态方法、静态属性和成员方法等

  • self 和 parent都是用范围解析符::来调用其内容

  • 语法:parent::类常量 | 静态属性 | 静态方法 | 成员方法;

    <?php
    class Student{
        const TABEL = "学生";
        protected  $name;
        protected $age;
    }
    
    class PHPStudent extends Student{
        const TABEL = "PHP学生";
        public function showInfo(){
            echo "<br>父类中的TABEL".parent::TABEL;
            echo "<br>本类中的TABEL".self::TABEL;
        }
    }
    $stu2 = new PHPStudent();
    $stu2->showInfo();    
        
        
    ?>
    

多态性

  • 子类进行同名方法重现,实现类的多种形态
  • 方法重写要求:
    • 与父类中的方法名同名
    • 要求参数与父级的参数一样
    • 与父类中同名方法类型一致 如:父类属于静态方法的子类也必须是静态的
    • 子类重写的方法访问权限,不能低于父类的同名方法权限
      • 父类方法权限为public时,子类的同名方法权限只能为public
      • 父类方法权限为protected时,子类同名方法权限可以时public和protected
      • 父类方法权限为private时,子类无法继承和重写

最终类和最终方法

  • 关键字 final
  • final关键字修饰的类,就是最终类,不能被继承
  • final关键字修饰的方法,就是最终方法,不能被重写
  • 最终类和最终方法不能同时用,因为最终类不能被继承,所有无法重写

抽象类和抽象方法

  • 关键字 abstract

  • abstract 修饰的类,就是抽象类,该类不能直接实例化,必须先继承和重写抽象方法后才能实列化;

  • abstract修饰的方法,该方法存在与抽象类中,必须重写后才能使用;

    • 注意:抽象方法,不能有方法体(即没有{});
  • 如果一个类中包含了抽象方法,则这个类必须是抽象类

  • 在PHP7中,抽象方法可以是成员方法,也可以是静态方法,在PHP5的版本只能为成员方法·

  • 抽象类中可以定义类的所有属性和方法,但必须包含一个或一个以上的抽象方法的

    <?php
    //抽象类
    abstract class Student{
        const TABEL = "学生";
        protected  $name;
        protected $age;
        //抽象方法
        public abstract function showInfo();
        
    }
    
    class PHPStudent extends Student{
        const TABEL = "PHP学生";
        public function showInfo(){
            echo "<br>父类中的TABEL".parent::TABEL;
            echo "<br>本类中的TABEL".self::TABEL;
        }
    }
    $stu2 = new PHPStudent();
    $stu2->showInfo();    
        
        
    ?>
    

接口

  • 关键字 interface 定义接口

  • 关键字 implements 来实现接口

  • 接口中方法权限必须为public

  • 接口中所有方法默认为抽象的

  • 接口中可以是静态方法也可以是成员方法

  • 接口中可以定义常量,常量值不能被重写

  • 类可以实现(implements)多个接口

  • 接口也可以继承接口

    <?php
    //学生接口
    interface Student{
        const TABEL = "学生";
        public function showInfo();//权限必须为public
    }
    //实现接口
    class PHPStudent implements Student{
        //const TABEL = "PHP学生";//不能重写变量
        public function showInfo(){
            echo "<br>本类中的TABEL".self::TABEL;
        }
    }
    $stu2 = new PHPStudent();
    $stu2->showInfo();    
        
    ?>
        
    

__clone()对象克隆

  • 关键字 clone;

  • 语法:$obj2 = clone $obj2;

  • 魔法方法:__clone() 会自动调用,可以在克隆过程中做一些操作

    <?php
    class Student{
        public $name = "张三";
        public $age =28;
        public function showInfo(){
            echo "<br>{$this->name}的年龄为{$this->age}岁";
        }
    
        //克隆方法
        public function __clone(){
            $this->name = $this->name."_克隆";
            $this->age = $this->age."_克隆";
        }
    }
    
    $student = new Student();
    $student2 = clone $student;
    var_dump($student);
    var_dump($student2);    
        
    ?>
    
  • 输出结果

    object(Student)#1 (2) { ["name"]=> string(6) "张三" ["age"]=> int(28) } object(Student)#2 (2) { ["name"]=> string(13) "张三_克隆" ["age"]=> string(9) "28_克隆" }
    

foreach遍历对象

  • 遍历对象会遍历对象的属性

    class Student{
        public $name = "张三";
        public $age =28;
        public function showInfo(){
            echo "<br>{$this->name}的年龄为{$this->age}岁";
        }
    }
    
    $student = new Student();
    foreach($student as $k => $v){
        echo "<br>$v";
    }
    
  • 输出结果

    张三
    28
    

__toString()转字符串

  • 把对象转成字符串时,__toString()会自动调用

  • 语法 `public string __toString(void)

  • 注意:PHP不支持对象转字符串,因此,不能使用echo 输出一个对象。

  • 直接输出对象,系统会报语法错误,存在暴露服务器系统路径安全,因此一般使用__toString()屏蔽报错**Recoverable fatal error**: Object of class Student could not be converted to string in **E:\rufeike\xdqphp\index.php** on line **23**

    <?php
    class Student{
        public $name = "张三";
        public $age =28;
        public function showInfo(){
            echo "<br>{$this->name}的年龄为{$this->age}岁";
        }
    
        public function __toString(){
            return "对象不能直接输出";
        }
    }
    
    $student = new Student();
    echo $student;
    ?>
    

    输出结果

    对象不能直接输出
    

__invoke()把对象当函数调用

  • 描述:当把一个对象当成函数调用时,__invoike()会自动调用

  • 当函数调用时,会报错**Fatal error**: Uncaught Error: Function name must be a string in E:\rufeike\xdqphp\index.php:23 Stack trace: #0 {main} thrown in **E:\rufeike\xdqphp\index.php** on line **23**

    <?php
    class Student{
        public $name = "张三";
        public $age =28;
        public function showInfo(){
            echo "<br>{$this->name}的年龄为{$this->age}岁";
        }
    
        public function __invoke(){
            echo  "对象不是函数,不能当函数调用";
        }
    }
    
    $student = new Student();
    $student();    
           
    ?>
        
    

    输出结果:

    对象不是函数,不能当函数调用
    

单例设置模式

  • 描述:一个类只能创建一个实例对象

  • 设置要求(三私一公):

    • 私有的静态保存对象属性
    • 私有的构造方法,防止类外部new对象
    • 私有的克隆方法,防止类外部clone对象
    • 公共的静态创建对象的方法
  • 代码实现:

    <php?
    class Db{
        //私有的静态保存对象属性
        private static $db = null;
        //私有的构造方法
        private function __construct(){}
        //私有的克隆方法
        private function __clone(){}
        //公共的静态创建对象方法
        public static function getInstance(){
            //判断当前对象是否存在
            if(!self::$db instanceof self){
                //如果对象不存在则创建对象
                self::$db = new self();
            }
            //存在则返回对象
            return self::$db;
        }
    
        //防止直接输出对象
        public function __toString(){
            return "对象不能直接输出";
        }
    
        //防止对象当函数调用
        public function __invoke(){
            echo  "对象不能当函数使用";
        }
    }
    
    $db = Db::getInstance();
    $db2 = Db::getInstance();
    var_dump($db);
    echo "<br>";
    var_dump($db2);
    ?>
    

    输出结果:

    object(Db)#1 (0) { }
    object(Db)#1 (0) { }
    

工厂设置模式

  • 描述:生产不同类对象的工厂。功能拓展和维护方便

  • 传递不同的类名参数,返回不同类的对象

  • 使用new 关键字创建对象的方式,改成工厂类中创建类的对象

  • 主要实现思想,对功能和特性进行抽取 分成接口文件、实现类文件和工厂类文件以及应用类执行;

    • 接口文件USB.interface.php
    <?php
    interface USB{
        public function run();
        public function read();
        public function write();
    }   
    ?>
    
    • 实现类文件 USB1.class.php和USB2.class.php
    <?php
    class USB1 implements USB{
        public function run(){}
        public function read(){}
        public function write(){}
    }
    ?>
    
    <?php
    class USB2 implements USB{
        public function run(){}
        public function read(){}
        public function write(){}
    }
    ?>
    
    • 工厂类Factory.class.php
    <?php
    class Factory{
        //对象创建方法
        public static function getInstance($className){
            //根据传递的不同类名参数,返回不同的类对象
            switch($className){
                case "USB1":
                    return new USB1();
                    break;
                case "USB2":
                    return new USB2();
                default:
                    return null;
            }
    
        }
    
    }
    ?>
    
    • 应用文件index.php
    <?php
      spl_autoload_register(function($className){
          $classPath = '.\lib\'.$className.'.interface.php';
          if(file_exists($classPath)){
          		require_once($classPath);
          }else{
          		die($classPath)不存在;
          }
      })
        
        
    ?>
    

PHP重载

  • PHP中所谓的重载,是指动态的创建类属性和方法,为了实现该功能。PHP官方提供了相关的魔术方法用于实现。
  • 当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用
  • 作用:该类方法可以屏蔽以下系统报错,也可以变相处理想要获取以下私有或受保护的内容
  • 注意:
    • 所有重载的方法,必须声明为public
    • 属性重载只能再对象中进行,在静态方法中,这些魔术方法不会被调用。
    • 魔术方法不能引用传递

__get()获取属性

  • 描述:读取不可访问的属性的值时,__get()会被调用
  • 语法:public mixed __get($var)
<?php
 class Student{
    private $name;
    private $age;
    public function __get($var){
        echo "该".$var."属性为私有,不能访问";
    }
}

$student = new Student();
echo $student->age;  
    
?>
    

输出结果

该age属性为私有,不能访问

__set()设置属性

  • 描述:给不可访问的属性赋值时,__set()会被调用
  • 语法:public mixed __set($var)
  • 作用:屏蔽报错,也可以个私有属性赋值
<?php
class Student{
    private $name;
    private $age;
    public function __set($var){
        $this->age = $var;
    }
}

$student = new Student();
echo $student->age=10;  
    
?>

__unset()删除属性

  • 描述:删除不可访问的属性时,__unset()会被调用
  • 删除私有属性和屏蔽错误
<?php
class Student{
    private $name;
    private $age;
    public function __unset($var){
        if(isset($this->$var)){
            unset($this->$var);
        }
    }
}

$student = new Student();
unset($student->age);  
    
?>

__isset()属性是否存在

  • 描述:对不存在或不可访问的属性调用isset()或empty()时,__isset()会被调用
  • 语法:public mixed __isset($var)
  • 作用:屏蔽报错和判断是否存在私有属性
<?php
class Student{
    private $name;
    private $age;
    public function __isset($var){
        if(isset($this->$var)){
            return true;
        }else{
            return false;
        }
    }
}

$student = new Student();
isset($student->age);  
    
?>

__call()调用方法

  • 描述:当访问不存在或不可访问的方法时,__call()会被调用
  • 接收两个参数 __call( f u n c , func, func,args)
  • 屏蔽错误或做其他处理
<?php
class Student{
    private $name;
    private $age;
    public function __call($func,$args){
        //处理代码
    }
}

$student = new Student();
$student->showInfo();  
    
?>

__callStatic()调用静态方法

  • 描述:用静态方式当访问不存在或不可访问的方法时,__callStatic()会被调用
  • 接收两个参数 __call( f u n c , func, func,args)
  • 屏蔽错误或做其他处理
<?php
class Student{
    private $name;
    private $age;
    public function __callStatic($func,$args){
        //处理代码
    }
}

$student = new Student();
$student::showInfo();  
    
?>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值