类和对象

php支持面向对象的编程方式。下面代码创建了一个类,并使用关键字new初始化了一个类的实例。

<?php

class Car
{
    var $name = '汽车';

    function getName()
    {
        return $this->name;
    }
}

//实例化一个car对象
$car = new Car();
$car->name = '奥迪A6'; //设置对象的属性值
echo $car->getName();  //调用对象的方法 输出对象的名字
?>

注意:定义成员变量$name时,有$符号,从实例中引用该成员变量时,则没有$car->name

类的继承

面向对象编程中,继承是一种扩展类功能的手段,PHP支持单继承。继承一个类,使用extends关键字。

<?php

class Animal
{
    public function eat()
    {
        echo '吃东西';
    }

    public function sleep()
    {
        echo '睡觉';
    }
}

class Dog extends Animal
{
    public function bark()
    {
        echo '狗叫';
    }
}

$a = new Dog();
$a->eat();
$a->sleep();
$a->bark();
?>

类的序列化和反序列化

<?php

class Car
{
    public $speed = 0;
    public $weight = 100;
}

$car = new Car();
$car_ser = serialize($car);
$car = unserialize($car_ser);
echo $car->speed;
echo $car->weight;
?>

php中可以用serialize()unserialize()将类序列化为字符串或反序列化,序列化的好处是便于在网络上传输或是存储到磁盘。

类成员的访问控制修饰符

  • public 任意位置可以访问
  • protected 只有本类和子类中可以访问
  • private 只有本类中可以访问
<?php

class Car
{
    private $name = '汽车';

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }
}

$c = new Car();
$c->setName("汽车2");
echo $c->getName();

?>

注意:和之前的代码不同,$name前没写var,而是直接加上了private,这是历史原因造成的,一开始php没有访问控制修饰符,所有成员都是public,后来引入了这个特性,又改成了新的写法。这里建议和Java一样,定义类时严格写好所有的访问控制修饰符。

静态成员变量和方法

和Java一样,静态成员变量和方法可以直接使用类名进行调用,不需要实例化。

<?php

class Car
{
    public static $name = "汽车";

    public static function echoName()
    {
        echo Car::$name;
    }
}

Car::echoName();

?>

构造函数和析构函数

php的构造函数和Java用法差不多,注意子类的构造函数如果需要调用父类的构造函数,就要显示的使用parent::__construct(),类似Java的super()。除此之外,调用父类的其他方法也都是parent::父类方法()的形式。

php具有“析构函数”,但显然php并不是一个由程序员手动控制内存的语言,php类实例的销毁时机是该类没有任何引用指向时。和Java的finalize()一样,实际上用的不多。

<?php

class A
{
    protected $value;

    function __construct($value)
    {
        $this->value = $value;
        print "A构造函数被调用 \n";
    }

    function __destruct()
    {
        print "A析构函数被调用 \n";
    }
}

class B extends A
{
    function __construct($value)
    {
        parent::__construct($value);
        print "B构造函数被调用 \n";
    }
}

$b = new B("aaa");

?>

方法和属性重载

php能够实现方法重载,但是php是弱类型语言,因此实现上比较怪异,php的“重载”和这两个字的意思也不太一样。在php中,通过“魔术方法”,动态的创建、删除类属性和方法,这种做法叫做“php的重载”,它可以实现强类型语言的“函数重载”。

属性重载

属性重载涉及4个方法,__set()__get()__isset()__unset(),分别代表动态设置属性,取得属性值,判断是否设置了某个属性,取消设置属性。

<?php

class Car
{
    private $ary = array();

    public function __set($key, $val)
    {
        $this->ary[$key] = $val;
    }

    public function __get($key)
    {
        if (isset($this->ary[$key])) {
            return $this->ary[$key];
        }
        return null;
    }

    public function __isset($key)
    {
        if (isset($this->ary[$key])) {
            return true;
        }
        return false;
    }

    public function __unset($key)
    {
        unset($this->ary[$key]);
    }
}

$car = new Car();
$car->name = '汽车';  //name属性动态创建并赋值
echo $car->name;
?>

方法重载

方法重载使用__call()实现。

<?php

class Car
{
    public $speed = 0;

    public function __call($name, $args)
    {
        if ($name == 'speedUp') {
            $this->speed += 10;
        }
    }
}

$car = new Car();
$car->speedUp(); //调用不存在的方法会使用重载
echo $car->speed;
?>

php的“重载”,不仅难写,还难读,除非编写考虑到易用性的库或框架,否则一般是不会用的。

为对象动态绑定属性

PHP也可以像JavaScript那样,为一个已经实例化了的对象直接使用赋值的写法添加一个属性。

<?php

class Foo
{
}

$f = new Foo();
$f->x = 1;
$f->y = 2;

echo $f->x;
echo $f->y;
?>
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。