在PHP5类中继续使用cons修饰常量。我们使用const定义一个常量,定义的这个常量不能被改变。在PHP5中const定义的常量与定义变量的方法不同,不需要加$修饰符。 const PI = 3.14; 这样就可以。
而使用const 定义的常量名称一般都大写,这是一个约定,在任何语言中都是这样。
如果定义的常量由多个单词组成,使用 _ 连接,这也是约定。
比如, MAX_MUMBER 这样的命名方式。一个良好的命名方式,是程序员必须注意的。
类中的常量使用起来类似静态变量,不同点只是它的值不能被改变。我们使用类名::常量名来调用这个常量。
<?php
//声明一个final类Math
class Math
{
const PI = 3.14;
public function __construct() {
return "这是Math类";
}
//这里写了一个算圆面积的方法,使用了Const常量,
//注意使用的方法,类似于静态变量。
public final function area($r) {
return $r * $r * self::PI;
}
public final function max($a, $b) {
return $a > $b ? $a : $b;
}
}
echo Math::PI;
?>
尝试为const定义的常量赋值,将会出现错误。
<?php
//说明一个final类Math
class Math
{
const PI = 3.14;
public funct ......
可以使用abstract来修饰一个类或者方法。
用abstract修饰的类表示这个类是一个抽象类,用abstract修饰的方法表示这个方法是一个抽象方法。
抽象类不能被实例化。
抽象方法是只有方法声明,而没有方法的实现内容。
abstract 抽象类
可以使用abstract来修饰一个类。
用abstract修饰的类表示这个类是一个抽象类。
抽象类不能被实例化。
这是一个简单抽象的方法,如果它被直接实例化,系统会报错。<?php
//定义一个抽象类
abstract class User
{
public function __toString() {
return get_class($this);
}
}
//实例化这个类会出现错误
echo new User();
?>
下面例子的 NormalUser 继承自 User类,就可以被实例化了。
<?php
//定义一个抽象类
abstract class User
{
public function __toString() {
return get_class($this);
}
}
//实例化这个类会出现错误
echo new User();
class NormalUser extends User
{
}
$a = new NormalUser();
echo "这个类" . $a . "的实例";
?>
单独设置一个抽象类是没有意义的,只有有了抽象方法,抽象类才有了血肉。下面介绍抽象方法。
abstract 抽象方法
用abstract修饰的类表示这个 ......
抽象类的应用就是典型的模版模式,先声明一个不能被实例化的模版,在子类中去依照模版实现具体的应用。
模版模式实例
我们写这样一个应用:
银行计算利息,都是利率乘以本金和存款时间,但各种存款方式计算利率的方式不同,所以,在账户这个类的相关方法里,只搭出算法的骨架,但不具体实现。具体实现由各个子类来完成。
<?php
//程序设计模式的模块部分
abstract class LoadAccount
{
//利息,本金
protected $interest, $fund;
public function calculateInterest() {
//取得利率
$this->interest = getInterestRate();
//用于计算利息的算法:本金*利率,但是利率的算法实现并没有在这个类中实现
$this->interest = $this->getFund() * $this->getInterstRate();
return $this->interest;
}
private function getFund() {
return $this->fund;
}
//.......
/*
* 不同类型的存款的利率不同,因此,
* 不在这个父类中实现率的计算方法,
* 而将他推迟到子类中实现
*/
protected abstract function getInterstRate();
}
?>
所有和计算利息的类都继承自这个类,而且必须实现其中的 getIntere ......
接口(interface)是抽象方法和静态常量定义的集合。
接口是一种特殊的抽象类,这种抽象类中只包含抽象方法和静态常量。
接口中没有其它类型的内容。
接口的定义
我们先写接口的定义,后面几节再介绍接口的意义。
下面的例子是接口的一个简单写法。
<?php
interface 接口名
{
}
?>
下面的例子定义了一个接口 User ,这个接口中有两个抽象方法,getName() 和setName()。能看到接口的写法和类很相似。
<?php
interface User
{
function setName($name);
function getName();
}
?>
接口中的抽象方法
注意,在接口中只能有抽象方法。如果在接口中出现了非抽象方法,会报错如下: Interface function User::setName() cannot contain body in ……….
<?php
interface User
{
function setName($name);
function getName(){} //这个地方是一个非抽象方法,会报错
}
?>
接口中抽象方法的修饰和访问权限
在接口中的抽象方法只能是public的,默认也是public权限。并且不能设置成 private 或者 protected 类型。否则会报错如下: Access type for interface method User::setName() must be omitted in &mdash ......
类实现接口要使用 implements 。类实现接口要实现其中的抽象方法。一个类可以实现多个接口。
一个类可以使用 implements 实现接口,甚至可以实现多个接口。
大部分的书说,这样是为了实现PHP的多继承。为什么呢?
PHP5是单继承的,一个类只可以继承自一个父类。接口可以实现多个,这样就是多继承了。
这样说有些道理。但,既然接口里面的方法没有方法体,所谓的多继承又有什么意义?
接口的意义在于后面一节继续说的多态。
使用implements实现接口
使用implements来实现一个接口。如果实现接口而没有实现其中的抽象方法,会报错如下。
<?php
interface User
{
const MAX_GRADE = 99; //此处不用声明,就是一个静态常量
function setName($name);
static function getName() {
}
}
class NoumalUser implements User
{
}
?>
Fatal error: Interface function User::getName() cannot contain body in C:\wamp\www\tt.php on line 5 实现接口要实现方法。注意静态变量的使用。
<?php
interface User
{
const MAX_GRADE = 99; //此处不用声明,就是一个静态常量
function setName($name);
function getName();
}
//实现接口
cl ......
一个接口可以继承自另外的接口。PHP5中的类是单继承,但是接口很特殊。一个接口可以继承自多个接口。
一个接口继承其它接口时候,直接继承父接口的静态常量属性和抽象方法。
在PHP5中,接口是可以继承自另外一个接口的。这样代码的重用更有效了。
要注意只有接口和接口之间使用 继承关键字extends。
类实现接口必须实现其抽象方法,使用实现关键字 implements。
接口实现继承
要注意只有接口和接口之间使用 继承关键字extends。
类实现接口必须实现其抽象方法,使用实现关键字 implements。
这个例子定义接口User,User有两个抽象方法getName和setName。又定义了接口VipUser,继承自User接口,并增加了和折扣相关的方法getDiscount。最后定义了类 Vip ,实现了VipUser接口。并实现了其中的三个方法。
<?php
interface User
{
function getName();
function setName($_name);
}
interface VipUser extends User
{
function getDiscount(); //此处添加了一个抽象的方法
}
class Vip implements VipUser
{
private $name;
private $discount = 0.8; //折扣变量
function getName() {
return $this->name;
}
function setName($_name) ......