封装
封装性是面向对象编程中的三大特性之一,封装性就是把对象的成员属性和成员方法结合成一个独立的相同的单位。并尽可能隐藏对象内部的细节。
设置私有成员
在声明成员属性和成员方法时,使用private关键字修饰就实现了对成员的封装。封装后在成员的外部不能被访问,但在对象内部的成员方法中可以访问到自己对象内部被封装的成员属性和被封装的成员方法。
<?php
header('content-type:text/html;charset=utf-8');
class Person{
private $name;
private $sex;
private $age;
function __construct($name,$sex="男",$age=1){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
function run(){
echo $this->name."在走路时".$this->leftleg()."再".$this->rightleg();
}
private function leftleg(){
return "迈左腿";
}
private function rightleg(){
return "迈右腿";
}
}
$person1=new Person("张三");
$person1->run();
$person1->name="李四";//name属性被封装,不能在对象外部给私有属性赋值
echo $person1->age;//age属性被封装,不能再对象外部获取私有属性的值
$person1->leftleg();//lefteg方法被封装,不能再对象外部调用对象中的私有方法。
//结果
张三在走路时迈左腿再迈右腿
Fatal error: Cannot access private property Person::$name in D:\WWW\class.php on line 24
Fatal error: Cannot access private property Person::$age in D:\WWW\class.php on line 25
Fatal error: Call to private method Person::leftleg() from context '' in D:\WWW\class.php on line 26
私有成员的访问
对象中的成员属性一旦被private关键字封装成私有之后,就只有在对象内部的成员方法中使用。不能被对象外部直接赋值,也不能在对象外部直接获取私有属性的值。如果不让用户在对象的外部设置私有属性的值,但可以获取私有属性的值,或者允许用户对私有属性赋值,但需要限制一些赋值的条件,解决方法就是在对象内部声明一些操作私有属性的公有方法。在对象外部就可以将公有方法作为访问接口,间接的访问对象内部成员。
<?php
header('content-type:text/html;charset=utf-8');
class Person{
private $name;
private $sex;
private $age;
function __construct($name,$sex="男",$age=1){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
public function getName(){
return $this->name;
}
public function setSex($sex){
if($sex=='男' ||$sex='女'){
return $sex;
}
}
public function setAge($age){
if($age>150||$age<0){
return ;
}
return $thi->age=$age;
}
public function getAge(){
if($this->age>30){
return $this->age-10;
}
return $this->age;
}
public function say(){
echo "我的姓名:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
}
}
$person1=new Person("张三");
echo $person1->getName().'<br/>';
$person1->setSex('女');
$person1->setAge(200);
echo $person1->getAge().'<br/>';
$person1->say();
//结果
张三
1
我的姓名:张三 性别:男 年龄:1
PHP系统中还我们提供了很多预定义的方法,来处理有关封装的一些魔法方法。
魔法方法__set
void __set(sting name,mixed value)
该方法的作用是在程序运行过程中为私有的成员属性设置值时自动调用的,它不需要返回值,但它需要两个参数,第一个是为私有属性设置值的属性名,第二个是属性设置的值。这个方法不需要我们主动调用,可以在方法前面加上private关键字修饰,防止用户直接调用它。如果不在类中添加这个方法而直接赋值,则会出现“不能访问某个私有属性”错误。
<?php
header('content-type:text/html;charset=utf-8');
class Person{
private $name;
private $sex;
private $age;
function __construct($name,$sex="男",$age=1){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
private function __set($propertyName,$propertyValue){
if($propertyName=='sex'){
if(!($propertyValue=='男' || $propertyValue=='女'))
return ;
}
if($propertyName=='age'){
if($propertyValue>150 || $propertyValue<0)
return ;
}
return $this->propertyValue=$propertyValue;
}
public function say(){
echo "我的姓名:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
}
}
$person1=new Person("张三");
$person1->sex='女';
$person1->age=200;
$person1->say();
//结果
我的姓名:张三 性别:男 年龄:1
魔术方法__get()
mixed __get(string name)
该方法的作用是在程序运行过程中,通过它可以在对象的外部获取私有成员属性的值时自动调用。 它有一个必要的参数,需要传入在获取私有属性值时的属性名,并返回一个值,是在这个方法处理后允许对象外部使用的值。也可以在这个方法前加上private关键字修饰,防止用户直接去调用它。如果不在类中添加这个方法而直接获取,则会出现“不能访问某个私有属性”错误。
<?php
header('content-type:text/html;charset=utf-8');
class Person{
private $name;
private $sex;
private $age;
function __construct($name,$sex="男",$age=1){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
private function __get($propertyName){
if($propertyName=='sex'){
return '保密';
}else if($propertyName=='age'){
if($this->age>30){
return $this->age-10;
}else{
return $this->$propertyName;
}
}else{
return $this->$propertyName;
}
}
}
$person1=new Person("张三",'男',40);
echo $person1->name.'<br/>';
echo $person1->sex.'<br/>';
echo $person1->age.'<br/>';
//结果
张三
保密
30
魔术方法__isset() 和 魔术方法 __unset()
bool __isset(string)
我们知道”isset()”函数,它是用来测定变量是否存在的函数。如果对象中的成员是公有的,我们可以直接用这个函数来测定,如果是私有的,这个函数就不起作用了。原因就是是私有的,在对象外部不可见。这是就要借助__isset()魔术方法,在对象的外部使用isset()方法测定对象中的成员时,就会自动调用__isset()方法,间接地帮助我们完成对对象中私有成员属性的测定。为了防止用户主动调用这个方法,也需要用private关键字封装在对象中。
bool __unset(string)
我们知道unset()函数,它的作用就是删除指定的变量。如果对象中的成员是公有的,我们可以直接用个函数删除指定的变量名称,如果对象中的成员时私有的,就需要在类中添加__unset()方法。在对象外部使用unset()方法时,就会自动调用__unset()方法,间接地将私有的成员属性删除。也可以在__unset()方法中限制一些条件,阻止删除一些重要的属性。
<?php
header('content-type:text/html;charset=utf-8');
class Person{
private $name;
private $sex;
private $age;
function __construct($name,$sex="男",$age=1){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
private function __isset($propertyName){
if($propertyName=='name')//name不允许测定
return false;
return isset($this->$propertyName);
}
private function __unset($propertyName){
if($propertyName=='name')//不能删除name的值
return ;
unset($this->$propertyName);
}
public function say(){
echo "我的名字:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
}
}
$person1=new Person("张三",'男',40);
var_dump(isset($person1->name));
var_dump(isset($person1->sex));
var_dump(isset($person1->age));
unset($person1->name);
unset($person1->sex);
unset($person1->age);
$person1->say();
//结果
bool(false) bool(true) bool(true)
我的名字:张三 性别: 年龄: