面向对象:继承,多态
<?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());
浙公网安备 33010602011771号