面向对象:魔术常量,类常量

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

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


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

重写/覆盖 override
指:子类重写了父类的同名方法


重载: overload
重载是指:存在多个同名方法,但参数类型/个数不同.
传不同的参数,调用不同的方法

但是在PHP中,不允许存在多个同名方法.
因此,不能够完成java,c++中的这种重载

但是,PHP的灵活,能达到类似的效果
***/


/****
代码部分
****/


class Human {
public function say($name) {
echo $name,' 吃了吗?<br />';
}
}


class Stu extends Human {
public function say() {
echo '切克闹,卡猫百比<br />';
}

/*
public function say($a,$b,$c) {
echo '哥仨好';
}
*/
}


$ming = new Stu();
$ming->say();
$ming->say('张三'); // 上面这个过程叫重写override!

 

 

class Calc {
public function area() {
// 判断一个调用area时,得到的参数个数
$args = func_get_args();
if(count($args) == 1) {
return 3.14 * $args[0] * $args[0];
} else if(count($args) == 2) {
return $args[0] * $args[1];
} else {
return '未知图形';
}
}
}


$calc = new Calc();

// 计算圆的页面
echo $calc->area(10),'<br />';

 

// 计算矩形的面积
echo $calc->area(5,8);

 

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

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


/***
====笔记部分====
普通常量 define('常量名',常量值);
以前说过: define定义的常量 ,全局有效.
无论是页面内,函数内,类内,都可以访问.


能否定义 专门在类内发挥作用的常量
专门在类内发挥作用 说明
1:作用域在类内,类似于静态属性
2:又是常量,则不可改.

其实就是"不可改变的静态属性"


类常量 在类内用 const 声明即可
前面不用加修饰符,
而且权限是public的,即外部也可以访问


***/


/****
代码部分
****/

 

define('ACC','Deny');


class Human {
const HEAD = 1;

public static $leg = 2;

public static function show() {
echo ACC,'<br />';
echo self::HEAD,'<br />';
echo self::$leg,'<br />';
}

}

Human::show();

echo Human::HEAD;

 

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

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


/***
====笔记部分====
魔术常量

1:无法手动修改他的值,所以叫常量
2:但是值又是随环境变动的,所以叫魔术

---魔术常量
__FILE__ 返回当前文件的路径.
在框架开发或者是网站初始化脚本中,用来计算网站的根目录

__LINE__ 返回当前的行号
在框架中,可以用来在debug时,记录错误信息

 

__CLASS__ 返回当前的类名

__METHOD__ 返回当前的方法名
***/


echo '当前正在运行的是',__FILE__,'文件','<br />';

echo '当前在',__DIR__,'目录下<br />';

echo 'hi,我在',__LINE__,'行<br />';
echo 'hello,我在',__LINE__,'行<br />';
echo 'hehe,我在',__LINE__,'行<br />';


class Human {
public static function t() {
echo '你正在运行',__CLASS__,'类<br />';
echo '下的',__METHOD__,'方法';
}
}

Human::t();

 

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

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


/***
====笔记部分====
后期绑定/延迟绑定
***/


class Human {
public static function whoami() {
echo '来自父类的whoami在执行<br />';
}

public static function say() {
self::whoami(); // 子类内没有say方法,找到了父类这里
// 在这里的self 指的是 父类
}

public static function say2() {
static::whoami(); // 子类也没有say2方法,又找到父类这里
// 但是父类用static::whoami,
// 指调用你子类自己的whoami方法
}
}


class Stu extends Human{
/*
public static function whoami () {
echo '来自子类的whoami在执行<br />';
}
*/
}


Stu::say();

Stu::say2();

 

 

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

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


/***
====笔记部分====
抽象类: 无法实例化
类前加 abstract, 此类就成为抽象类,无法实例化.


春秋战国时期,燕零七 飞行器专家,能工巧匠.

他写了一份图纸---飞行器制造术

飞行器秘制图谱
1: 要有一个有力的发动机,喷气式.
2: 要有一个平衡舵,掌握平衡

他的孙子问: 发动机怎么造呢?
燕零七眼望夕阳: 我是造不出来,但我相信后代有人造出来

 

总结:
类前加 abstract 是抽象类
方法前加 abstract 是抽象方法

抽象类 不能 实例化
抽象方法 不能有 方法体

有抽象方法,则此类必是 抽象类
抽象类,内未必有抽象方法

但是 --- 即便全是具体方法,但类是抽象的,
也不能实例化.

***/


