抽象类abstract
抽象类的定义方法如下:
abstract class Test {
}
抽象类的特点:
- 抽象类不能被实例化
- 一个类只要含有一个抽象方法,就必须声明为抽象类。抽象类必须至少含有一个抽象方法
- 继承了一个抽象类,子类必须定义父类中的所有抽象方法
- 抽象方法不用实现具体功能,交由子类完成
- 当子类实现抽象类的方法时,这些方法的访问控制可以和父类中的一致,也可以有高的可见性,但是不能有更低的可见性。例如:某个抽象方法声明为protected的,那么子类中实现的方法就应该声明为protected或者publicd的,而不能声明为private
- 一个类只能继承一个抽象类
- 如果抽象方法有参数,那么子类的实现也必须有相同的参数个数,只能多不能少,但是多余的参数必须要有默认值。
<?php
// 定义一个抽象类
abstract class Test {
// 定义一个抽象方法,一个抽象类至少含有一个抽象方法
abstract public function demo($name);
}
class Code extends Test {
public function demo($name, $intro = 'none') {
echo $name . ' ' . $intro . "\n";
}
}
$code = new Code();
$code->demo('codehui'); # 输出 codehui none
$code->demo('codehui', 'phper'); # 输出 codehui phper
接口interface
# 接口的定义方法
<?php
interface Test {
}
# 实现一个接口
class Code implements Test {
}
使用接口interface,可以指定某个类必须实现哪些方法,单不需要定义这些方法的具体内容。接口是通过关键词interface关键词来实现的,接口中定义的所有方法都是共有的而且没有方法体。
接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。接口中还可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。
要实现一个接口类,可以使用关键词implements来完成,类中必须实现接口中定义的所有方法,虽然php不支持多继承,但是一个类可以实现多个接口,用逗号来分割多个接口的名称。
下面写一个接口的使用示例:
<?php
# 声明一个接口
interface Test {
const VERSION = '1.0.0';
function set($key, $val);
function get($key);
}
# 实现接口
class Code implements Test {
private $name;
function set($key, $val){
$this->name[$key] = $val;
}
function get($key){
return $this->name[$key];
}
public function getAll(){
return $this->name;
}
}
$code = new Code();
$code->set('name', 'codehui');
echo $code->get('name') . "\n"; # 输出 codehui
$code->set('hobby', 'code');
echo $code->get('hobby') . "\n"; # 输出 code
// 获取静态变量
echo Code::VERSION . "\n"; # 输出 1.0.0
print_r($code->getAll());
# 输出
Array
(
[name] => codehui
[hobby] => code
)
接口和抽象类的区别
抽象类:PHP5支持抽象类和抽象方法,被定义为抽象的类不能被实例化。任何一个类如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方法和参数,不能定义其具体的功能实现。抽象类通过关键字abstract来声明。
接口:可以指定某个类必须实现哪个方法,但不需要定义这些方法的具体内容。在这种情况下,可以通过interface关键字来定义一个接口,在接口中声明对的方法都不能有方法体。
二者虽然都是定义了抽象的方法,但是事实上两者区别还是很大的,主要区别如下:
- 对接口的实现是通过关键词implements来实现的,而抽象类继承则是使用类继承的关键字extends实现的
- 接口没有数据成员(可以有常量),但是抽象类有数据成员(各种类型的成员表变量),抽象类可实现数据的封装
- 接口没有构造函数,抽象类可以有构造函数
- 接口中的方法都是public类型,抽象类可以有构造函数
- 一个类可以同时实现多个接口,但是只能实现一个抽象类