面向对象

类是得到对象的一种方法,所以想要得到对象必须先有类。

对象、属性、方法

class Student{

}

类里面应该有属性、方法、类常量。

类常量public $num;

类常量可以有非计算的默认值

方法可以不写public,是默认。

类的实例化

利用类得到对象的过程就是类的实例化

$student =  new Student;
$name = $student->name;

instanceof判断某个对象是否由某个类实力化而来

$stu instanceof Student

$this关键字

当前类的当前对象

为什么打印对象的时候只有属性被打印出来

属性归具体的对象管理

方法由类进行管理

构造方法

在new一个对象的同时,自动的调用初始化属性的方法,在实例化一个对象的时候,PHP会自动的调用一个名字叫作__construct()的方法

析构方法

析构方法是在一个对象“销毁”(消失)的时候由系统自动调用!

析构方法的名字为:__destruct(),注意该方法里面不能有任何的参数!

作用不是为了删除一个对象,而是为了释放该对象所占用的额外资源

析构方法在对象消失之前调用

对象的传值与克隆

对象的变量名引用的是对象的内部编号,值传递的时候,只是赋值这个内部编号。没有开启一个新的对象空间,所以说是"浅复制"。

对象的克隆

赋值无法获取新的对象,只有通过克隆,通过一个对象得到一个新的对象

新对象 = clone 已有的对象

克隆不是实例化,不能触发构造方法,为了与旧对象做区分,用到__clone(),克隆的时候自动调用此方法。

静态属性

class Student{
  public static $stu_num = 0;
}

属于所有的对象共有的成员,类来管理

public \ protected \private static 属性名

静态属性的访问

类名:静态属性名,Student::$stu_age;,因为归类管理,不属于某个对象,所以无法使用对象直接访问静态属性。类的内部可以使用self。

静态方法

所有对象共享的方法,类来管理,public static function showNum(){},不能使用$this这个方法,因为static静态方法本来就是公共的方法.

$this关键字本身就体现了各个对象。类调用静态属性,对象调用非静态属性

self、static、$this的区别?

类常量

类中的一个常量,const CLASS_ID='610'

类管理,Student::CLASS_ID

类中的成员

静态属性

非静态属性

静态方法

非静态方法

类常量

类空间:静态属性、类常量

对象空间:非静态属性

用户代码区:非静态方法、静态方法

自动加载机制

  • 按需

  • 自动

    PHP在执行的时候,发现需要一个类,当前脚本没有,会调用__autoload会给该喊出传递一个参数,当前需要的类的类名。(所以强调类名的一致性,通过类名能找到类文件)

注册其他的自动加载函数

  1. 定义一个可以加载类文件的普通函数

  2. 将该普通的函数注册成自动加载函数

    spl_autoload_register(函数名);

注意:

  • 函数的注册一定要发生在需要某个类之前
  • 一旦注册了其他的自动加载函数,那么系统默认的__autoload()函数就失效了!如果想继续使用,必须像注册其他普通函数一样,重新的进行注册!

注册非静态方法

首先,要实例化一个对象出来

其次,spl_autoload_register函数的参数为一个索引数组,该数组里面只有两个元素,第一个元素为一个对象变量,第二个元素为方法名!

注册静态方法

此时,spl_autoload_register函数的参数为一个索引数组,该数组里面只有两个元素,第一个元素为一个类名,第二个元素为方法名!

数据的序列化和反序列化

为什么需要序列化和反序列化

因为文件中只能保存字符串,当写入的内容是false,取到的时候会是空字符串。这样就没有保障数据的原样输出。

序列化 serialize()

反序列化unserialize()

不能序列化资源类型,因为是外部数据,在变化的,也没有意思保存。其中,session和cookie的区别,在于session能保存除了资源类型外的所有类型,cookie只能保存字符串,就因为session有序列化和反序列化。

__sleep()

序列化的时候,存在不想被序列化的数据(资源类型),用到__sleep()

序列化一个对象的时候由系统自动调用!

