类与对象 访问修饰限定符 继承与重写 自动加载 异常处理 抽象类与接口 项目四 面向对象网站开发 类与对象 访问修饰限定符 继承与重写 自动加载 异常处理 抽象类与接口
目录 体验类与对象 面向对象三大特征 魔术方法 静态工具类 自动加载 异常处理 抽象类与接口 任务一 任务二 任务三 任务四 任务五 任务六 任务七 抽象类与接口
项目描述 在前面的章节中,要解决某个问题都是通过分析解决问题需要的步骤,然后用函数把这些步骤一一实现,在使用的时候依次调用这些函数就可以了,这种解决问题的方式称之为面向过程编程。 但在程序开发过程中,为了使程序代码更加符 合人类逻辑思维,去处理现实生活中各种事物 之间的联系,在程序中则利用对象来映射现实 中的事物,使用对象的关系来描述事物之间的 联系,即面向对象编程。 接下来,本项目将利用面向对象的方式,以员 工信息管理为依托,完成相应的操作,由浅入 深的了解和掌握面向对象编程和面向过程编程 的差异和乐趣。
任务 说明 任务一:体验类与对象 声明一个员工类,用于描述员工的姓名和年龄,并实现员工进行自我介绍的动作。 定义成员属性,用于描述员工的姓名和年龄。 定义成员方法,用于实现员工的自我介绍“大家好,我叫XXX,今年XX岁!”。 创建两个员工对象,分别为各自的属性赋值,并调用成员方法。
任务一:体验类与对象 引入知识点 1、面向对象概述 2、类与对象的关系 3、类的定义与实例
任务一:体验类与对象 面向对象概述 无脊椎动物 青蛙 蜥蜴 动物 脊椎动物 鸟 鱼
任务一:体验类与对象 面向对象概述 现实生活中存在各种形态的事物,这些事物之间存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象。
任务一:体验类与对象 面向对象概述 (1)封装性 封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节,这就是封装思想。 (2)继承性 继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。 (3)多态性 多态性指的是同一操作作用于不同的对象,会产生不同的执行结果。
任务一:体验类与对象 引入知识点 1、面向对象概述 2、类与对象的关系 3、类的定义与实例
任务一:体验类与对象 设计图纸 汽车 汽车 汽车 类与对象的关系 类是对某一类事物的抽象描述,对象则是该类事物实际存在的个体。 例如:汽车与设计图纸之间的关系。 设计图纸 汽车 汽车 汽车
任务一:体验类与对象 引入知识点 1、面向对象概述 2、类与对象的关系 3、类的定义与实例
任务一:体验类与对象 类的定义 类是由class关键字、类名和成员组成 成员包括(成员)属性和(成员)方法 属性用于描述对象的特征 方法用于描述对象的行为
任务一:体验类与对象 类的定义 类名不区分大小写,即大小写不敏感。 推荐使用大驼峰法命名,即第一个单词首字母大写。 例如:Student、student、sTudent等都表示同一个类 推荐使用大驼峰法命名,即第一个单词首字母大写。 例如:ClassName 类名要见名知意,方便阅读和维护程序。 例如:Model表示模型类
任务一:体验类与对象 类的实例 在PHP程序中,类创建完成后,若想要完成具体的功能,还需要使用new关键字来创建对象。 “$对象名”表示一个对象的引用名称,通过这个引用就可以访问对象中的成员。 “$”符号是固定写法,对象名是自定义的,命名规则与标识符相同。 “new”表示要创建一个新的对象 “类名”表示新对象的类型 “[参数1,参数2]”中的参数是可选的
任务一:体验类与对象 类的操作 在实例化对象后,就可以通过“->”来访问类中的成员属性和方法。 $对象名 ->成员 $对象名 -> 成员属性名 = '属性值';
任务一:体验类与对象 任务 实现
任务一:体验类与对象 补充 类的操作 为成员属性赋值,除了在声明类时,通过为成员变量赋值的方式初始化成员属性外,还可以通过以下方式: $对象名 -> 成员属性名 = '属性值'; 补充
任务 说明 任务二:面向对象三大特征 封装Employee类的属性,再次运行instance.php文件,观察结果。 Employee类使用构造方法完成对私有属性的赋值,在instance.php文件中,带参数实例化Employee类,接着调用introduce()方法,观察结果。 任务 说明 定义一个普通员工类和管理层员工空类,完成对Employee类的继承。调用并观察结果。 在普通员工和管理层员工类中,分别重写父类中的introduce()方法。调用并观察结果。
任务二:面向对象三大特征 1、访问修饰限定符 引入知识点 2、构造方法与析构方法 3、继承 4、重写
任务二:面向对象三大特征 访问修饰限定符 在PHP中,为了对类中成员的访问作出限制,提供了三种访问修饰符分别为public、protected和private。
任务二:面向对象三大特征 访问修饰限定符 public:公有修饰符,所有的外部成员都可以访问这个类的成员。如果类的成员没有指定访问修饰符,则默认为public。 protected:保护成员修饰符,被修饰为protected的成员不能被该类的外部代码访问,但是对于该类的子类可以对其访问、读写等。 private:私有修饰符,被定义为private的成员,对于同一个类里的所有成员是可见的,即没有访问限制,但对于该类外部的代码是不允许进行改变,对于该类的子类同样也不能 访问。
任务二:面向对象三大特征 1、访问修饰限定符 引入知识点 2、构造方法与析构方法 3、继承 4、重写
任务二:面向对象三大特征 构造方法与析构方法 构造方法的作用就是可以在实例化对象的同时就为这个对象的属性进行赋值,并且它会在类实例化对象时自动调用,用于对类中的成员进行初始化。 访问修饰限定符 function __construct(参数列表){ //初始化操作 }
任务二:面向对象三大特征 补充 构造方法与析构方法 与类同名的方法也被视为构造方法 这是早期PHP版本中定义构造方法的方式,PHP为了向前兼容,现在仍然支持这种方式。 补充
任务二:面向对象三大特征 构造方法与析构方法 与构造方法相对应的是析构方法,它会在对象被销毁之前自动调用,完成一些功能或操作的执行,例如,关闭文件、释放结果集等。 function __destruct(){ //清理操作 }
任务二:面向对象三大特征 1、访问修饰限定符 引入知识点 2、构造方法与析构方法 3、继承 4、重写
任务二:面向对象三大特征 继承 继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。
任务二:面向对象三大特征 爷爷 爸爸 儿子 继承 大眼睛 大眼睛 大眼睛 若儿子的眼睛长得与爸爸和爷爷的一样都是大眼睛 在生活中,我们则会使用遗传来表示这种缘故。 在程序中,我们则会使用继承来表示这种关系。
任务二:面向对象三大特征 继承 class 子类名 extends 父类名{ //类体 } extends关键字用于实现类的继承 子类会继承父类的所有公共成员和受保护的成员 子类不会继承父类的私有成员
任务二:面向对象三大特征 继承 在PHP中只能实现单继承,也就是说子类只能继承一个父类(是指直接继承的类),但一个父类可以被多个子类所继承。 注意
任务二:面向对象三大特征 1、访问修饰限定符 引入知识点 2、构造方法与析构方法 3、继承 4、重写
任务二:面向对象三大特征 重写 多态指的是同一操作作用于不同的对象,会产生不同的执行结果。在PHP中可以通过重写来实现多态效果,重写的过程很简单,只需要在子类中同样存在这个方法,并对方法体进行重新实现即可。
任务二:面向对象三大特征 重写 实例化子类Child,调用call()方法,请猜测输出结果。 输出结果:这里是子类!
任务二:面向对象三大特征 重写 重写方法的参数数量必须一致。 子类的方法的访问级别应该等于或弱于父类中的被重写的方法的访问级别。 注意
任务二:面向对象三大特征 任务 实现
任务 说明 任务三:魔术方法 修改任务二 在__set()方法中为Employee类中的私有属性赋值。 在__get()方法中获取Employee类中私有属性的值。
任务三:魔术方法 1、__set() 引入知识点 2、__get() 3、__clone() 4、__call()
任务三:魔术方法 __set() 所谓魔术方法就是以双下划线开头的方法。且魔术方法有一个特点就是不需要手动调用,它会在某一时刻自动执行,为程序的开发带来了极大的便利。
任务三:魔术方法 __set() __set()方法用于为当前环境下未定义或不可访问的成员赋值时被自动调用。 访问修饰限定符 function __set($name,$value){ //为$name赋值为$value } $name参数表示属性名 $value参数表示要给属性设置的值
任务三:魔术方法 1、__set() 引入知识点 2、__get() 3、__clone() 4、__call()
任务三:魔术方法 __get() 在PHP中,读取不存在的或被访问修饰符限制的成员属性时,程序就会自动调用__get()方法进行处理。 访问修饰限定符function __get($name){ //返回$name的值 } 参数$name表示需要获取的成员属性的名称。
任务三:魔术方法 1、__set() 引入知识点 2、__get() 3、__clone() 4、__call()
任务三:魔术方法 __clone() __clone()方法用于在使用clone关键字克隆对象时,完成对新对象的某些属性重新初始化的操作。 访问修饰限定符 function __clone(){ //重新初始化克隆新对象的某些属性 } __clone()方法没有参数
任务三:魔术方法 __clone() 对象的克隆分为深克隆和浅克隆 所谓深克隆就是对象属性如果为对象,则将其生成克隆副本。 所谓浅克隆(默认)就是仅仅将当前对象属性进行克隆操作,如果对象属性为对象,则不会做克隆工作。 $克隆对象名称 = clone $被克隆对象名称;
任务三:魔术方法 __clone()
任务三:魔术方法 1、__set() 引入知识点 2、__get() 3、__clone() 4、__call()
任务三:魔术方法 __call() 在PHP中,当调用一个不存在或不可访问的类属性和方法时,程序会自动调用重载方法__call()。 public __call ($name , $args){ //方法体 } 参数$name表示待调用的方法名称 参数$args表示调用方法的实参列表数组
任务三:魔术方法 __call() ① $b1调用私有成员方法directory()方法时,程序会自动调用__call()方法 ② 在__call()方法中利用list()函数将用户传递的参数分配给变量 ③ 在__call()方法中完成$f_name方法的调用,并传递参数
任务三:魔术方法 __call() PHP新增了一个静态版重载方法__callStatic(),用于在静态方法被重载时,触发,其功能与__call()一致。 注意
任务三:魔术方法 任务 实现
任务 说明 任务四:静态工具类 设置两个私有的静态属性,用于保存用户传递的类文件名称和方法名称。 封装静态的方法,用于初始化静态工具类的属性。 编写一个公共的静态入口方法,完成类库的加载以及方法的调用。 编写一个入口文件,用于载入静态工具类,完成入口方法的调用。
任务四:静态工具类 1、静态成员 引入知识点 2、类常量 3、final关键字
任务四:静态工具类 静态成员 为了满足在程序开发中,有些数据在内存中只有一份,但又被类的所有实例对象所共享的需求。因此,PHP提供了静态成员,即静态(成员)属性和静态(成员)方法。
任务四:静态工具类 静态成员 访问修饰限定符 static 变量名 访问修饰限定符 static function 方法名(){} 静态成员与普通成员之间的区别 定义时 唯一区别是多了static关键字。 使用时 静态成员是属于类的,使用时需要通过静态访问符 “::”来访问。 普通成员是属于对象的,使用时则需要“->”来访问
任务四:静态工具类 静态成员 静态成员访问方式 类名::静态成员 self::静态成员 static::静态成员 既可以在类的内部,又可以在类的外部访问本类的静态成员 self::静态成员 仅可以在类的内部访问本类的静态成员 static::静态成员 既可以在本类内又可以在其父类中访问静态成员
任务四:静态工具类 静态成员 实际上实例化的对象也能够访问静态成员。但是在实际开发中并不提倡这种用法,一般而言对象用来调用非静态方法,类用来调用静态方法。 注意
任务四:静态工具类 1、静态成员 引入知识点 2、类常量 3、final关键字
任务四:静态工具类 类常量 在PHP中,类内除了可以定义成员属性、成员方法、静态成员属性、静态成员方法外,还可以定义类常量。 所谓类常量,就是在类中使用const关键字定义的常量
任务四:静态工具类 类常量 const 类常量名 = '常量值'; 类常量命名规则与变量名一致,但习惯上通常把类常量名以大写字母表示。 类常量 “类名::常量名称”的方式进行访问。其中“::”称为范围解析符,简称双冒号。 类常量不仅可以在语法上限制数据不被改变,还可以简化说明数据,方便开发人员的阅读与数据的维护。
任务四:静态工具类 1、静态成员 引入知识点 2、类常量 3、final关键字
任务四:静态工具类 final关键字 PHP中的继承特性给项目开发带来了巨大的灵活性,但有时在开发中,要保证某些类或某些方法不能被改变。此时,就需要使用final关键字。 final关键字有“无法改变”或者“最终”的含义,因此被final关键字修饰的类不能被继承以及被final关键字修饰的方法不能被重写。
任务四:静态工具类 final关键字 当希望某个类不能被继承,只能被实例化时,就可以通过final关键字来声明。
任务四:静态工具类 final关键字 在程序开发中,若要求在子类中一定会存在某个功能一样的方法,则可以使用final关键字修饰该方法。
任务四:静态工具类 任务 实现
任务五:自动加载 在开发中,由于业务越来越复杂,一个脚本中需要加载的类库文件越来越多。因此采用手动载入类文件,或在一个文件中完成所有文件的定义皆有局限性。 针对这种情况,下面请利用PHP提供的自动加载机制完成静态工具类库的自动加载。 任务 说明
任务五:自动加载 引入知识点 1、自动加载 2、自定义加载
任务五:自动加载 自动加载 引入文件的方法:直接使用include和require方法将类文件包含进来。 但在项目开发中,使用此种方式不仅会降低效率,且会使代码难以维护。 如果不小心忘记引入某个类的定义文件,PHP就会报告一个致命错误,导 致整个应用程序崩溃。
任务五:自动加载 自动加载 解决办法:PHP提供了类的自动加载机制,即魔术方法__autoload(),它能 够方便地实现类库的自动加载,运用该方法可以在实例化对象之前自动加载 指定的类文件。 在方法体中,可以根据不同文件存放规则,实现更为复杂的自动加载机制。
任务五:自动加载 自动加载 __autoload()函数只有在试图使用未被定义的类时自动调用 本书中所有需自动加载的类与类库文件名相同
任务五:自动加载 引入知识点 1、自动加载 2、自定义加载
任务五:自动加载 自定义加载 在编程中,运用自动加载方法__autoload()虽然简单易用,但却不是很灵活。 因此,PHP提供了一种用户自定义加载的机制,首先需创建一 个自定义加载函数,然后再使用spl_autoload_register()函数将 其注册到SPL __autoload函数栈中,使其成为自动加载函数。
任务五:自动加载 自定义加载 用户自定义函数,规定加载函数的规则 将自定义函数注册为自动加载函数
任务五:自动加载 任务 实现
任务 说明 任务六:异常处理 为员工信息添加操作设置异常处理 当获取的员工信息为空时,请使用throw关键字抛出Exception异常,并设置异常提示信息。 请在静态工具类Framework中进行异常的捕获和处理。
任务六:异常处理 1、异常的处理 引入知识点 2、自定义异常 3、多个catch块
任务六:异常处理 异常的处理 异常处理与错误的区别在于异常定义了程序中遇到的非致命性的错误。 例如: 程序运行时磁盘空间不足,网络连接中断,被操作的文件不存在等。
任务六:异常处理 异常的处理 异常处理 使用try{}包裹可能出现异常的代码 使用throw关键字来抛出一个异常 利用catch捕获和处理异常
任务六:异常处理 1、异常的处理 引入知识点 2、自定义异常 3、多个catch块
任务六:异常处理 自定义异常 虽然PHP中提供了处理异常的类Exception,但在开发中,若希望针对不同 异常,使用特定的异常类进行处理,此时就需要创建一个自定义异常类。 自定义异常类非常简单,只需要继承自Exception类,并添加自定义的成员 属性和方法即可。
任务六:异常处理 自定义异常 自定义异常类 CusException
任务六:异常处理 1、异常的处理 引入知识点 2、自定义异常 3、多个catch块
任务六:异常处理 多个catch块 实际上,对于同一个脚本异常的捕获,不仅可以使用一个try语句对应于一个 catch语句,还可以使用一个try语句对应于多个catch语句,用来检测多种 情况。并且这些异常能够使用不同的异常类,返回不同的错误消息。
任务六:异常处理 多个catch块 多个catch块
任务六:异常处理 任务 实现
任务 说明 任务七:抽象类与接口 利用PHP提供的接口和抽象方法实现员工通信接口的定义与实现。 定义通讯接口(ComInterface),完成通讯的连接,数据传输,和断开连接。 定义手机类(MobilePhone)实现(implements)通讯接口,完成必要功能的实现。
任务七:抽象类与接口 1、抽象类与抽象方法 引入知识点 2、接口的定义与实现
任务七:抽象类与接口 抽象类与抽象方法 在网站开发中,经常需要为一个类定义一些方法来描述该类的特 征,但同时又无法确定该方法的实现,例如,动物都会叫,但是 每种动物叫的方式又不同。 因此,可以使用PHP提供的抽象类和抽象方法来实现。
任务七:抽象类与接口 抽象类与抽象方法 abstract class 类名{ //抽象方法的定义 abstract function 方法名(); } 使用abstract修饰,只有方法声明而没有方法体的特殊方法称为抽象方法,该方法需要在子类继承时再编写该方法的实现。
任务七:抽象类与接口 抽象类与抽象方法 抽象类不能被直接实例化,必须先继承该抽象类,然后再实例化子 类。且抽象类中如果有抽象方法,则子类必须实现抽象类中的所有 抽象方法。 另外,这些方法的访问权限必须和抽象类中一致或者更为宽松。 例如:抽象类中某个抽象方法被声明为protected,那么子类中实现 的方法就应该声明为protected或者public,而不能定义为private。
任务七:抽象类与接口 1、抽象类与抽象方法 引入知识点 2、接口的定义与实现
任务七:抽象类与接口 接口的定义与实现 如果说抽象类是一种特殊的类,那么接口又是一种特殊的抽象类。 若抽象类中的所有方法都是抽象的,则此时可以使用接口来定义, 就像定义一个标准的类一样。
任务七:抽象类与接口 接口的定义与实现 interface 接口名{ public function 方法名(); }
任务七:抽象类与接口 接口的定义与实现 接口中的方法都是抽象方法,没有具体实现。因此需要使用 implements关键字来实现。
任务七:抽象类与接口 接口的定义与实现 class 类名 implements 接口名{ //需要实现接口中的所有方法 …… } 类中必须实现接口中定义的所有方法,否则会报一个fatal错误。 如果要实现多个接口,可以用逗号来分隔多个接口的名称。
任务七:抽象类与接口 任务 实现