面向对象三大特征: 封装 继承 多态

封装

<?php
class Human
{
	public $money = 1000;
}

$lisi = new Human();

echo $lisi->money,'<br />';//1000

//变一下money

$lisi->money = 500;
echo $lisi->money,'<br />';//500

李四的钱,别人问他有多少钱,他就如实说
别人把他的钱减少,立即就减少了

如果在现实生活中,这个现象显然不合理,
我们需要把钱保护起来

public是公共的,即大家都可以来读取,操作,
钱显然不应该是公共的。

class Human
{
	private $money = 1000;

	public function showMoney(){
		return $this->money * 0.8;
	}
}

$lisi = new Human();

/*
在下例中,调用失败,因为money是私有的,
在外部不能被调用,
这是,我们就把money封装其他了。

注意:光封起来是没有意义的,因为money这个属性还得与外界有所交互才行。
*/
//echo $lisi->money,'<br />';


/*
你不能直接翻lisi的钱袋,但是可以问

把某些重要属性封装起来,然后通过一个开放的接口来操作,
这就实现了对属性的封装。
*/

echo $lisi->showMoney(),'<br />';

从方法的体现上来看封装

<?php
class Human
{
	private $money = 1000;
	private $bank = 2000;

	private function getBank($num){
		$this->bank -= $num;
		return $num;
	}

	public function showMoney(){
		return $this->money;
	}

	public function showBank(){
		return $this->bank;
	}

	public function send($much){
		if ($much > $this->money+$this->bank) {
			return false;
		} else if ($much > $this->money){
			$num = $much - $this->money;//要从银行取多少钱
			$this->money += $this->getBank($num);//从银行取出钱加到现金里

			$this->money -= $much;//再把钱借给朋友
			return $much;
		} else {
			$this->money -= $much;
			return $much; 
		}
		
	}
}

$lisi = new Human();
$m = $lisi->send(300);
if ($m) {
	echo '借了',$m,'元<br />';
	echo '现金还剩下',$lisi->showMoney(),'元<br />';
}

//再借2000元
$m = $lisi->send(2000);
if ($m) {
	echo '借了',$m,'元<br />';
	echo '现金还剩下',$lisi->showMoney(),'元<br />';
	echo '银行里还剩下',$lisi->showBank(),'元<br />';
}

/*
在上个例子中,
借钱者,只知道,借成功了还是失败了。

至于,如果借成功了,lisi是如何把钱凑齐的,
借钱者会不会知道?
答:不会知道lisi也许跑了趟银行,才把钱凑齐。

就像同学们,只需要每周一到每周五20:00-22:00来听课,
至于老师如何备课,拉网线,不需要知道。

对于一个对象,对外界开放一个借口,
调用接口时,内部进行的操作,不需要外界知道,
隐藏了内部的实现细节。

这是对方法的封装


生活中的封装比比皆是。
例如:电视机,收音机,
开电源,一个动作
【隐藏的内部动作:触发显像管,接无线电信息,调频等等】

*/
 ?>

权限修饰符

作用: 用来说明 属性/方法的权限特点
写在 属性/方法前面

共有3个权限修饰符
private 私有的,保护的最严
protected 受保护的,
public 公共的,保护的最松

疑问:
public修饰的属性/方法,可以在那儿访问?
private修饰的属性/方法,可以在那儿访问?

如何判断属性/方法,有没有权限访问?
答: 看访问的位置

private的属性/方法,只能再类定义的大括号内{},才能访问

public的属性/方法,在任意位置都可以访问

<?php

class Human
{
	public $mood = "";//心情,公有
	private $money = 1000;//钱,私有

	public function showMoney(){
		return $this->money;
	}

	private function secret(){
		echo "我小时候偷吃过一块肉";
	}

	public function tellMe(){
		$this->secret();
	}
}

$lisi = new Human();
$lisi->mood = 'happy';
echo "{$lisi->mood}<br />";


//调用位置在Humen类的{}外面,因此调用失败
//echo "{$lisi->money}<br />";

/*
showMoney()是公共的,因此可以在任意位置调用
showMoney中的第35行,return $this->money;
这一句运行的环境是在类的{}内部,因此有权限访问money的属性
*/
echo $lisi->showMoney();

//$lisi->secret(); //不可以

$lisi->tellMe(); //可以,因为是通过43行,即类内调用的

/*
总结:private权限控制

只能在定义的类内{}调用
走出了{},谁也调不动
*/

对象共有

<?php 

class Human
{
	private $money = 1000;

	public function getMoney($people){
		return $people->money;
	}

	public function setMoney($people){
		$people->money -= 500;
	}
}

$zhangsan = new Human();
$lisi = new Human();

//echo $lisi->money;//can't

//让lisi去打探zhangsan的钱
echo $lisi->getMoney($zhangsan),'<br />';

//让lisi去改变zhangsan的钱
echo $lisi->setMoney($zhangsan);
echo $lisi->getMoney($zhangsan),'<br />';


/*
奇怪之处在于,
zhagnsan的钱应该由zhangsan来调用getMoney和setMoney

但是符合 “private的属性/方法,只能再类定义的大括号内{},才能访问
public的属性/方法,在任意位置都可以访问” 的规则

*/

对象私有

<?php 

class Human
{
	private $money = 1000;

	public function getMoney($people){
		return $people->money;
	}

	public function setMoney($people){
		$people->money -= 500;
	}
}

$zhangsan = new Human();
$lisi = new Human();

//echo $lisi->money;//can't

//让lisi去打探zhangsan的钱
echo $lisi->getMoney($zhangsan),'<br />';

//让lisi去改变zhangsan的钱
echo $lisi->setMoney($zhangsan);
echo $lisi->getMoney($zhangsan),'<br />';


/*

lisi读取和改变zhangsan的钱,
这从生活的角度来考虑,是不合理的。

钱私有,是指“每个对象的钱,针对每个对象私有”
即:zhangsan的钱,由$zhangsan->showMoney才能引用

lisi不应该有权直接引用,
或者说,$lisi->showMoney,也只有权限引用lisi自己的money属性

但是,在上面的代码中,lisi却显然引用和改变了zhangsan的钱
这是因为:
PHP在实现上,并不是以对象为单位来控制的权限,
而是以类为单位,来控制的权限。
所以前一页,不断强调类内,类外,而不是对象内外。 


因为类声明一次,而对象却可能非常多,
以类为单位,简单了判断模型

*/