~~~~ 有胆量你就来跟着路老师卷起来! -- 纯干货,技术知识分享 ~~~~
路老师给大家分享PHP语言的知识了,旨在想让大家入门PHP,并深入了解PHP语言。
编辑
1 PHP对象的高级应用
1.1 final关键字
final 最终的、最后的。被final修饰过的类和方法就是“最终的版本”。被修饰的类不可以被继承,也不能有子类。被修饰的方法不可以被重写,也不可以被覆盖。
<?php /*** * 定义抽象类Book */ final class Book{ const NAME= 'computer';//定义常量NAME /** * 定义构造方法 */ function __construct(){ echo "本年度图书类冠军为:".Book::NAME."<br>"; } } class BookRank extends Book{ const NAME = 'foreign language'; function __construct(){ parent::__construct(); echo '本月图书类冠军为:'.self::NAME.''; } } $obj = new BookRank(); ?>
会出现final无法被继承的异常信息:
编辑
1.2 抽象类
抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。抽象类使用abstract关键字来声明,格式如下:
//抽象类 abstract class AbstractName{ //类体 //抽象方法 abstract function abstractFunctionName(); }
注意:
抽象类和普通类相似,包含成员变量、成员方法。两者的区别在于,抽象类至少包含一个抽象方法。
抽象方法没有方法体,其功能的实现只能在子类中完成。抽象方法也是使用abstract关键字来修饰的。在抽象方法后面要用分号结尾“;”。
抽象类和抽象方法主要应用于复杂的层次关系中,这种层次关系要求每一个子类都包含并重写某些特定的方法。
下面是商品抽象类及其子类的实现:
<?php /*** * 商品抽象类 */ abstract class CommodityObject{ //抽象方法 abstract function service($name,$price,$num); } class Books extends CommodityObject{ function service($name,$price,$num){ echo '商品是:'.$name.'---该商品的价格是:'.$price.'元'; echo "<br>"; } } class Computers extends CommodityObject{ function service($name,$price,$num){ echo '商品是:'.$name.'---该商品的价格是:'.$price.'元'; echo "<br>"; } } $books = new Books(); $computers = new Computers(); $books->service('PHP教程基础',30,5); $computers->service('戴尔计算机',5030,20); ?>
编辑
1.3 接口使用
继承特性简化了对象、类的创建,增强了代码的可重用性。可是PHP只支持单继承。如果想实现多重继承,就要使用接口类。接口类通过interface关键字来声明,并且类中只能包含未实现的方法和一些成员变量,格式如下:
//接口类 interface InterfaceName{ //接口方法 function interfaceFunctionName1(); function interfaceFunctionName2(); }
注意:不要用public以外的关键字来修饰接口中的类成员,对于方法,不写关键字也可以。这是由接口类自身的属性决定的。
子类是通过implements关键字来实现接口的,如果要实现多个接口,那么每个接口之间应使用逗号“,”连接,而且所有未实现的方法需要在子类中全部实现,否则将出现错误。
class SubClass implements InterfaceName1, InterfaceName2{ function interfaceFunctionName1(){ //功能实现 } function interfaceFunctionName1(){ //功能实现 } // ... }
会员和管理员权限案例:
<?php /** * 职位 */ interface MPopedom{ function popedom(); } /** * 权限 */ interface MPurview{ function purview(); } class Member implements MPurview{ function purview(){ echo "会员全部权限"; } } class Manager implements MPurview,MPopedom{ function popedom(){ echo "管理员-职位权限"; } function purview(){ echo "管理员-全部权限"; } } $member = new Member(); $manager = new Manager(); $member->purview(); echo "<br>"; $manager->purview(); echo "<br>"; $manager->popedom(); ?>
编辑
1.4 对象类型检测
instanceof操作符可以检测当前对象是属于哪个类。一般格式如下:
ObjectName instanceof ClassName
<?php class SprotObject{} class Books extends SprotObject{ private $type; } $c_book = new Books(); if($c_book instanceof Books) echo '对象$c_book属于Books类<br>'; if($c_book instanceof SprotObject) echo '对象¥c_book属于SportObject类<br>'; ?>
编辑
1.5 魔术方法(__)
PHP中有很多两个下划线开头的方法,比如构造方法__construct()方法,这些方法被称为魔术方法。当然不是他们真的会魔术,而是指在创建类的时候PHP自动包含的一些方法。
注意:PHP中保留了所有以"__"(双下划线)开头的方法,因此只能使用PHP文档中已经有的方法而不能创建。
1.5.1 __set()和__get()方法
__set()给变量赋值的方法,当程序试图写入一个未定义或者不可见的成员变量时,就会调用该方法。这个方法包含两个参数,第一个参数是变量名称,第二个参数是变量值,两个参数不能省略。
__get()方法是程序调用一个未定义或者不可见的成员变量时执行的,该方法参数只有一个就是被调用的变量名。
<?php class Student{ private $a; private $b = 0; public $c; public $d = 0; public function __get($name){ return 123; } public function __set($name, $value) { echo "这是 set 方法<br>"; } } $s = new Student(); echo "<pre>"; var_dump($s->a);//输出int(123) 私有变量调用get方法返回123 var_dump($s->b);//输出int(123) 私有变量调用get方法返回123 var_dump($s->c);//输出NULL 公有变量未赋值 返回NULL var_dump($s->d);//输出int(0) 公有变量赋值了,返回赋值结果 0 var_dump($s->e);//输出int(123) 未定义变量 和私有变量相同处理调用get方法返回 123 $s->a = 3;//输出 这是 set 方法 私有变量调用set方法 $s->c = 3;//已定义的公有变量不会调用get set方法,直接赋值 $s->f = 3;//输出 这是 set 方法 未定义的f和私有变量输出相同 ?>
注意:
1.公有变量可以直接调用和赋值,调用通过"->",赋值通过"="号,不会调用__get 和__set方法。比如$c和$d。
2.私有变量只能是类内部使用,因此调用和赋值的时候分别会调用__get 和__set方法。比如$a和$b。
3.未定义的变量按照私有变量处理。比如$e和$f。
1.5.2 __call()方法
当程序试图调用不存在或者不可见的成员方法时,PHP会先调用__call()方法来存储方法名及其参数。__call()方法包含两个参数,即方法名和方法参数(以数组形式存在)。
<?php class Exam{ public function myDream(){ echo '调用的方法myDream存在,直接执行此方法。<br><br>'; } public function __call($method, $parameter){ echo '方法不存在,执行__call方法。<br>'; echo '方法名为:'.$method.'<br>'; echo '参数有:'; echo '<pre>'; print_r($parameter); } } $exam = new Exam(); $exam->myDream();//调用存在的方法 $exam->myDream2('how','what','nb');//调用不存在的方法 ?>
编辑
1.5.3 __toString()方法
当使用echo或者print输出对象时,将对象转换成字符串。
<?php class Exam{ private $type = 'EXAM'; public function __toString(){ return $this->type; } } $exam = new Exam(); echo '对象$exam的值为:'; echo $exam; ?>
编辑
1.5.4 spl_autoload_register方法
通常使用include()函数或者require()函数在一个PHP文件中引入类文件。如在index.php文件中引入类A,代码如下:
<?php require('A.php');//引入类 $a = new A();//实例化类A ?>
但是多数情况下程序中需要引入很多的类,就不能一个个利用require引入了,为了解决这个问题从PHP开始便引入了spl_autoload_register方法,该方法可以自动实例化需要使用的类,当程序需要用到一个类,但该类还没有被实例化,PHP7会使用spl_autoload_register方法在指定的路径下自动查找和该类名称相同的文件。如果找到,程序继续执行,否则报告错误。
下面例子实现spl_autoload_register自动加载
创建两个文件StudyObject.php和SportObject.php以及1个index.php,然后使用spl_autoload_register方法实现自动加载。
//index.php <?php function loadPrint($class_name) { $class_path = $class_name.'.php'; if(file_exists($class_path)) { include_once($class_path); //动态包含类文件 } else { echo "类路径错误,文件可能不存在!"; } } spl_autoload_register('loadPrint'); $study = new StudyObject(); echo $study->cont; echo '<br>'; $str = "爱江山更爱美人!"; $sport = new SportObject($str); echo $sport; ?>
<?php class SportObject{ private $cont; public function __construct($cont){ $this->cont=$cont; } public function __toString(){ return $this->cont; } } ?>
<?php class StudyObject{ private $cont; public function __get($name){ return "江山代有才人出,各领风骚数百年!"; } } ?>
编辑
下篇文章面向对象的应用。