php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: php 视频教程
查看: 453|回复: 0

4、面向对象基础

[复制链接]

61

主题

61

帖子

426

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
426
发表于 2021-5-2 22:10:17 | 显示全部楼层 |阅读模式
[TOC]
### 类的声明 ###
- 定义类:

----------
    [修饰类的关键字] class 类名
    {
        成员
    }
- 类文件的命名: 类名.class.php
- 注意事项:
> - 类的成员要和类名相关
> - 类的成员属性前面必须要有修饰词, 不知道写什么就写 var
> - 类的成员对象在定义时可以设置初值, 但建议不要
> - 类的成员默认访问权限是: public
## 实例化类 ##

----------
    $对象名 = new 类名([参数列表]);
    $对象名 = new 类名;
## 对象在内存中的分配 ##
### 内存的划分 ###
- 栈: 存放程序中临时创建的变量, 空间小但被 CPU 访问的速度很快。用于储存占用空间不变且占用空间小的数据类型的内存段
- 堆: 用于存储进程运行中被动态分配的内存段, 大小不固定, 可以动态扩张或缩减。用于存储数据长度可变或占用内存较大的数据
- 初始化数据段: 用于存放可执行文件中已初始化的全局变量, 即程序静态分配的变量
- 代码段: 存放可执行文件的操作指令, 即可执行文件在内存中的镜像, 访问类型为只读

### 对象的存储 ###
对象存储在堆内存中, 在堆中的地址储存在栈上, 变量对应的是栈上的空间
## 调用对象的成员 ##
- 对象->属性
- 对象->方法
## 构造函数 ##
- 作用: 为对象初始化属性
- PHP4 中使用, 普通方法

----------
    function 类名()
    {
        函数体
    }
- PHP5 中使用, 魔术方法

----------
    function __construct()
    {
        函数体
    }
## 析构函数 ##
- 作用: 关闭资源, 清理垃圾
- PHP4 中没有析构函数的概念;PHP5 中才使用, 属于魔术方法

----------
    function __destruct()
    {
        函数体
    }
## 魔术方法 ##
PHP 给某些功能预设好了函数名, 直接定义这个函数就可以实现对应的功能, 如: 随着对象的创建而加载的 \_\_construct() 函数, 一般此类函数都是以 "\_\_" 开头
## this 指针 ##
- 指向成员属性: $this->属性
- 指向成员方法: $this->方法

## 类的封装 ##
- 含义: 将属性和方法封装成一个整体, 隐藏类的内部细节
- 步骤: 使用 private 隐藏类的属性和内部方法
- 有关的魔术方法:

----------
    __set($proName, $proValue): 直接设置私有成员属性时调用, 可以对属性值进行限制。设置值时: $this->proName = $proValue;
    __get($proName): 直接获取私有成员属性时调用。返回属性值时: return $this->proName;
    __isset($proName): 使用 isset() 函数检查私有属性是否存在时调用。返回检查结果: return isset($this->proName);
    __unset($proName): 使用 unset() 函数释放私有属性所占资源时调用。删除属性: unset($this->proName);
## 继承的作用 ##
- 增加开放性、可扩展性
- 提高代码重用性
- 提高软件可维护性
- 继承就是用子类扩展父类
- PHP 属于单继承

## 继承的应用 ##
只要两个或以上的类中有公共部分, 就可以共享, 就能作为父类
## 继承的语法 ##
- 子类 extends 父类
- 子类将继承父类的所有成员, 包括 private 成员, 但是子类无法直接使用父类的 private 成员

## 访问类型控制 ##
- private: 子类和外部都不能访问
- protected: 子类能够访问, 外部不能访问
- public: 子类和外部都能访问

## 子类重写父类方法 ##
- 子类可以声明和父类方法同名的方法, 用以覆盖父类方法
- 如果子类中需要使用父类的方法, 不要写重复代码, 直接调用即可
- 子类调用父类中被覆盖的方法:
> - 父类::方法名();
> - parent::方法名();
- 子类的构造方法中尽量调用父类的方法给父类的变量初始化
- 重写方法的访问权限不能低于父类的同名方法, 如果父类方法的访问权限是 protected, 则子类方法必须是 protected/public

## PHP 中常用关键字 ###
### final ###
- 作用: 使用 final 修饰的类, 不能被继承;使用 final 修饰的方法, 不能被重写
- 注意: final 不能修饰成员属性, 只能修饰类和方法, 类中的常量是用 const 修饰
### static ###
- 作用: 使用 static 修饰的属性, 可以被一个类的所有对象共享;使用 static 修饰的方法, 不用创建对象就能使用
- 注意:
> - static 只能修饰属性或方法, 不能修饰类
> - 静态数据是在类第一次被加载(第一次出现类名时)时声明, 其后都是使用
> - 静态成员必须使用类名访问: 类名::静态成员, 在 PHP5 以后可以使用 self 指代本类
> - 静态方法不能访问非静态成员, 因为可能访问时还未创建对象