/****
代码部分
****/


// 燕零七的构想,当时的科技造不出来,即这个类只能在图纸化,无法实例化.
// 此时这个类没有具体的方法去实现,还太抽象.
// 因此我们把他做成一个抽象类
abstract class FlyIdea {
// 大力引擎,当时也没法做,这个方法也实现不了
// 因此方法也是抽象的
public abstract function engine();

// 平衡舵
public abstract function blance();

/*
注意:抽象方法 不能有方法体
下面这样写是错误的
public abstract function blance() {
}
Fatal error: Abstract function FlyIdea::engine() cannot contain body
*/
}

/*
抽象类不能 new 来实例化
下面这行是错误的
$kongke = new FlyIdea();
Cannot instantiate abstract class FlyIdea
*/

 

// 到了明朝,万户用火箭解决了发动机的问题
abstract class Rocket extends FlyIdea {

// 万户把engine方法,给实现了,不再抽象了
public function engine() {
echo '点燃火药,失去平衡,嘭!<br />';
}

// 但是万户实现不了平衡舵,
// 因此平衡舵对于Rocket类来说,
// 还是抽象的,
// 类也是抽象的
}

 

/*
到了现代,燕十八亲自制作飞行器
这个Fly类中,所以抽象方法,都已经实现了,不再是梦想.
*/

class Fly extends Rocket{
public function engine() {
echo '有力一扔<br />';
}

public function blance() {
echo '两个纸翼保持平衡~~~';
}

public function start() {
$this->engine();
for($i=0;$i<10;$i++) {
$this->blance();
echo '平稳飞行<br />';
}
}
}

 

$apache = new Fly();

$apache->start();

 


abstract class Car {
public function run() {
echo '滴滴';
}
}


class qq extends Car {
}

$qq = new qq();

 

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

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


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

抽象类的意义:

请看如下场景:
Facebook 多国语言欢迎页面

user登陆,有一个 c 字段,是其国家
当各国人登陆时,看到各国语言的欢迎界面


我们可以用面向过程的来做

if($c == 'china') {
echo '你好,非死不可';
} else if($c =='english') {
echo 'hi,welcome';
} else if($c == 'japan') {
echo '搜达斯内';
}

反思: 当facebook进入泰国市场时,
增加 else if ,扩展性很差

 


$c = 'english';

if($c == 'china') {
echo '你好,非死不可';
} else if($c =='english') {
echo 'hi,welcome';
} else if($c == 'japan') {
echo '搜达斯内';
}

***/


// =====用面向对象来做======//
/*
让美国小组/中国开发组/斯蜜达开发组 来开发Welcome类

争执不下: echo 到底该中? 日? 韩?

说: 干脆在wel()方法里,判断一下? 没意义啊

*/

abstract class Welcome {
public abstract function wel();
}

 

// 这是首页的controller开发者
//$wel = new Welcome();
//$wel->wel();
/*
说:你们别争执了,我只知道,我要调用wel()方法,就是打招呼,
你们显示什么语言和我无关.
*/


/**
经理说话:
Welcome谁也不许动,各国开发小组开发自己的招呼类

另:为了首页的controller开发者便于调用,
统一继承自welcome类
**/

 

class china extends Welcome {
public function wel() {
echo '你好,非死不可,<br />';
}
}


class english extends Welcome {
public function wel() {
echo 'hi,welcome';
}
}


class japan extends Welcome {
public function wel() {
echo '搜达斯奈';
}
}

 

 

// 再看首页开发者

$c = 'english'; // china, japan
$wel = new $c();
$wel->wel();


/*

以后新增了泰国语,首页的开发者,根本无需改动
只需要增加一个泰国的welcome类 就可以了.

所以有一些面向对象的介绍中,说面向对象的一个特点:可插拔特性

*/

 

posted on 2012-11-19 15:51  besile  阅读(242)  评论(0)    收藏  举报