7.5.3 PHP面向對象封裝性之魔術方法1
封裝性是面向對象編程中的三大特性之一,封裝就是把對象中的成員屬性和成員方法加上訪問修飾符,使其盡可能隱藏對象的內部細節,以達到對成員的訪問控制(切記不是拒絕訪問)。
這是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屬性";
}