作用:该方法用于规定哪些属性应该被序列化,实现的方式为:返回一个索引数组,数组内的元素为需要被序列化的属性名的集合!

__wakeup

触发时机:在反序列化一个对象的时候自动触发!

作用:就是在反序列化一个对象的时候,对该对象进行一系列的初始化操作!

类的三大特性

封装性、继承性、多态性

子类实例化出来的对象也同时是其父类的一个实例

几个概念

继承:一个类从另一个已有的类获得其成员和特性,就是继承!

派生:从一个已有的类产生一个新的类,叫作派生!

注意:继承和派生其实是从不同的方向来描述的一个概念,本质上是一样的!

父类:也叫作基类,就是指以后的那个被继承的类

子类:也叫作派生类或扩展类

扩展:在子类中增加一些自己特有的特征信息(属性、方法和类常量),没有扩展,继承也就没有任何的意义!

单继承:==一个类只能继承自一个其他的类==,不能继承多个类,单继承也是大多数面向对象的语言的特性(C++就是多继承)

重写override

重写也叫作覆盖,就是指当子类成员和父类成员名字相同的时候,从父类继承下来的成员就会重新定义!

代码描述
class A,classB分别都有function C (输出当前类的属性)
class B 继承 classA

实例化B,重新赋值,
调用function c 会输出class B的属性

重写机制是由继承链来决定的,子类找到了就不会再在父类中找

如果要强制性执行父类的同名方法,需要显式调用 父类名::父类方法名

Parent关键字

相对于self代表的当前所属类的类名,parent关键字代表的是其父类的名字!通常用于在子类中调用父类的成员的时候使用!

可能是父类,也可能是父类的父类

访问控制修饰符

PHP中一共三个访问范围:

  1. 当前类内
  2. 继承连类内
  3. 类外
public:公开的,当前类内,继承链类内以及类外都可以访问
protected:受保护的,当前类内,继承链类内可以访问
private:私有的,只有当前类内可以访问

访问控制修饰符:public private protected

注意点:

子类重写父类的成员的时候,子类的访问控制符的作用范围不低于父类

父类 public 子类 只能是public

父类 protected 子类是 public protected

final最终类和abstract抽象类

类的两个功能

  1. 被继承
  2. 实例化对象

final类:最终类,不能被继承,只能实例化对象

abstract类:抽象类,不能实例化,只能被继承

抽象类,不同的对象实现相同的动作的时候有多种形态(方法)!我们可以在类中规定一些必须要完成的动作(方法),但是不去完善方法体(因为不同的对象实现这个动作的方式不一样),这种方法就叫作抽象方法(不完整的方法)

简单说,抽象类就是包含了抽象方法的类,

abstract class Animal{
    publilc function move();
}

继承抽象方法的子类,要么继续做抽象类,要么实现父类中所有的抽象方法。==面向对象的多态性==

interface接口

接口就是一个对象对外的公共的操作方法!规定该接口的下级类必须要实现的公共的方法!

接口常量:其实就是普通的常量,只不过是出现在接口里面而已!

抽象方法:必须声明为public,不需要有abstract关键字

一般来说,接口的名字以大写字母I开头!接口不是类!只是类的一种规范!

接口的实现

class Person implements I_animal{
  public function move();
  const PI =3.14;
}

接口与抽象类的比较

1, 从逻辑上看,==接口可以看成是抽象类的一个“子集”,接口比抽象类更“抽象”,都可以规定下级类的内部结构,只是接口中只能有公开的抽象方法和接口常量==

2, 接口不是类,而只是类的一种规范,类又是对象的一种规范,但是抽象类是类!

3, PHP不支持多继承,但是支持多实现,也就是说,==一个类可以同时实现多个接口!这也是接口与抽象类的最本质的区别!注意:当一个类实现多个接口的时候,要么实现所有接口中的所有的抽象方法,要么就只能做抽象类!==

overload重载简介

