面向对象:接口

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====

***/

class Animal {
const age = 1;
public static $leg = 4;

public static function cry() {
echo '呜呜<br />';
}

public static function t1() {
self::cry();
echo self::age,'<br />';
echo self::$leg,'<br />';
}

public static function t2() {
static::cry();
echo static::age,'<br />';
echo static::$leg,'<br />';
}

}


class Human extends Animal {
public static $leg = 2;

public static function cry() {
echo '哇哇<br />';
}
}

class Stu extends Human {
const age = 16;

public static function cry() {
echo '嘤嘤<br />';
}
}

Stu::t1(); //呜呜,1,4
Stu::t2(); // 嘤嘤,16,2

 

 

 

 

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====
类: 是某一类事物的抽象,是某类对象的蓝图.
比如: 女娲造人时,脑子中关于人的形象 就是人类 class Human

如果,女娲决定造人时, 同时,形象又没最终定稿时,
她脑子有哪些支离破碎的形象呢?

她可能会这么思考:
动物: 吃饭
猴子: 奔跑
猴子: 哭
自己: 思考
小鸟: 飞

我造一种生物,命名为人,应该有如下功能
eat()
run();
cry();
think();


类如果是一种事物/动物的抽象
那么 接口,则是事物/动物的功能的抽象,
即,再把他们的功能各拆成小块
自由组合成新的特种

 

***/


interface animal {
public function eat();
}

interface monkey {
public function run();
public function cry();
}

interface wisdom {
public function think();
}

interface bird {
public function fly();
}


/***
如上,我们把每个类中的这种实现的功能拆出来
分析: 如果有一种新生物,实现了eat() + run() +cry() + think() ,这种智慧生物,可以叫做人.
***/

/*
class Human implements animal,monkey,wisdom {

}

Class Human contains 4 abstract methods
竟然说我有4个抽象方法

因为接口的方法 本身就是抽象,不要有方法体,也不必加abstract
*/

class Human implements animal,monkey,wisdom {
public function eat() {
echo '吃';
}

public function run() {
echo '走';
}

public function cry() {
echo '哭';
}

public function think() {
echo '思考';
}
}

$lisi = new Human();
$lisi->think();

 

/*
根据接口,造一个"鸟人"
*/

class BirdMan implements animal,monkey,wisdom,bird{
public function eat() {
echo '吃';
}

public function run() {
echo '走';
}

public function cry() {
echo '哭';
}

public function think() {
echo '思考';
}

public function fly() {
echo 'hi,我是天使,但大家都叫我鸟人';
}
}

echo '<br />';

$birdli = new BirdMan();
$birdli->fly();

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====
接口的具体语法:
0:以人类为, class Human 是人的草图
而接口 是零件
可以用多种零件组合出一种新特种来.

1: 如上,接口本身即是抽象的,内部声明的方法 默认也是抽象的.
不用加 abstract

2: 一个类可以一次性实现多个接口.
语法用 implements 实现 (把我这几个功能实现了)
class ClassName implements interface1,interface2,interface3 {
}
然后再把接口的功能给实现.


3: 接口也可以继承, 用extends

4:接口是一堆方法的说明,不能加属性

5:接口就是供组装成类用的,封闭起来没有意义,因此方法只能是public

***/

interface animal {
protected function eat();
}

interface monkey extends animal {
public function run();
public function cry();
}

interface wisdom {
public function think();
}

interface bird extends animal{
public function fly();
}

/*
// 下面有误,monkey继承的aniaml接口,因此必须要把eat()实现
class Human implements monkey,wisdom {
public function run() {
echo '走';
}

public function cry() {
echo '哭';
}

public function think() {
echo '思考';
}
}
*/


class Human implements monkey,wisdom {
public function eat() {
echo '吃';
}

public function run() {
echo '走';
}

public function cry() {
echo '哭';
}

public function think() {
echo '思考';
}
}

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====
面向对象的一个观点:
做的越多,越容易犯错

抽象类{就定义类模板}--具体子类实现{china,japan,english}

接口:

 

***/


// 抽象的数据库类
/*
创业做网站
到底用什么数据库? mysql, oracle,sqlserver,postgresql?
这样:先开发网站,运行再说.
先弄个mysql开发着,正式上线了再数据库也不迟

引来问题:
换数据库,会不会以前的代码又得重写?

答:不必,用抽象类
开发者,开发时,就以db抽象类来开发.
*/
abstract class db {
public abstract function connect($h,$u,$p);

public abstract function query($sql);

public abstract function close();
}