### const ###
- 作用: 在类中定义常量属性
- 注意:
> - 只能修饰成员属性
> - 常量不需要使用 "$", 定义时直接是: const 常量名 = 值
> - 调用常量时需要使用 类名/self 调用
> - const 的作用域为当前命名空间;define 的作用域为全局

### instanceof ###
可以确定一个对象是类的实例、类的子类还是实现了某个接口, 并进行相应的操作, 比较失败将退出脚本, 主要用于处理多个对象。如多个对象调用同个方法, 但是需要根据特定的对象类型调整函数的行为。

----------
    $man = new Person();
    if ($man instanceof Person)
        echo '$man 是 Person 类的对象';
### clone ###
使用 clone 关键字将创建对象副本, 而不是设置别名, 使用时自动调用 \_\_clone() 函数

----------
    $a = new Person();
    $b = clone $a;
## 魔术方法 ##

----------
    __construct: 构造函数
    __destruct: 析构函数
    __set: 设置私有属性值时
    __get: 获取私有属性值时
    __isset: 判断私有属性是否存在时
    __unset: 释放私有属性所占资源时
    __call: 调用对象中不存在的方法时调用, 没有此方法则报错
    __toString: 需要将对象转化成字符串时
    __clone: 克隆出另一个副本对象(当使用 $对象2 = $对象1; 时, 只是生成别名), 在副本对象中, $this 指副本对象, $that 指原对象
    __autoload: 每当使用某个类名时, 自动将类名作为参数传递给此方法, 可以在函数体内加上包含此文件的语句: include_one "./func/".$className.".class.php";
    __sleep: 在序列化时自动调用, 将对象部分序列化, 不加该方法则全部序列化
    __weakup: 在反序列化时自动调用
## 序列化和反序列化 ##
序列化的作用是将对象长时间存储在数据库或文件中, 或者是在多个 PHP 文件中传输

----------
    序列化: serialize()
    反序列化: unserialize()
## 抽象方法 ##
- 抽象方法: 没有方法体, 使用 abstract 修饰的方法
- 抽象类
> - 类中有抽象方法, 用 abstract 修饰的类
> - 抽象类和普通类相比, 多了抽象方法和类修饰词而已
> - 抽象类不能实例化, 只有继承后实现抽象方法, 实例化才有意义
- 除非使用了自动加载, 否则一个类必须在使用之前被定义。如果一个类扩展了另一个, 则父类必须在子类之前被声明。此规则适用于类继承其它类与接口。

## 接口 ##
- 接口是方法全为抽象方法、属性全为常量、访问权限全为 public 的抽象类, 具有抽象类的所有特征
- 接口的类名不是使用 abstract 修饰, 而是使用 interface 修饰, 接口内的方法默认都是抽象方法, 不需要使用 abstract 修饰
- 接口的出现是间接实现多继承, 一个类只能继承一个类, 但可以实现多个接口, 同时存在父类和接口时, 先继承后实现接口
- 接口的实现和继承(重写了接口方法就是实现, 没有就是继承)

----------
    interface one
    {
        const TAG = 'ONE';
        function f1();
    }
    interface two
    {
        const TAG = 'TWO';
        function f2();
    }
    interface three extends one
    {
        const TAG = 'THREE';
        function f3();
    }
    class Person implement one, two
    {
        ...
    }
## 关系 ##
- 抽象类是特殊的类, 接口是特殊的抽象类
- 两者作用相同, 都不能创建对象, 都需要靠子类去实现方法

## 多态 ##
- 简单理解: 赋值号左右两边类型不同且具有继承关系, 就是多态
- 多态的基础是具有继承关系的两个类中, 子类可以赋值给父类

## Trait 特性 ##
Trait 是用来混入类内使用的, 不能单独使用, 也不能实例化, 支持抽象方法、类定义静态方法、定义属性等。在类中使用 Trait 时, 相当于将 Trait 的成员拷贝到类中, 在应用时就像使用类自己的成员一样。
### 在类中使用 Trait ###

----------
    class Demo
    {
        use Trait1, Trait2;
    }
当两个 Trait 中具有同名方法时, 为防止歧义, 需要使用 insteadof 声明使用哪一个方法。

----------
    class Demo
    {
        use Trait1, Trait2
        {
            // 声明使用 Trait1 中的 func 方法
            Trait1::func insteadof Trait2::func;
        }
    }
### 注意事项 ###
- Trait 会覆盖调用类继承的父类方法
- 从基类继承的成员被 Trait 插入的成员所覆盖。优先顺序为: 当前类的成员 > Trait 中的方法 > 被继承的方法
- Trait 不能像类一样使用 new 实例化对象
- 单个 Trait 可以由多个 Trait 组成
- 在单个类中, 用 use 引入 Trait, 可以引入多个 Trait



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|php中文网 | cnphp.com

GMT+8, 2021-6-25 21:37 , Processed in 0.029967 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表