面向对象的PHP
2016-04-27 18:16
513 查看
面向对象的PHP
OOP的好处
OOP的三个基本概念:封装,继承,多态。封装
通过众所周知的接口将用户与实际应用程序的内部工作原理分离,这种方法叫做封装。通过这些定义良好的接口进行交互的组件称为对象,对象是通过一个称为类的模板创建的,类用于定义某个实体所应具有
的数据和行为。
继承
通过类来继承,子类会继承父类的所有性质和行为。多态
多态是指OOP能够根据使用类的上下文来重新定义或改变类的性质或行为。关键的OOP概念
在OOP术语中,实体的性质和行为的具体定义称为类(class)。每个实体都包含了一组性质和行为,在OOP中分别称为字段(field)和方法(method)。
类
对象
字段
字段作用域public //OOP中不鼓励使用公共字段,直接访问公共字段使得类无法很容易的完成数据验证。两种办法,公共方法和属性。 private //私有的字段不能由实例化的对象直接访问,也不能由其子类使用。必须通过公共接口来访问。 protected //只能在类内部使用的子段,同时,在继承的子类中也可以访问和操作保护字段 final // 当为字段设置final作用域时,将阻止在子类中覆盖这个字段
属性
通过强制在方法中访问和操作字段,一方面能够保护字段,同时还允许向访问公共字段一样访问数据。这些方法称为访问方法(accessor)和修改方法(
mutator),或非正式的称为获取方法(
getter)和设置方法(
setter)。他们将在访问或者操作字段的时候自动触发。
遗憾的是PHP5并没有提供属性功能,因此需要通过公共方法来模拟这种功能。例如,声明2个函数
setName()和
getName(),为属性
name分别创建获取和设置方法。
不过PHP5中提供了对属性的某种支持,这是通过重载
__set和
__get来实现的。当试图引用一个类定义中不存在的成员变量时,就会调用这种方法。
<?php class Employee{ private $name; public $title; function clockIn(){ echo "Member $this->name clocked in at ".date("h:i:s"); } function __set($p,$v){ $this->$p =$v; echo "nonexisten var: $p and $v"; } function __get($name) { $this->$name = $name; echo "这里是get" . $name; } } $a =new Employee(); echo "<pre>"; $a->clockIn(); $a->sex ="man"; $a->title = "funck"; echo json_encode($a); ?>
常量 constant
在类中可以定义常量,用来表示不会改变的值。class math{ const PI = '3.1415926'; }
方法
比字段多一种作用域 抽象(abstract)public private protected final abstract // 只能在父类中声明,但在子类中实现,只有声明为abstract的类可以声明为抽象方法 static
构造函数和析构函数
构造函数定义为对象实例化时自动执行的一段代码。- 构造函数可以接收参数,能够在创建对象时赋给特定的对象字段
- 构造函数可以调用类方法或其他函数
- 类的构造函数可以调用其他构造函数,包括父类的构造函数
析构函数:脚本执行结束时,PHP会撤销内存中所有的对象,因此,如果实例化的类和实例化时创建的信息都留在
内存中,就不需要显示声明析构函数。但是,如果实例化时创建了不那么容易丢失的数据(如存储在数据库中),就应当
在对象撤销时撤销这些数据,为此就需要创建一个定制的析构函数。
<?php class Book{ private $title; private $isbn; private $copies; function __construct($isbn)//构造函数 { $this->setIsbn($isbn); $this->getTitle(); $this->getNumberCopies(); //当然了,实际的实现可能需要一些更智能的get方法(例如查询数据库的方法)。 } function __destruct() //析构函数 { echo "book destroyed"; } function setIsbn($isbn){ $this->isbn = $isbn; } function getTitle(){ $this->title="Beginning Python"; print "title:".$this->title."<br/>"; } function getNumberCopies(){ $this->copies ="5"; print "copies:" . $this->copies."<bt/>"; } } class TecBook extends Book{ function __construct($isbn) { parent::__construct($isbn); //调用父类构造函数, //classname::__construct 调用无关的构造函数 } } $book = new Book("159059519X"); ?>
静态类成员
创建供所有类实例共享的字段和方法,这些字段和方法与所有的类实例有关,但不能由任何特定对象调用。<?php class Vistor { private static $visitors=0; function __construct() { self::$visitors++; } static function getVistors(){ return self::$visitors; } } $visits = new Vistor(); echo Vistor::getVistors(). "<br/>"; $visits2 = new Vistor(); echo Vistor::getVistors(); ?>
静态字段和方法应使用
self关键字和类型来引用,而不是通过this和箭头操作符。
instanceof关键字
判断一个对象是否是类的实例,类的子类还是实现了某个特定的接口,并进行了相应的操作。辅助函数
class_exists(); get_class(); get_class_methods(); get_class_vars(); get_declared_classes(); get_object_vars(); get_parent_class(); interface_exists(); is_a(); is_subclass_of(); method_exists();
自动加载对象
function __autoload($class){ require_once ("classes/$class.class.php"); }
高级OOP特性
PHP不支持的高级OOP特性
不支持 方法重载不支持 操作符重载
不支持 多重继承
对象的克隆
PHP4时,将对象视为另一种数据类型(按值传递),使得很多依赖于将对象作为引用传递给其他类方法的OOP方法无法使用。 PHP5更正了这个问题,现在所有对象在默认的情况下都被视为引用。所以为了让对象按值传递,PHP提供了一种克隆对象的显示方法。__clone()方法
可以在对象类中定义一个__clone()方法来调整对象的克隆行为。此方法的代码将在克隆操作期间执行。
class Corporate_Drone { private $employeeid; private $tiecolor; function __clone() { $this->tiecolor="blue"; } function setEmployeeID($employeeid){ $this->employeeid = $employeeid; } function getEmplyeeID(){ return $this->employeeid; } function setTieColor($tiecolor){ $this->tiecolor=$tiecolor; } function getTieColor(){ return $this->tiecolor; } }
继承
在PHP中,类继承通过extends关键字实现。
继承和构造函数
如果父类有构造函数,而子类没有。那么在子类实例化时,确实会执行父类的构造函数。
但是,如果子类也有构造函数,那么当子类实例化时,不论父类是否有构造函数,都会执行子类
自己的构造函数。
如果子类有构造函数,但也希望执行父类或者其他类中的构造函数可以使用如下语句。
parent::__construct()
classname::__construct
接口 interface
接口定义了实现某种服务的一般规范,声明了所需的函数和常量,但不指定如何实现。常量需要通过
classname::constname使用。
接口也可以继承。同时一个类也可以实现多个接口
抽象类 abstract
抽象类和普通类一样可以定义字段和方法。只是抽象类是不能实例化的类,只能作为由其他类继承的基类。抽象类和接口的选择
1. 如果要创建一个模型,这个模型将由一些紧密相关的对象采用,就可以使用抽象类,如果要创建将由一些不相关对象采用的功能,就要使用接口。
2. 如果必须从多个来源继承行为,就使用接口。PHP类可以继承多个接口,但不能扩展多个抽象类。
3. 如果知道所有类都会共享一个公共的行为实现,就使用抽象类,并在其中实现该行为。在接口中无法实现行为。
相关文章推荐
- 推荐给开发者的11个PHP框架
- 报错 Exception 'yii\db\Exception' with message 'SQLSTATE[HY000]
- CakePHP 为什么国内不流行
- Laravel中使用thrift-php
- Laravel Eloquent get获取空的数据问题
- CakePHP简介
- array_splice.php
- sphinx+mysql+php做千万数据级别的搜索引擎
- php 数组常用函数
- 在PHP语言中使用JSON
- thinkphp常用CURDS方法解释
- 手动编译php
- YII加载机制扩展冲突解决方案
- php接收数据流
- php调试工具之firephp
- ThinkPHP无法add保存数据
- PHP图像函数列表
- phpAdmin数据导出用法
- php水印处理类中级篇
- php水印原理篇