众所周知,面向对象的编程语言有三大特性,分别是:封装、继承和多态。
面向对象的封装特性就是将类中的成员属性和方法内容细节尽可能地隐藏起来,确保类外部代码不能随意访问类中的内容。
面向对象的继承特性使得子类可继承父类中的属性和方法,提高类代码的复用性。
面向对象的多态特性是最常用到的一种特性。所谓多态,是指同一个东西不同形态的展示。
PHP 也是面向对象的编程语言,它也支持这三大特性。
可使用 public、protected、private 来修饰对象的属性和方法。使用不同修饰符的属性和方法其可被访问的权限也不同:
关于修饰符的使用示例如下:
<?php
class yourclass{
public $name;
private $age;
protected $weight;
function __construct($name,$age,$weight){
$this->name = $name;
$this->age = $age;
$this->weight = $weight;
}
private function get($key){
return $this->$key;
}
}
class hisclass extends yourclass{
function key($key){
//父类中get方法为private, 子类中不可访问, 故重新定义一个相同功能的函数
return $this->$key;
}
}
$obj = new yourclass('tom',22,'60kg');
echo $obj->name;
//echo $obj->age; // 将会报错
echo $obj->get('age'); // 可通过调用公共方法访问
$son = new hisclass('jim',23,'70kg');
echo $son->name;
echo $son->key('weight');
echo $son->key('age'); // 访问不到$age
?>
执行以上程序的输出结果为:
把一个类作为公共基类,其他的类继承自这个基类,则其他类中都具有这个基类的属性和方法,其他类也可各自额外定义自己不同的属性和方法。
类的继承使用关键词extends,在子类中可使用parent访问父类的方法。在子类中可重写父类的方法。
关于类继承特性的代码如下:
<?php
class yourclass{
public $name;
private $age;
protected $weight;
function __construct($name,$age,$weight){
$this->name = $name;
$this->age = $age;
$this->weight = $weight;
}
function like(){
echo "I like money. ";
}
function age(){
echo $this->name . ' is ' . $this->age . 'years old';
}
protected function get($key){
return $this->$key;
}
function set($key,$value){
$this->$key = $value;
}
}
class hisclass extends yourclass{
function get($key){ //重写父类方法
echo $this->key;
}
function what(){
parent::like(); //子类中访问父类方法
}
function getAge(){
$this->age(); //调用从父类继承来的方法
}
}
$obj = new hisclass('tom',22,'60kg'); //使用继承自父类的__construct方法初始化实例
$obj->get('name');
$obj->what();
$obj->set('age',33);
$obj->getAge();
?>
执行以上程序的输出结果为:
多态通过继承复用代码而实现,可编写出健壮可扩展的代码,减少流程控制语句(if else)的使用,例如:
<?php
class animal{
function can(){
echo "this function weill be re-write in the children";
}
}
class cat extends animal{
function can(){
echo "I can climb";
}
}
class dog extends animal{
function can(){
echo "I can swim";
}
}
function test($obj){
$obj->can();
}
test(new cat());
test(new dog());
?>
上述例子便体现了面向对象的多态性,可以改进代码将 animal 类定义为抽象类,或者使用接口都是可以的,这样就无须在父类的方法中定义无意义的函数体了。