面向对象:单例模式
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
这一题很典型的体现
static 静态方法的特点: 不绑定$this
***/
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this is not defined.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo(); // foo是普通方法,$a绑定到$this,因此,$this is defined(A);
A::foo(); // 这样调用,是不规范的.$this is not defined
$b = new B();
$b->bar(); // bar是普通方法,$b绑定到$this,bar(){A::foo-这里是静态调用,不操作$this}
// $this is defined (B);
B::bar(); // this is not defined
?>
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
总结self, parent的用法
self: 本类(不要理解成本对象)
parent: 父类
在引入自身的静态属性/静态方法
以及父类的方法时,可以用到.
用法:
self::$staticProperty
self::staticMothed;
parent::$staticProperty
parent::Mothed;
***/
/*
class Human {
static public $head = 1;
public function say() {
echo Human::$head,'<br />';
}
}
echo Human::$head,'<br />'; // 1
$lisi = new Human();
$lisi->say(); //
*/
// 某一天,类名要统一,规范化. Human不叫Human了,叫cHuman
// 导致类内部,凡引用到自身类名的也要改
class cHuman {
static public $head = 1;
public function say() {
echo self::$head,'<br />';
}
}
echo cHuman::$head,'<br />'; // 1
$lisi = new cHuman();
$lisi->say(); //
class Stu extends cHuman {
static public $head = 2;
public function say() {
echo self::$head,'<br />';
echo '父类只有',parent::$head,'<br />';
}
}
$ming = new Stu();
$ming->say();
// ========一位同学的疑问,$this,还用parent====//
class a{
public function a1(){
echo 'this is class function a1()';
}
}
class b extends a{
public function b1(){
$this->a1();
}
public function b2(){
parent::a1();
}
}
$b = new b();
$b->b1();
$b->b2();
/*
上面2个调用,显示效果一样的,
如果从速度角度看,理论上parent::稍快一点点.
因为在子类寻找a1方法,寻找不到,再去其父类寻找.
但是从面向角度看,继承过来的,就是自己的.
$this 更符合面向的思想.
举一个反例
class a {
}
class b extends a {
}
class c extends b {
}
...
...
class f extends e {
parent::parent::parent::
总不能这么写吧?
}
*/
<?php
class Human {
protected $age = 23;
public function say() {
echo $this->age,'<br />';
}
}
class Stu extends Human{
protected $age = 15;
public function say1() {
$this->say();
}
public function say2() {
parent::say();
}
public function say3() {
echo $this->age;
}
}
$ming = new Stu();
print_r($ming);
$ming->say1();
$ming->say2();
$ming->say3();
?>
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
单例模式
先看场景:
多人协同开发, 都要调用mysql类的实例
如果用svn知道,好多人一起开发,再提交各自的文件.
A:
$mysql = new mysql();
$mysql->query....
测试通过
B:
$db = new mysql();
测试通过
...
...
两人的代码要合到一块,如下
$mysql = new mysql();
$mysql->query....
$db = new mysql();
两个mysql类的实例,
而且,每new一下,还要连接一次数据库.
显然,一个页面呢,有一个mysql类的实例就够了.
如果限制,让多人开发,无论你怎么操作,只能得到一个对象呢?
1:开会时,经理说:有一个$db变量,是系统自动初始化的,就是mysql类的实例.
大家都用他.谁敢new mysql(),开除.
2:这是行政手段,不能阻止技术上的new mysql()行为.
我们可以从技术上,用单例模式来解决
注:单例常用也常考,请认真练习
***/
echo '<pre>';
/*
第一步:一个普通的类
这个普通类,可以new 来实例化
这显然不是单例
class single {
}
$s1 = new single();
$s2 = new single();
$s3 = new single();
*/
/*
第二步:看来new是罪恶之源,干脆不让new了
我们把构造方法 保护/私有
外部不能new了
--但引出一个问题,不能new,那得不到对象,这不是单例,这是0例模式
class single {
protected function __construct() {
}
}
$s1 = new single();
*/
/*
第三部,通过内部的static方法,来调用
class single {
public $hash; //随机码
protected function __construct() {
$this->hash = mt_rand(1,99999);
}
static public function getInstance() {
return new self();
}
}
$s1 = single::getInstance();
$s2 = single::getInstance();
*/
/*
两个对象什么时间相等?
答:只有指向一个对象地址的时候,才相等.
print_r($s1);
print_r($s2);
if($s1 === $s2) {
echo '是一个对象';
} else {
echo '不是一个对象';
}
*/
/*
第四步,通过内部的static方法实例化,
并且,把实例保存在类内部的静态属性上
*/
class single {
public $hash; //随机码
static protected $ins = NULL;
protected function __construct() {
$this->hash = mt_rand(1,99999);
}
static public function getInstance() {
if(self::$ins instanceof self) { // instance实例 of谁的,
//专门判断某个对象是不是某个类的实例 用的
return self::$ins;
}
self::$ins = new self();
return self::$ins;
}
}
$s1 = single::getInstance();
$s2 = single::getInstance();
print_r($s1);
print_r($s2);
if($s1 === $s2) {
echo '是一个对象';
} else {
echo '不是一个对象';
}
//===========看问题===============//
class test extends single {
public function __construct() {
parent::__construct();
}
}
$t1 = new test();
$t2 = new test();
print_r($t1);
print_r($t2);
// 问题1:我们辛苦写的单例,继承一下就不灵了.
// 解决 final 最终的 详见05.php
class s {
public $hash; //随机码
static protected $ins = NULL;
final protected function __construct() {
$this->hash = mt_rand(1,99999);
}
static public function getInstance() {
if(self::$ins instanceof self) { // instance实例 of谁的,
//专门判断某个对象是不是某个类的实例 用的
return self::$ins;
}
self::$ins = new self();
return self::$ins;
}
}
class t extends s {
}
$t1 = t::getInstance();
$t2 = t::getInstance();
$t3 = clone $t2;
if($t1 === $t2) {
echo '是一个对象<br />';
} else {
echo '不是一个对象<br />';
}
if($t3 === $t2) {
echo '是一个对象<br />';
} else {
echo '不是一个对象<br />';
}
// clone又多出一个对象, 试问,如何解决?
// 提示: 请看魔术方法 clone!
// 魔术方法很多, __construct, __destruct, __clone,__callstatic....
// 请同学们自行预习
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
final 最终的
这个关键词 在PHP中,可以修饰类,方法名,但不能修饰属性
final 修饰类,则此类 不能够被继承
final 修饰方法,此方法不影响继承,但是此方法 不允许重写
在java中,final也可以修改属性,此时属性值,就是一个常量,不可修改.
问:PHP的类中,可不可以有常量.
答:有
***/
/*
final class Human {
}
class Stu extends Human {
}
*/
/*
不能继承自最终的类
Fatal error: Class Stu may not inherit from final class (Human)
*/
class Human {
final public function say() {
echo '华夏子孙';
}
public function show() {
echo '哈哈';
}
}
class Stu extends Human {
}
$ming = new Stu();
$ming->say(); // final 方法可以继承
class FreshMan extends Stu{
public function say() {
echo '我要出国,做美利坚人';
}
}
/*
Fatal error: Cannot override final method Human::say()
*/
浙公网安备 33010602011771号