PHP强化之18|PHP强化之18 - 抽象类与接口
[toc]
一、abstract
1、抽象类
在实际开发中,我们可以有这样一种类,是其它类的父类,但是他本身并不需要去实例化,主要用途是用于让子类来继承,这样可以达到代码的复用,同时利于项目设计者去设计类。
- 定义抽象类:
abstract class 类名{
//属性
//方法
}
- 继承抽象类
class 类名 extends 抽象类
{
}
2、抽象方法
抽象方法不能有方法体。所谓没有方法体就是在方法声明的时候没有大括号以及其中的内容,而是直接声明时在方法名后加上分号结束。
- 如:
abstract function 方法名();
3、注意
1)如果一个类使用了abstract来修饰,则该类就是抽象类(不能被实例化)。
2)抽象类可以没有抽象方法,同时还可以有实现了的方法。
3)一个类只要有abstract方法,则该类必须声明为abstract类。
4)抽象方法是作为子类方法重载的模板使用的,如果一个A类继承了一个抽象B类,则要求A类实现B类的所有抽象方法(除非A类也是抽象类)。
5)如果子类没有全部实现抽象类中的所有抽象方法,那么该子类也是一个抽象类,必须在 class 前面加上 abstract 关键字,并且不能被实例化。
6)抽象方法不能为private。
二、interface 1、简介
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。
接口是更加抽象的抽象类,抽象类可以存在有方法体的方法,而接口里的所有方法都没有方法体。
接口体现了程序设计的多态和高内聚低偶合的设计思想。
2、定义接口类
interface A
{
public function a();
Public function b();
}
3、实现接口类
class X implements A
{
public function a(){
}
public function a(){
}
}
4、注意
1)不能去实例化一个接口。
2)接口中的所有方法都不能有方法体。
3)一个接口可以继承多个其它接口。
4)一个类可以实现多个接口(用逗号隔开)。
5)接口中可以有属性,但必须是常量,默认是public。
6)接口的方法必须都是public,默认public。(但将常量变量放在接口中违背了其作为接口的作用而存在的宗旨,也混淆了interface与类的不同价值。所以不建议)
7)一个类可以同时继承又实现某些接口。(extends子句应该在implements子句之前)
8)任何实现接口的类都要实现接口中所定义的所有方法。
三、Abstract Class与Interface的异同 1、 相同点:
1)两者都是抽象类,都不能实例化。
2)interface 实现类及 abstract class 的子类都必须要实现已经声明的抽象方法。
2、不同点:
1)interface需要实现,要用 implements ;而 abstract class 需要继承,要用 extends 。
2)一个类可以实现多个 interface ,但一个类只能继承一个abstract class。
3) interface 中的每一个方法都是抽象方法,实现类必须要实现;而 abstract class 的子类可以有选择地实现。
4)接口中的抽象方法前不用也不能加 abstract 关键字,默认隐式就是抽象方法,也不能加 final 关键字来防止抽象方法的继承;而抽象类中抽象方法前则必须加上 abstract 表示显示声明为抽象方法。
5)接口中的抽象方法默认是 public 的,也只能是 public 的;而抽象类中的抽象方法则可以用 public 或 protected 来修饰,但不能用 private 。
四、Interface经典实例 需求:
我需要从不同的源收集文本。(可以从远程URL读取HTML,可以读取流资源,也可以收集终端命令的输出)
1、定义Documentable接口
实现Documentable接口的任何类都必须实现接口的getId()方法与getContent()方法。
2、定义三种实现方式
定义以上接口的用处是,我们可以分开定义获取文档的类,而且能使用十分不同的实现方式。
1)定义HtmlDocument类
url = $url;
}
public function getId()
{
return $this->url;
}
public function getContent()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
$html = curl_exec($ch);
curl_close($ch);
return $html;
}
}
2)定义StreamDocument类
resource = $resource;
$this->buffer = $buffer;
}
public function getId()
{
return 'resource-' . (int)$this->resource;
}
public function getContent()
{
$streamContent = '';
rewind($this->resource);
while (feof($this->resource) === false) {
$streamContent .= fread($this->resource, $this->buffer);
}
return $streamContent;
}
}
3)定义CommandOutputDocument类
command = $command;
}
public function getId()
{
return $this->command;
}
public function getContent()
{
return shell_exec($this->command);
}
}
3、定义DocumentStore类
getId();
$value = https://www.it610.com/article/$document->getContent();
$this->data[$key] = $value;
}
public function getDocuments()
{
return $this->data;
}
}
4、使用DocumentStore类
addDocument($htmlDoc);
// Add stream document
$streamDoc = new StreamDocument(fopen('stream.txt', 'rb'));
$documentStore->addDocument($streamDoc);
// Add terminal command document
$cmdDoc = new CommandOutputDocument('cat /etc/hosts');
$documentStore->addDocument($cmdDoc);
print_r($documentStore->getDocuments());
总结:
使用接口编写的代码更灵活,能委托别人实现细节。使用接口后会有起来越多的人使用你的代码,因为他们只需要知道如何实现接口,就可以无缝地使用你的代码。
源码地址:https://github.com/codeguy/modern-php/tree/master/02-features/interfaces
五、参考 【PHP强化之18|PHP强化之18 - 抽象类与接口】《Modern PHP》Josh Lockhart 著 安道 译
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 太平之莲
- 闲杂“细雨”
- 七年之痒之后
- 深入理解Go之generate
- 由浅入深理解AOP
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 生活随笔|好天气下的意外之喜
- 感恩之旅第75天
- python学习之|python学习之 实现QQ自动发送消息