7.5.4 PHP面向对象封装性之魔术方法2
封装性是面向对象编程中的三大特性之一,封装就是把对象中的成员属性和成员方法加上访问修饰符,使其尽可能隐藏对象的内部细节,以达到对成员的访问控制(切记不是拒绝访问)。
这是PHP5的新特性,但却是OOP语言的一个好的特性。而且大多数OOP语言都已支持此特性。
PHP5支持如下3种访问修饰符:
public (公有的 默认的)
private (私有的)
protected (受保护的)
设置私用成员
只要在声明成员属性或成员方法时,使用private关键字修饰就是实现了对成员的私有封装。封装后的成员在对象的外部不能直接访问,只能在对象的内部方法中使用 $this访问。
<?php
class Person {
private $name; //第一个成员属性$name定义人的名字,此属性被封装
private $sex; //第二个成员属性$sex定义人的性别,此属性被封装
public function __construct($name="", $sex="男") {
$this->name = $name;
$this->sex = $sex;
}
private function leftLeg() { //声明一个迈左腿的方法,被封装所以只能在内部使用
return "迈左腿";
}
}
<?php
class Person {
private $name; //第一个成员属性$name定义人的名字,此属性被封装
private $sex; //第二个成员属性$sex定义人的性别,此属性被封装
public function setName($name ) { //通过此方法设置属性name的值
$this->name=$name; //为对象的私有属性赋值
}
public function getName(){ //通过此方法获取属性name的值
return $this->name; //返回当前的私有名字属性
}
public function setSex($sex) { //通过此方法设置属性sex的值
if($sex=="男" || $sex=="女") //如果传入合法的值才为私有的属性赋值
$this->sex=$sex; //条件成立则将参数传入的值赋给私有属性
}
public function getSex(){ //通过此方法获取属性$sex的值
return $this->sex; //返回当前的私有性别属性
}
__set()、__get()、__isset()和__unset()
魔术方法:
__set(): 用于替代通用的set赋值方法
__get(): 用于替代通用的get取值方法
__isset(): 检测对象中成员属性是否存在
__unset(): 销毁对象中成员属性方法
注意:
上面四个魔术方法只对类中的私有、受保护成员属性有效。
魔术方法前的修饰符可以是公有、私有,不影响调用。
__set( )方法:
格式 [修饰符] function __set(string $name,mixed $value){
... }
当我们直接为一个对象中非公有属性赋值时会自动调用此方法,并将属性名以第一个参数(string),值作为第二参数(mixed)传进此方法中。
__get( )方法:
格式:[修饰符] function __get(string $name){ ... }
当我们直接输出一个对象中非公有属性时会自动调用此方法,并将属性名以第一个参数传进去。
<?php
/*
* 只看封装的一部分, 方法的封装
*
*
* 将一些“特殊的方法 ” 加上一个 关键字 private修饰, 就不能拿到这个对象之后, 用对象中private有的内容, 但对象自己中的其它成员可以使用这个, 因为是自己用自己的成员
*
*
*
*/
class Person {
//成员属性
private $name;
private $age;
private $sex;
//构造方法
function __construct($name="", $age=0, $sex="男") {
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
function setSex($sex) {
if(!($sex=="男" or $sex =="女"))
return;
$this->sex = $sex;
}
function getAge() {
if($this->age < 20){
return $this->age;
}else if($this->age < 30){
return $this->age - 5;
}else if($this->age < 40) {
return $this->age - 8;
}else{
return 29;
}
}
//成员方法
function say() {
echo "我的名子是:{$this->name}, 我的年龄是:{$this->age}, 我的性别是:{$this->sex}.<br>";
}
function run() {
$this->left();
$this->left();
$this->right();
$this->right();
$this->go();
$this->go();
$this->go();
}
private function left() {
echo "迈左脚<br>";
}
private function right() {
echo "迈右脚<br>";
}
private function go() {
echo "前进<br>";
}
function eat() {
$this->say();
}
//析构方法
function __destruct() {
echo "再见:{$this->name} <br>";
}
}
$p1 = new Person("妹子", 88, "女");
//$p1->age=120;
// echo $p1->age;
// $p1 -> setSex("男");
//
echo $p1 -> getAge();
// echo $p1->say();
test.php
<?php
/*
* 只看封装的一部分, 方法的封装
*
*
* 将一些“特殊的方法 ” 加上一个 关键字 private修饰, 就不能拿到这个对象之后, 用对象中private有的内容, 但对象自己中的其它成员可以使用这个, 因为是自己用自己的成员
*
* 魔术方法:
*
* __get()
*
* 1. 自动调用: 是在直接访问私有成员时,自动调用! 一个参数
* __set()
* 1. 自动调用: 是在直接设置私有属性值时, 两个参数
*
* __isset() isset() 在使用isset()判断一个私有属性是否存在时, 自动调用__isset()魔术方法, 参数则是属性名称
* __unset() unset();
*
*/
class Person {
//成员属性
private $name;
private $age;
private $sex;
//构造方法
function __construct($name="", $age=0, $sex="男") {
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
function __unset($proname) {
echo "$proname !!!!!!!!!!!!!!!!<br>";
if($proname != "age") {
unset($this->$proname);
}
}
function __isset($proname) {
if($proname=="age")
return false;
return isset($this->$proname);
}
/*
function __get($pro) {
return $this->$pro;
}
function __set($name, $value) {
if($name=="age") {
if($value < 0 or $value > 100)
return;
}
$this->$name = $value;
}
*/
//成员方法
function say() {
echo "我的名子是:{$this->name}, 我的年龄是:{$this->age}, 我的性别是:{$this->sex}.<br>";
}
function eat() {
$this->say();
}
//析构方法
function __destruct() {
echo "再见:{$this->name} <br>";
}
}
$p1 = new Person("妹子", 88, "女");
unset($p1->name);
if(isset($p1->name)) {
echo "这个对象中的name是存的属性<br>";
}else{
echo "对象p1中不存在name属性";
}