前文说到,封装性是面向对象的三大特征之一。它的核心思想在于把数据域隐藏,使其相对独立并提供相应的方法对其进行操作。它的好处在于能有效防止数据被篡改以及使得类更易于维护。封装性强调以下两点
- 把对象的属性和方法结合,形成一个不可分割的独立单位
- 信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系
封装的原则在软件上的反映是:要求使对象以外的部分不能随意存取对象的内部数据(属性),从而有效的避免了外部错误对它的”交叉感染”,使软件错误能够局部化,大大减少查错和排错的难度。
举个栗子,假设我们有个模拟账户的类,他有账户名与密码两个被封装的属性,只提供查询功能
<?php
class id {
//被 private 修饰的变量只能在类的内部被访问
private $username;
private $password;
function __construct($username,$password) {
$this->username=$username;
$this->password=$password;
}
function getUsername() {
return $this->username;
}
function getPassword() {
return $this->password;
}
}
$id1 = new id("angelment","123");
echo $id1->getUsername()."<br>".$id1->getPassword();
/*
正确的输出方式如上所示
若采用 echo $id1->username."<br>".$id1->password;
进行输出将会报错,被 private 关键字修饰的变量无法在类外被访问
*/
?>
同理,方法也可以被 private 修饰,使其变成只能在类的内部使用:
<?php
class id {
//被 private 修饰的变量只能在类的内部被访问
private $username;
private $password;
function __construct($username,$password) {
$this->username=$username;
$this->password=$password;
}
function getUsername() {
return $this->myUsername();
}
function getPassword() {
return $this->myPassword();
}
//被 private 修饰的方法也只能在类的内部被访问
private function myUsername() {
return $this->username;
}
private function myPassword() {
return $this->password;
}
}
$id1 = new id("angelment","123");
echo $id1->getUsername()."<br>".$id1->getPassword();
/*
正确的输出方式如上所示
若采用 echo $id1->username."<br>".$id1->password;
或者 echo $id1->myUsername()."<br>".$id1->myPassword();
进行输出将会报错,被 private 关键字修饰的变量和方法均无法在类外被访问
*/
?>
总结起来,被 private 关键字修饰的属性与方法可视为在他们在类外部是“不可见的”。我们要在类的外部修改这些“不可见的”属性的值或者调用这些“不可见的”方法,就要在类的内部定义一些“可见的”方法,通过这些“可见的”内部的方法来对这些外部“不可见”的内容进行编辑修改或使用
封装的好处是显而易见的,假如我们有如下圆类,我们知道,圆的半径需大于零,若不把半径 $radius 封装起来,就有可能会被错误地赋值
<?php
class circle {
//使用 private 关键字使其在类的外部“不可见”
private $radius;
//为外部提供查询 $radius 的方法
function getRadius() {
return $this->radius;
}
//为外部提供修改 $radius 的方法
function setRadius($radius) {
//调用内部方法
$this->setter($radius);
}
//内部方法,判断半径输入是否正确
private function setter($radius) {
if ($radius > 0) {
$this->radius=$radius;
}else{
echo "Error: radius <= 0";
}
}
}
?>
发表回复