PHP抽象类、接口

抽象类是使用abstract关键字声明的类。要将类中某个方法声明为抽象方法,只需要省略掉包含所有大括号的方法实现体,将方法声明的代码行用分号结束即可。

简单地说,当我们在创建一个基础对象的时候,其中所需的某些方法暂时并没有完整地定义出来,我们就可以用到抽象类。而后将方法中的细节推迟到继承者来实现。

比如定义一个 动物类,动物有 吃东西 这一方法,而每种动物吃东西的方式又不同,比如牛吃草,老虎吃肉。因此我们就可以将动物类定义为一个抽象类。

当然抽象类中也可以包括完整实现的方法,而不单单只有抽象方法,另外抽象类不能被实例化。

abstract class Food {
    public $name;

    abstract protected function getCount();
}

abstract class Animal {
    abstract function eat(Food $food);
}

继承抽象类的时候用关键字extends,PHP只支持单一继承,原因在于,当两个或更多的类定义了相同的方法时,多重继承会导致不必要的复杂性。在实现抽象方法的时候,不能高于声明抽象方法时的访问级别(private > protected > public)。

class Grass extends Food {
    public $name = 'grass';

    // 由于基类Food中此方法声明时为protected,所在这里不能用private修饰(可以用protected, public)
    public function getCount() {
        
    }
}

class Meat extends Food {
    public $name = 'meat';

    public function getCount() {
        
    }
}

class Cow extends Animal {
    public $name = 'cow';
    function eat(Food $food) {
        echo $this->name;
        if (!($food instanceof Grass)) {
            echo ' don\'t ';
        }
        echo ' eat ', $food->name, '.<br/>';
    }
}


$cow = new Cow();
$grass = new Grass();
$meat = new Meat();

// cow eat grass.
$cow->eat($grass);

// cow don't eat meat.
$cow->eat($meat);

接口是一种类似类的结构,通常用来声明API,而不关心如何实现这个API。接口中只能声明抽象方法。

interface IPerson {
    function marry($person);
}

实现接口用关键字implements,一个类要实现一个接口,必须实现接口中的所有方法。一个类可以实现多个接口,多个接口之间用逗号隔开。

class Person implements IPerson {
    protected $sex, $name, $age;

    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }

    public function marry($person) {
        if ($person instanceof Person) {
            echo 'You can marry.';
        } else {
            echo 'Oh no, you can\'t marry.';
        }
    }
}

// 当然下面还可以继续扩展
class Boy extends Person {
    public $sex = 'male';
}

class Girl extends Person {
    public $sex = 'female';
}

$boy = new Boy('cctv', 22);
$girl = new Girl('asdf', 21);
$boy->marry($girl);

posted on 2013-02-01 17:53  27_Man  阅读(449)  评论(0)    收藏  举报