一.面向对象的基本概念
1.对象的理解
1.1什么是对象
世间万物皆对象。
我们能够接触到的,感知到的,都是对象。我们每天都跟对象在打交道。
1.2对象的组成
对象由两部分组成,一部分是属性,一部分是方法。
属性:描述对象所应具有的属性。
方法:描述对象所应具有的功能。
比如:人这个对象。
属性:身高、体重、年龄…
方法:走路、吃饭、学习…
2.面向对象的理解
面向,就是一直看着,一直用着。
面向对象,就是一直看着对象,一直用着对象。
即:
编程的时候,将所有的数据结构,都以对象的思维来组织,来实现。
3.为什么要使用面向对象
3.1我们每天使用的都是对象
我们每天打交道的都是对象,每天都在面向对象的过程中,我们的思维就是面向对象的思维。
比如:
用电视机对象来完成看电视的功能
用电脑对象来完成编程、上网功能
3.2面向对象更符合我们的思维
因为我们的思维是面向对象的思维,所以,当我们的程序用面向对象的方法来编写时。会有以下好处
1.便于我们对复杂的、大型的业务的理解
2.可读性高,便于他人理解,易维护
3.更加灵活。
4.面向对象的步骤与原则
4.1步骤
1.识别对象
2.识别对象的属性
对象的属性可以是变量或常量。
定义常量,使用const关键字。
访问常量时,使用SELF或PARENT或类名。
3.识别对象的方法
对象内部的方法
对象与对象之间交互的方法
4.2原则
高内聚:即一个对象只完成特定的功能。(功能可大可小)
低耦合:对象与对象之间的依赖很小。
比如一个NBA球员对象:
高内聚:只有打球的功能,没有做生意的功能。
低耦合:只开放开其他对象一些特定的属性与方法。对象间依赖程度很好。
高内聚与低耦合互为补充:
做到了高内聚,自然做到低耦合
做到了低耦合,自然做到高内聚。
二、面向对象基本实践
1.类与对象
类:多个相似的对象,具有的相同属性以及方法的集合。
对象:类的一个实例。
注意:我们在类中经常用到$this这个变量。$this是一个伪变量,表示对象自身。
2.构造函数与析构函数
构造函数:__construct(),实例化对象的时候会自动运行此函数。
析构函数:__destruct(),在对象将要被销毁的时候(比如脚本文件将要运行结束的时候),系统自动调用此函数。
我们也可以人为的干扰此函数:即手动销毁对象
手动销毁对象,就会触发此函数。
$object=NULL就会触发此函数
析构函数一般用于释放对象占用的资源,比如打印机资源。
3.PHP对象的引用:
在PHP面向对象编程时,我们经常说:“默认情况下对象是通过引用传递的。”
其实,上面的说法不准确。
我们可能会认为,对象名与对象值得关系是下图:
其实,是下图:
在PHP5中,变量名不再保存对象的值,而是保存该对象的标识符,使用该标识符来访问这个对象。
引用自:php.net-对象和引用
举例:
比如两个对象$Jordan1和$Jordan2
$Jordan2=$Jordan1。
$Jordan2拷贝了$Jordan1的变量标识符。
如下图:
$Jordan2=&$Jordan1。
$Jordan2对$Jordan1是引用传值:即$Jordan2是$Jordan1的别名
如下图:
三、面向对象的高级实践
1.访问控制
public:自身、子类、外部都可以访问
protected:自身、子类可以访问
private:只有自身可以访问
2.静态成员
如果一个类所有的对象都共用某种相同的属性,或某种相同的方法。
即:类中某个属性或方法改变了,所有对象对应的属性和方法都改变。
如果我们用普通的 对象->属性(方法),不能实现。因为每个对象都可以改变自己的属性。
这时候就要用到静态成员了。只需要在属性或方法前面加static关键词就行。
自身类调用自身的静态属性或方法,使用关键词 SELF::
子类调用父类的静态属性或方法:使用关键词 PARENT::
外部调用类的静态成员或方法:使用 类名::
3.继承
PHP是单继承
子类重新定义父类中的方法,我们称之为重写。
final关键字
如果不想让子类重写父类的方法,就在父类方法前加final关键字
如果父类不想让子类继承,就在父类前加final 关键字
4.接口
接口是一种规范,是一种模板。
一个类可以使用implents关键字实现接口,并且可以实现多个接口。
接口中:只是方法的定义,没有实现方法
类实现接口:必须实现接口的方法。
如何判断一个对象是否实现了某个接口或类?
可以使用instanceof关键字
5.多态
比如有A接口,B、C可以同时实现A接口,但B、C可以是不同的实现,这就为多态奠定了基础。(子类的重写也可以)
即:
对于同一个接口,可以有不同的实现。
什么是多态呢?
同一个方法,我们传入不同的对象作为参数的时候,表现是不同的。
因为B、C同时实现了A接口,但是实现不同,所以B的对象作为参数与C的对象作为参数,表现是不同的,这就实现了多态。
6.抽象类
抽象类即是介于普通类与接口之间的类。
普通类:不含有抽象方法
接口:全部是抽象方法
抽象类:可以有一部分是抽象方法,一部分不是。
三、PHP独有的魔术方法
1.对象被非正常使用时:
1.__toString():当对象被当成string调用时,这个方法自动调用
2.__invoke():当对象被当成function调用时,这个方法自动调用
2.调用不存在的方法时(实现方法重载)
1.__call(funcName,args) 调用不存在的普通方法时,触发此函数
2.__callstatic(funcName,args) 调用不存在的静态方法时,触发此函数。
使用__call()方法为例:
<?php
header("content-Type:text/html;charset=utf-8");
class People
{
public function __call($name,$args)
{
echo "方法".$name."以及参数".implode(", ",$args)."不存在";
}
}
$eric=new People();
echo $eric->test1("a1","a2");//方法test1以及参数a1, a2不存在
implode()可以将数组分割成字符串,
explode()可以将字符串分割成数组。
※在使用__callstatic()方法时,__callstatic要定义成静态方法。
3.调用不可访问属性时(实现属性重载)
1.__get()当调用不可访问(不存在或private)属性时,触发此方法
2.__set()当设置不可访问属性的值时,触发此方法。
如下:
<?php
header("content-Type:text/html;charset=utf-8");
class People
{
public function __get($name)
{
echo "getting the property ".$name;
}
public function __set($name,$value)
{
echo "setting the property ".$name ."to ".$value;
}
}
$eric=new People();
$eric->height; //getting the property height
$eric->height=180; //setting the property height to 180
3.__unset() 当对不可访问变量使用unset()时,触发此函数
4.__isset() 当对不可访问变量使用isset()时,触发此函数
4.复制对象(clone)以及复制不同的对象(__clone)
1.使用clone关键字可以复制一个对象;
2.如果不想复制对象的某些元素,可以使用__clone()方法,在__clone()方法内设置不同的内容。
<?php
header("content-Type:text/html;charset=utf-8");
class People
{
public $name;
public function __clone()
{
$this->name="James2";
}
}
$james=new People();
$james->name="james";
echo $james->name; //james
//复制一个$james对象
$james2=clone $james;
echo $james2->name; //$James2