面向对象:继承,多态

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

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


/***
====笔记部分====
继承: 是指以一个类为父类,另一个类可以做为其子类,
子类在继承了父类的属性/方法的基础上,
进一步增添或修改.

***/


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

// 定义3个类, 人类, 学生类,律师类


class Human {
private $height = 160;

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


class Stu {
private $height = 170;
public $snun = '00134';

public function cry() {
echo '59啊59....<br />';
}

public function study() {
echo 'good good study, day day up<br />';
}
}


/*
老友记
long time no see

you don't bird me,I don't bird you!
*/


class Lawer {
private $height = '180';
public $area = '经济案件';

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

public function bianhu() {
echo '我的当事人是无罪的<br />';
}
}


$zhoukou = new Human();
$zhoukou->cry();


$xiaoming = new Stu();
$xiaoming->cry();
$xiaoming->study();

$lizhuang = new Lawer();
$lizhuang->cry();
$lizhuang->bianhu();


/****
思考:
1: 学生和律师 归根结底还是人!
自然,人的属性和方法,自然就有


2:学生和律师,虽然是人,但比最原始的人,
又多了一些属性和方法.


而我们目前写的3个类,
完成了第2点: 即有原始人的属性,又有学生/律师的独特属性

但是,没有很好的利用上第1点:
即:既然是人,那默认就应该有人的属性,何必再重新声明一遍???

这里的代码,就已经冗余!

如何达到 学生/律师 默认就有人的属性,达到代码的重用和简洁?
答: 继承
****/

 

 

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

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


/***
====笔记部分====
继承
语法: extends

子类 extends 父类 {
}

注意点: 子类 只能继承自 一个父类

不能这样写:
subClass extends Dog,Cat,Pig {
}


***/


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


class Human {
private $height = 160;

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

 

// 再声明一个学生类,学生本质上还是人
// 只不过是人类中,稍微特殊一点的一个群体.
// 即:人类的基础上,衍生出学生类.
// 可以让学生类 继承自 人类
class Stu extends Human{
}

$zhoukou = new Human();
$zhoukou->cry();

/**/
$lily = new Stu();
$lily->cry();
$lily->laugh();


/*
思考:
在学生类中
cry 与 laugh方法 都没定义
为什么cry方法调用成功
laugh方法调用失败!

答:因为Stu类 继承自 Human类

现实中,继承的例子更多.
你同事高帅富,某天开了个宝马.
他没有宝马,但是他爹有宝马.
*/

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

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


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

继承了哪些东西?

子类可以做什么扩充?
构造函数如何继承的?
私有属性/方法如何继承?

***/


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


//

class Human {
private $wife = '小甜甜';

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


class Stu extends Human{
public function subtell() {
echo $this->wife;
}
}

$lisi = new Stu();

$lisi->cry(); // 5555
$lisi->subtell(); // 出错如下
/*
未定义的属性,wife属性
Undefined property: Stu::$wife in D:\www\1108\03.php on line 44

问:父类不是有wife属性吗? 为什么没继承过来?
答: 私有的属性,可以理解不能继承.
(其实能继承过来,只不过无法访问)

public protected private中,
public protected 都可以继承,并拥有访问和修改的权限
这就好比说,家产已经继承了,愿意卖就卖,愿意改就改.

而私有的,就像先祖的牌位,继承下来
但是无权动,只能供着.

*/

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

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


/***
====笔记部分====
继承时,继承来Protcted/public 属性/方法
完全继承过来,属性子类.

继承来 父类private属性/方法,
但不能操作

***/


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

class Human {
// private $wife = '小甜甜';

public $age = 22;
public function cry() {
echo '5555<br />';
}

public function pshow() {
echo $this->wife,'<br />';
}
}


class Stu extends Human{
private $wife = '凤姐';

public $height = 180;
public function sshow() {
parent::pshow();
echo $this->wife,'<br />';
}
}

$lisi = new Stu();

// print_r($lisi);
$lisi->sshow(); // ???

 

/*
根据图来思考:
如果把Stu类中的 wife=凤姐去掉,什么效果? // 未定义属性
如果把Human类中的 wife=小甜甜去掉,什么效果? // 无权访问


*/

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

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


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

子类继承父类的属性/方法,可以修改或增加

***/


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

class sixty {
protected $wine = '1斤';

public function play() {
echo '谈理想<br />';
}
}


class nine extends sixty{
public function play() {
echo '玩网游,宅!<br />';
}

public function momo() {
echo '妹子,认识一下<br />';
}

public function showW() {
echo $this->wine,'<br />';
}
}


$s9 = new nine();

$s9->showW(); echo '<br />'; // 父类有的,继承过来

$s9->play(); // 父类有的,继承过来,可以修改/覆盖(overide).

$s9->momo(); // 父类没有,可以添加


/***
上面所说的继承过来的大环境,
是指 protected /public
**/

 

 

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

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


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

继承时的权限变化

继承自父类的属性/方法
权限只能越来越宽松或不变,不能越来越严格.
***/


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


class Human {
public function cry() {
echo '555<br />';
}
}


class Stu extends Human{
protected function cry() {
echo '5959<br />';
}
}


/*

Fatal error: Access level to Stu::cry() must be public (as in class Human) in D:\www\1108\06.php on line 36

子类的cry比父类的cry方法,权限要严格.
这不行,继承时,权限只能越来越宽松或不变,不能越来越严格.

*/

 

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

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


/****
构造方法的继承

答: 构造方法也是可以继承的,
而且继承的原则和普通方法一样.

进而,如果子类也声明构造函数,则父类的构造函数,被覆盖了!
如果父类构造函数被覆盖了,自然,只执行子类中新的构造函数.


引发一个问题:
如果是一个数据库操作类,或者model类
我们肯定是要继承过去再使用,不能直接操作model类.
而model类的构造函数,又做了许多初始化工作.

我重写的model类的构造函数之后,导致初始化工作完不成了,怎么办?
答: 如果子类继承时,子类有构造函数,保险一点,调用 parent::__construct


这一点和java的面向对象,也有不同.
在java中,实例化子类时, 父类的构造函数运行,且先运行
然后运行子类的构造函数


另外: java中构造函数不是 __construct(),而是和类名相同的方法理解为构造函数.

在一些比较教材或者,老的代码中,你也有可能这种情况.
即 与类名相同的函数做构造函数----这是PHP4时代的残留.

请记住,你不要这样写

****/


class Human {
public function __construct(){
echo '呱呱坠地!<br />';
}
}

 

class Stu extends Human {
}


$ming = new Stu(); // 呱呱坠地,这说明构造函数也是可以继承的


class King extends Human {
public function __construct() {
echo '红光满屋,终日不散<br />';
}
}

 

$zhu = new King();

 

echo '<hr />';
class Mysql {
protected $conn = NULL;
public function __construct() {
$this->conn = mysql_connect('localhost','root','111111');
}

public function query($sql) {
return mysql_query($sql,$this->conn);
}
}

/*
$mysql = new Mysql();
var_dump($mysql->query('use test')); // true,query成功
*/

class MyDb extends Mysql{
public function __construct() {
// 如果子类继承时,有构造函数,保险一点
parent::__construct();

// 然后再写自己的业务逻辑
}

public function autoInsert() {
return $this->query('use test');
}
}


$mydb = new MyDb(); // 看看问题出在哪儿?
var_dump($mydb->autoInsert());

 

 

posted on 2012-11-12 14:31  besile  阅读(191)  评论(0)    收藏  举报