/*
// 下面这个代码有误
// 因为子类实现时, connect和抽象类的connect参数不一致
class mysql extends db {
public function connect($h,$h) {
return true;
}

public function query($sql,$conn) {
}

public function close() {
}
}
*/

 

/*
下面这个mysql类,严格实现了db抽象类
试想: 不管上线时,真正用什么数据库

我只需要再写一份如下类
class oracle extends db {
}

class mssql extends db {
}

class postsql extends db {
}

业务逻辑层不用改?

为什么不用改?
因为都实现的db抽象类.

 

我开发时,调用方法不清楚的地方,我就可以参考db抽象类.
反正子类都是严格实现的抽象类.
*/
class mysql extends db {
public function connect($h,$h,$u) {
return true;
}

public function query($sql) {
}

public function close() {
}
}

 


/*

接口 就更加抽象了

比如一个社交网站,

关于用户的处理是核心应用.

登陆
退出
写信
看信
招呼
更换心情
吃饭
骂人
捣乱
示爱
撩骚

这么多的方法,都是用户的方法,
自然可以写一个user类,全包装起来

但是,分析用户一次性使不了这么方法

用户信息类:{登陆,写信,看信,招呼,更换心情,退出}

用户娱乐类:{登陆,骂人,捣乱,示爱,撩骚,退出}


开发网站前,分析出来这么多方法,
但是,不能都装在一个类里,
分成了2个类,甚至更多.

作用应用逻辑的开发,这么多的类,这么多的方法,都晕了.

*/

interface UserBase {
public function login($u,$p);

public function logout();
}

interface UserMsg {
public function wirteMsg($to,$title,$content);
public function readMsg($from,$title);
}

interface UserFun {
public function spit($to);
public function showLove($to);
}

 

/*
作为调用者, 我不需要了解你的用户信息类,用户娱乐类,
我就可以知道如何调用这两个类

因为: 这两个类 都要实现 上述接口.
通过这个接口,就可以规范开发.

*/


/*
下面这个类,和接口声明的参数不一样,就报错,
这样,接口强制统一了类的功能
不管你有几个类,一个类中有几个方法

我只知道,方法都是实现的接口的方法.
*/
class User implements UserBase {
public function login($u) {
}
}

 

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====
类的自动加载

***/


require('./HumanModel.php');

$lisi = new HumanModel();
$lisi->t();

/*
如上,没有require时,报错
手动require进来

如果网站比较大,model类比较多
HumanModel
UserModel
GoodsModel
CatModel
OrderModel
...
...
...
...

 

1:这么多的model,我用谁,就得include/require谁.

2:而且不知道,之前是否已经include/require进来某个类
(这个用once可以解决,但once的效率很低)


这时 我们可以用自动加载!
*/

echo '<br />';


function __autoload($c) {
echo '~~~~',$c,'~~~~~';
}

$ming = new Pig();


/*

如果调用某个不存在的类,
在报错之前,
我们还有一次介入机会 __autoload函数

系统会调用__autoload()函数,
并把"类名"自动传给__autoload函数

我们自然可以在__autoload里 加载需要的类!

见下页
*/

 

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====
__autoload用法
***/


function __autoload($c) {
echo '我先自动加载';
echo './' . $c . '.php';
echo '<br />';
require('./' . $c . '.php');
}


$lisi = new HumanModel();

$lisi->t();

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====

***/


function test() {
// 函数内可以写任何合法的PHP代码,包含再声明一个函数/类
echo '来';
class Bird {
public static function sing() {
echo '百灵鸟儿放声唱!';
}
}

echo '去';
}


// Bird::sing(); // Class 'Bird' not found

 

 

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


/***
====笔记部分====

自动加载只能用__autoload函数吗?
答:不是的,其实也可以指定一个函数

比如 我们就用zidongjiazai()函数

注意:要通知系统,让系统知道--我自己写了一个自动加载方法,用这个!
怎么通知: 用系统函数 spl_auto_register

***/


// 下面这句话,是把zidongjiazai函数注册成为"自动加载函数";
spl_autoload_register('zidongjiazai');

function zidongjiazai($c) {
echo '我引入了./' . $c . '.php','<br />';
require('./' . $c . '.php');
}

 

$HumanModel = new HumanModel();

$HumanModel->t();


/**
__autoload 是一个函数

我能自己注册一个自动加载函数
能否注册类的一个静态方法 当 自动加载函数?


TP里这么做的,自己解决 :)
**/

 

<?php
/****
燕十八 公益PHP讲堂

论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/


// HumanModel类

class HumanModel {
public function t() {
echo '人类';
}
}

 

posted on 2012-11-19 16:08  besile  阅读(375)  评论(0)    收藏  举报