1.复习OOP:
* 析构函数:|--默认是在程序结束时自动调用,目的是释放所有的资源{比如打印机资源}
|--本质:PHP通过监测一个对象或者变量,发现它再不会被使用,就决定销毁它,释放内存。
* 但是注意 *
检测一个对象是不是真的再也不会被调用,除了默认在程序结束的那一刻之外,我们是可以人为干预的:
比如,我们提前销毁一个变量$a,系统就会调用析构函数{目的是释放$a占据的内存}
我们提前把一个对象$obj=null,它也会认为再不用这个对象了,也会调用析构函数释放$obj的内存
但是注意:这里设计一个对象引用的东西:
$obj1 = $obj
//这里相当于创建了$obj的引用,当$obj=null, $obj1依旧指向这个对象,无影响,所以这个候 即使你销毁了$obj, 而$obj1依旧在占据着这个对象的资源,在后台运行。
{析构函数不会被调用}
$obj2 = &$obj
//这也是一个对象引用,区别上面的特点是:$obj2和$obj可以认为是一个变量的两个名字,一 概全改,一销毁全销毁。他们其实就是一个东西。
如果$obj = null或者被销毁,$obj2也不复存在。
{析构函数会被调用}
*继承符号: extends //继承的局限性:
*访问控制:public
private //仅自身类的内部
protected //自身类和子类的内部
//字段被封装了不能在类外部直接访问,可以,在类内部,立马写一个public方法,
外部通过访问这个public方法来访问它。
* static属性和方法:
|--定义方法:public static fuction add(){};
public static $hello ;
|--静态属性保存所有对象共有的属性,
静态方法只能访问静态属性,{当然public可以访问所有的类型变量。}
静态成员直接用类调用,不可以实例化对象。
|--特点及访问方式:静态方法和字段创建的目的就是为所有对象服务{也可以说不是为某个特定对象服务}
所以它的访问方式是
类外部: NbaPlayer::add {直接用类名调用,不允许用对象调用}
NbaPlayer::$hello {$符号注意带上}
类内部: self::add();
self::$hello;
static::add();
static::$hello();
|--但是现在:如果父类里有一个static变量或方法,子类默认是....
那么怎么访问他呢?
如:父类man里static变量: haoge,
在子类big_man类内部只需要这么调用: parent::$haoge;就OK了,等于把self改成parent
但是之类外部就不能访问了。
* 重写:子类中定义一个和父类方法名相同的方法{只要求方法名相同},这就是重写。
调用方法时,按子类的规则来。
//重载:PHP中虽然没有如同java子类语言那种“允许一个类定义里面用一个函数名写多个方法{每个方法参数不同或 函数返回值类型不同}”
这种机制实现重载,但是由于PHP不讲究变量类型,所以它也想出了一套方案:
在这个方法定义的时候一次性写全所有的参数,并且给定默认值,之后当我们需要调用的时候,传入不同的
参数,就产生不同的结果,等于是重载了。
*注意:*重载是“一个类定义方法的时候方法的多态性”,而重写发生在“子类继承父类对一个方法的多态性”
*final关键字:
父类的定义的前面加一个final那么任何类都不能继承这个父类。
如果父类的一个方法A定义时前面加了个final,那么任何继承父类的子类都不允许重写这个方法A。
* 关键字访问: |-- parent关键字
我们有了重写之后,默认在“子类定义时”访问方法A已经是被重写之后的方法了:$this->A();
这个时候,如果还想访问父类的原来的方法A,只要使用parent就OK了: parent::A;
//当然,在开始说static的时候,parent也是神器。
|-- self关键字
在任何类的定义时: $this->hello() <=> self::hello(); //访问方法
const PI = 3.14; $this->PI <=> self::PI ; //访问常量
static //当然可以访问静态变量。
//但是self比较奇葩的是,它不支持类自身属性{变量}的访问,
所以除了要调用static,还不如全部用$this->...方便清晰。
|-- static关键字
只用于访问类自身定义时,定义的static的属性,方法。
* 接口:
|--意义:
|-- 解决了PHP只能单继承带来的缺陷,现在也可以大量继承很多方法了。
|-- 怎么个复用性看具体项目吧.
|--利于分工合作开发:
A负责接口的方法在某些类中的的具体实现,
B直接调用接口的方法做项目的其他步奏,无须管他怎么实现
|-- 用法:
|-- //interface关键字定义接口。注意接口命名是驼峰法。
interface IcanEat {
public function eat($food); //接口里面只写方法声明,不许实现。
}
//implements关键字实现接口
class haoge implements IcanEat {
public function eat($food){ //在实现了接口的类里,必须把方法具体实现出来。
echo "haoge eat {$food}";
}
}
//接口不能被实例化
//可以用instanceof关键字来查看对象是否实现了某个接口:
var_dump($obj instanceof IcanEat ); //若bool true 则说明obj这个对象实现了接口
{这个instanceof作用在于:有时候需要判断某个方法是否能被某个对象调用,做一下安全检查}
//可以用extends实现子接口继承父接口:
interface IcanRun extends Icaneat{
public function run($distance);
}
//当一个类实现了这个子接口时,不但要实现子接口的方法,还要实现子接口对应的父接口....
class haoge implements IcanRun{
public function eat($food){.......};
public function run($distance){........};
}
* 多态:
这里的PHP多态就是一个接口但是被不同类做了不同的实现,所以不同对象调用同一方法产生不同效果,即多态。
* 抽象类:
|--特点:abstract类的结构介于类和接口之间,就是既包括需要具体实现的普通方法,
也包括抽象方法{不许实现}
|-- abstract public class AcanEat{
public function breath{ //普通方法,需要具体实现。
echo "we are all need breah";
}
abstract public function eat($food); //abstract标示,不需要实现,也不能实现
}
class human extends AcanEat{
abstract public function eat($food){ //继承了抽象类,只需要具体实现抽象方法即可。
echo "haoge like {$food}";
}
}
*PHP的特殊OOP性质*:
|--魔术方法:
* __tostring() :当对象被当做一个string时,该方法自动调用
* __invoke(): 当对象被当做一个方法时,...
实例:{可做个试验玩哇}
class MagicTest{
public function __tostring(){
return "this is a magic method";
}
public function __invoke($x){
echo "__invoke called with {$x}";
}
}
$obj = new MagicTest;
echo $obj ; //对象被当做一个string使用了,所以调用__tostring。
$obj(5); //对象被当做一个方法使用了,所以调用了__invoke。
* __call() :
* __callStatic() :
案例:
class MagicTest{
//相当于重载了一次haoge();
public function __call($name, $arguments){
/* 这里$name就是待会儿访问不存在的方法名haoge,
$arguments就是传入haoge的参数形成的数组,
他们由系统自动捕获,我们不用管它。
*/
echo "calling with {$name} with parameter ".implode(",", $arguments);
} //implode是分割函数
//这里相当于重载了static的haoge();
public static function __invoke($x){
echo "static calling with {$name} with parameter ".
implode(",", $arguments);
}
}
$obj = new MagicTest;
$obj->haoge("haha", "hehe"); //访问不存在的haoge(),so...
MagicTest::haoge("haha", "hehe") //访问不存在的static的haoge(),so....
//这个魔术方法真的很神奇,一个不存在的方法被调用后,出现了两种结果。
* __get() : 在读取"不可访问"的属性时...
* __set() : 在给"不可访问"的属性赋值时...
* __isset() : 在对"不可访问"的属性使用isset()时...
* __unset() : 在对"不可访问"的属性使用unset()时...
//不可访问的属性:比如private,protected,未定义的变量...
案例:{这四个家伙也被称为属性的重载}
class MagicTest{
public function __get($name){ //这里的$name是系统捕获的属性名
return "the undifined property is {$name} ";
}
public function __set($name, $value){
return "the property: {$name} has value: {$value}";
}
private $priva;
public function __isset(){
echo "__isset is called";
}
public function __unset(){
echo "__unset is called";
}
}
$obj = new MagicTest;
$obj->hello; //获取一个不存在的属性,so...
$obj->hello = 1000; //给一个不存在的属性赋值,so...
isset($obj->priva); //判断一个private的变量非空否,so...
unset($obj->hello); //删除一个不存在的hello变量,so...
* __clone :
首先声明,当使用clone关键字复制对象时,只要用户定义了__clone,就会自动调用__clone
class MagicTest{
public $name;
}
$test1 = new MagicTest;
$test1->name = "haoge";
$test2 = clone $test1; //复制一个完全相同的test1,连属性值都相同。
var_dump($test2->name);
如果你想在clone的时候,给clone的新对象test2做点操作,比如修改它的$name,
就需要定义__clone了。
class MagicTest{
public $name;
public function __clone(){
$this->name = "hhq";
}
}
$test1 = new MagicTest;
$test1->name = "haoge";
$test2 = clone $test1;
var_dump($test2->name); //test2已经发生变化。
var_dump($test1->name); //我们发现test2的改变不会引起test1的任何改变。
clone 和对象引用是不一样的,具体区别:
http://www.zhihu.com/question/28363811
http://www.cnblogs.com/gameboy90/archive/2011/11/02/2232682.html
http://weizhifeng.net/php-clone.html
{明天花时间一定立刻要弄清楚!!!很重要!!!}
2.接口基础:
|--APP接口:
|--APP如何通信:
|--通信数据格式区别:
|--接口做了什么:
|--json 封装接口数据:
|--xml封装接口数据:
|--PHP生成xml文件:
|--直接输出:
|--dom类的方法:待谷歌之。
|--封装实例:
* 方法
* data数据类型分析:
|--array('name'=> 'haoge', 'love'=> 'hhq'); //key为字母,结构正常
|--array(1, 2, yunda); //key为数字,xml解析节点不允许是数字
|--array('name'=> 'hhq', yunnan); //key既有正常的,也有数字,这是混编
|--array('name'=> 'haoge', array(1, 2, 'haoge')); //,key为数字,value有的是数组
value为数组它也能通过递归处理
关键是key是数字怎么办?
<0>haoge</0> ==> <item id="0"><item> 这样就转化过去了{以属性来赋值}
接下来全是代码。具体叙述要见代码和注释。