面向对象:接口
<?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 '人类';
}
}
浙公网安备 33010602011771号