面向对象:多态,静态方法
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
private
protected
public
三者的区别
private protected public
本类内 Y Y Y
子类内 N Y Y
外部 N N Y
注意:
在java中,如果属性/方法前面不写任何参数
即public/protected/private都不写,也是可以的,friendly
在PHP中,如果public/protected/private 都不写,
则理解为 public 建议养成好习惯,不要不写
***/
/****
代码部分
****/
class Human {
private $name = 'zhangsan';
protected $money = 3000;
public $age = 28;
public function say() {
echo '我叫',$this->name,'<br />';
echo '我有',$this->money,'元钱<br />';
echo '我今年',$this->age,'岁';
}
}
class Stu extends Human {
private $friend = '小花';
public function talk() {
echo '我叫',$this->name,'<br />';
echo '我有',$this->money,'元钱<br />';
echo '我今年',$this->age,'岁<br />';
}
}
$ming = new Stu();
echo $ming->age,'<br />'; // 28
// 下行错,因为类外不能调用private
// echo $ming->friend;
// 下行错,因为类外不能调用protected属性
// echo $ming->money;
/*
总结:
public 可以在类外调用,权限最为宽松
protected和 private不能在类外调用
?? public 在类内调用行不行
答:当然行,类外都可以,权限很宽松,类内自然没问题.
*/
/*
下一行执行时
Notice: Undefined property: Stu::$name in D:\www\1109\02.php on line 44
我有3000元钱
我今年28岁
分析原因: Undefined property: Stu::$name 这是说明:stu对象 没有name属性
但昨天说,私有的不是可以继承吗?
是可以继承过来,但系统有标记,标记其为父类层面的私有属性.
因此无权调用,导致此错发生.
可以分析出:
protected 可以在 子类内访问
?? protected能在子类访问,本类内能否访问?
答:当然可以
*/
$ming->talk();
echo '<hr />';
$yuanmou = new Human();
$yuanmou->say();
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
public class PolyTest
{
public static void main(String[] args)
{
Light light = new Light();
RedGlass rg = new RedGlass();
BlueGlass bg = new BlueGlass();
light.ons(rg);
light.ons(bg); // I want to show blue light;
}
}
class Light
{
public void ons(RedGlass red)
{
red.display();
}
}
class RedGlass
{
public void display()
{
System.out.println("red light");
}
}
class BlueGlass
{
public void display()
{
System.out.println("BlueGlass");
}
}
这样一段代码,在java中 编译通不过.
原因是:
public void ons(RedGlass red)
{
red.display();
}
ons方法, 指定了 接收的参数必须是 RedGlass,即红玻璃对象
因此,你传一个蓝光玻璃,不行!
强类型语言的一个特点,
函数参数,函数的返回值,都是定死的.
***/
/****
代码部分
****/
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
PHP中的多态
***/
/****
代码部分
****/
class Light {
// 开灯, 传一个玻璃参数
public function ons($g) {
// 用玻璃渲染颜色
$g->display();
}
}
class RedGlass {
public function display() {
echo '红光照耀<br />';
}
}
class BlueGlass {
public function display() {
echo '蓝光照耀<br />';
}
}
class GreenGlass {
public function display() {
echo '绿光照耀<br />';
}
}
class Pig {
public function display() {
echo '八戒下凡,哼哼坠地!<br />';
}
}
// 创建一个手电筒
$light = new Light();
// 创建3块玻璃
$red = new RedGlass();
$blue = new BlueGlass();
$green = new GreenGlass();
// 变红灯
$light->ons($red);
// 为蓝灯
$light->ons($blue);
// 变绿灯
$light->ons($green);
// 调用错了
$pig = new Pig();
$light->ons($pig);
/*****
分析 与java那段出错程序相比
php没报错,
因为PHP是弱类型动态语言.
一个变量
$var = 8;
$var = 'hello';
$var = new Pig();
一个变量,没有类型,你装什么变量都行.
同理,传参,参数也没有强制类型.
传什么参都行.
所以,对于PHP动态语言来说,岂止是多态,简直是变态.
// 又有专家说, 你这个太灵活了,简直变态,不能这么灵活.
否则我们就不说你多态.
答:别急,我们不让php这么灵活还不行吗
我对参数做类型限制总行了吧.
见下一页
*****/
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
***/
/****
代码部分
****/
class Light {
// 此处,仿java,也加一个类名,做参数类型检测
public function ons(RedGlass $g) {
// 用玻璃渲染颜色
$g->display();
}
}
class RedGlass {
public function display() {
echo '红光照耀<br />';
}
}
class BlueGlass {
public function display() {
echo '蓝光照耀<br />';
}
}
class GreenGlass {
public function display() {
echo '绿光照耀<br />';
}
}
class Pig {
public function display() {
echo '八戒下凡,哼哼坠地!<br />';
}
}
// 造手电筒
$light = new Light();
// 造红玻璃
$red = new RedGlass();
// 造蓝玻璃
$blue = new BlueGlass();
// 红灯亮
$light->ons($red);
// 蓝灯亮
$light->ons($blue);
/**
Catchable fatal error: Argument 1 passed to Light::ons() must be an instance of RedGlass, instance of BlueGlass given, called in D:\www\1109\05.php on line 72 and defined in D:\www\1109\05.php on line 24
加了类型检测后,果然传蓝玻璃不行.
解决:参数定为父类,传其子类.
哲学: 子类是父类, 例:男人是人,白马是马,蓝玻璃是玻璃.
里氏代换: 原能用父类的场合,都可以用子类来代替.
见下一页的解决
**/
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
class Light {
// 此处,仿java,也加一个类名,做参数类型检测
public function ons(int $g) {
// 用玻璃渲染颜色
$g->display();
}
}
class Glass {
public function display() {
}
}
class RedGlass extends Glass{
public function display() {
echo '红光照耀<br />';
}
}
class BlueGlass extends Glass {
public function display() {
echo '蓝光照耀<br />';
}
}
class GreenGlass extends Glass {
public function display() {
echo '绿光照耀<br />';
}
}
class Pig {
public function display() {
echo '八戒下凡,哼哼坠地!<br />';
}
}
// 造手电筒
$light = new Light();
// 造红玻璃
$red = new RedGlass();
// 造蓝玻璃
$blue = new BlueGlass();
// 红灯亮
$light->ons($red);
// 蓝灯亮
$light->ons($blue);
// 猪八戒降生
$pig = new Pig();
$light->ons($pig);
/****
如果按PHP本身特点,不检测类型,
本身就可以说是多态的,甚至变态的.
但是PHP5.3以后,引入了对于对象类型的参数检测,
注意 只能检测对象所属的类
其实,这对于PHP来说,限制了其灵活性,达到的java中多态的效果.
反思多态:
其实就是
只抽象的声明父类, 具体的工作由子类对象来完成
这样,不同的子类对象完成,有不同的特点.
****/
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
静态属性 静态方法
在属性,和方法前 加 static 修饰,这种称为静态属性/ 静态方法
***/
class Human {
static public $head = 1;
public function changeHead() {
Human::$head = 9;
}
public function getHead() {
return Human::$head;
}
}
// 现在没有对象,想访问静态的$head属性
/*
普通属性包在对象内,用对象->属性名 来访问
静态属性放在类内的,
静态属性既然存放于类空间内
1:类声明完毕,该属性就已存在,不需要依赖于对象而访问
2:类在内存中只有一个,因此静态属性也只有一个
*/
// 当一个对象都没有,静态属性也已随类声明而存在
echo Human::$head,'<br />'; // 1
// 静态属性只有一个,为所有的对象的共享.
$m1 = new Human();
$m1->changeHead(); // 某个人改变了人类的头的数量
$m2 = new Human();
$m3 = new Human();
echo $m2->getHead(),'<br />'; // 9
echo $m3->getHead(),'<br />'; // 9
<?php
/****
燕十八 公益PHP讲堂
论 坛: http://www.zixue.it
微 博: http://weibo.com/Yshiba
YY频道: 88354001
****/
/***
====笔记部分====
静态方法
static public/protected/private function t() {
}
普通方法,存放于类内的,只有1份
静态方法,也是存放于类内的,只有1份
区别在于: 普通方法需要对象去调动, 需要绑定$this
即,普通方法,必须要有对象,用对象调动
而静态方法, 不属性哪个对象,属于类,因此不需要去绑定$this,
即, 静态方法,通过类名就可以调动
***/
class Human {
public $name = '张三';
static public function cry() {
echo '5555';
}
public function eat() {
echo '吃饭';
}
public function intro() {
echo $this->name;
}
}
// 此时一个对象都没有
Human::cry();
/*
下面这个eat方法是一个非静态方法,应由对象来调用
但是呢,调用了,也没出问题
*/
Human::eat();
/*
接上,但从逻辑来理解, 如果用类名静态调用非静态方法
比如 intro()
那么: $this 到底是指哪个对象???
因此,直接报错
Fatal error: Using $this when not in object context in D:\www\1109\08.php on line 45
*/
// Human::intro();
/*
如上分析,其实非静态方法,是不能由类名静态调用的.
但是! PHP中的面向对象检测的并不严格,
只要该方法没有$this,就会转化静态方法来调用.
因此,cry()可以调用.
但是,在PHP5.3的strict级别下,或者PHP5.4的默认级别
都已经对类名::非静态方法做了提示
则会提示:Strict Standards: Non-static method Human::eat() should not be called statically
不能静态的去调用非静态方法
*/
Error_reporting(E_ALL|E_STRICT);
Human::eat();
/***
因此此原因导致的典型问题,欢迎解答
http://www.zixue.it/forum.php?mod=viewthread&tid=3756&extra=page%3D1
***/
// 动访问静
$lisi = new Human();
$lisi->cry(); // 5555
/*
类->访问->静态方法 可以
类->动态方法 方法内没有this的情况下,但严重不支持.逻辑上解释不通.
对象-->访问动态方法 可以
对象-->静态方法 可以
*/
多态,
静态方法
单例模式
=====昨天回顾===
继承
subClass extends parentClass {
}
继承的特点:
对于protected/public类型的属性/方法
完成继承过来,有权重写,调用.
继承过来的属性/方法:
父类有的,子类也有
父类有的,子类可以改写
父类没有的,子类可以添加
对于pricate类型的属性/方法,比较特殊.
可以继承过来,但有个标记,标记记从属父类而来.
即 在子类内是无权调用继承过来的私有属性/方法的.
构造方法的继承
构造方法也是可以继承的,
new 子类时,如果构造方法继承过来,当然也要自动执行.
但继承过来,子类重写了,自然执行子类的构造方法
(注意,父类的构造方法不再调用)
浙公网安备 33010602011771号