指的是对不可访问的成员的处理,称之为成员的重载!

  1. 成员不存在
  2. 成员声明成了private、protected,无权限

也就是说,为一个不存在的属性赋值的时候,PHP默认是支持将该属性重新载入到当前对象内部的!这种现象就称之为属性的重载!

属性重载

  1. 为不可访问的属性赋值的时候:__set()
  2. 获取不可访问的属性的时候:__get()
  3. 删除不可访问的属性的时候:__unset()
  4. 判断不可访问的属性是否存在的时候:__isset()

方法重载

处理不可访问的方法!

利用两个魔术方法来完成:

__call():当调用一个不可访问的对象方法(非静态方法)的时候,会自动的执行该魔术方法!

__callstatic():当调用一个不可访问的静态方法,会自动的执行该访问,需要在方法的前面加上static

魔术方法和魔术常量

魔术方法

名字由系统定义,而方法体由用户定义的方法!

最大的特点是:不需要用户手动调用,而是当特点的情况方法的时候,系统会自动的调用!

总结,目前,一共学习了哪些魔术方法:

__construct()

__destruct()

__clone()

__sleep()

__wakeup()

__set()

__get()

__unset()

__isset()

__call()

__callstatic()

__invoke()

当把对象当成一个函数(或方法)来使用的时候,会自动的调用该魔术方法,目前使用的不是很多!

__toString()

触发条件:将对象当成是一个字符串来使用的时候,会自动的触发该魔术方法,该方法的返回值,一般就是对象转换为字符串的结果!

面试题

1,$this是不是永远代表当前代码所在类直接实例化出来的对象?

不是!$this的值是根据执行环境来决定,有可能向上或者向下传递!

2,==self是不是永远代表当前代码所在的类==?

于是需要static,来完成,当前类,而不是self所在的类。

static的三个功能

  1. 函数中的静态属性
  2. 当前类
  3. 定义类中的静态成员

总结:目前代表类的关键字有几个?

==一共有三个:==

self:当前类,绑定(确定)类名的时机发生在代码的预编译阶段

static:当前类,绑定(确定)类名的时机发生在代码的执行阶段

parent:父类

单例模式

只需要实例化出来一个对象就可以完成所有的功能!一个典型的类就是数据库工具类!所以,如果我们能够通过某些技巧,使得==一个类只能开辟一个对象==空间的话,就可以节省相应的对象资源,这种模式就叫作单例模式!

  1. 防止用户通过new关键字无限实例化对象(==构造方法私有化==)
  2. 增加一个静态的公共方法,进入到类的内部(静态方法:还没有对象,用类访问,公共方法,类外调用) (如何防止用户无限调用,判断当前静态属性里保存的是不是由当前类实例化而来的,如果不是,才返回对象)
  3. 为当前类增加一个私有的静态属性(类来访问,类外无法修改属性的值)
  4. 私有化克隆方法(防止克隆)

工厂模式

:设计一个类(此时这个类就叫作工厂类),该类的作用就是帮助其他的类“生产”对象(实例化对象),也就是说,==只要传递给这个“工厂”一个类名,就可以得到一个相应的对象!==

约束类型

形参约束为$int,$array,$obj

类和对象的相关函数

class_exists()

类是否存在

interface_exists()

接口是否存在

method_exists()

方法是否存在

get_class()

获得对象所属的类!

get_parent_class()

获得对象的父类!

get_class_methods()

获得一个类的所有的方法名,返回一个数组!需要一个参数是类名!

get_class_vars()

获得一个类的所有的属性!

is_object()

命名空间

电脑中相同文件名的文件,需要文件夹放到不同的空间,同理,代码中相同方法、属性,需要空间划分开。

namespace 空间名字;

子空间

目录:A/B/C,其中C就是B目录的子目录,而B又是A目录的子目录

空间:namespace A\B\C,其中C空间就是B空间的子空间,而B空间又是A空间的子空间(注意使用反斜杠\),其表示的含义是,创建了一个名字为C的子空间,同时A和B空间也一起创建了!

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!