1. <?php
  2. /*
  3. PHP 5 introduces abstract classes and methods. Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature - they cannot define the implementation.
  4.  
  5. PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
  6.  
  7. When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private. Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same. For example, if the child class defines an optional argument, where the abstract method's signature does not, there is no conflict in the signature. This also applies to constructors as of PHP 5.4. Before 5.4 constructor signatures could differ.
  8. 继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。 这也适用于 PHP 5.4 起的构造函数。在 PHP 5.4 之前的构造函数声明可以不一样的。
  9.  
  10. */
  11.  
  12. abstract class AbstractClass
  13. {
  14. //Force Extending class to define this method
  15. // 强制要求子类定义这些方法
  16. abstract protected function getValue();
  17. abstract protected function prefixValue($prefix);
  18.  
  19. // Common method 普通方法(非抽象方法)
  20. public function printOut(){
  21. print $this->getValue().'<br>';
  22. }
  23. }
  24.  
  25. class ConcreteClass1 extends AbstractClass
  26. {
  27. protected function getValue(){
  28. return 'ConcreteClass1';
  29. }
  30.  
  31. public function prefixValue($prefix){
  32. return "{$prefix}".'ConcreteClass1';
  33. }
  34. }
  35.  
  36. class ConcreteClass2 extends AbstractClass
  37. {
  38. public function getValue(){
  39. return 'ConcreteClass2';
  40. }
  41.  
  42. public function prefixValue($prefix){
  43. return "{$prefix}".'ConcreteClass2';
  44. }
  45. }
  46.  
  47. /*
  48. class ConcreteClass3 extends AbstractClass
  49. {
  50. private function getValue(){
  51. return 'ConcreteClass3';
  52. }//Fatal error: Access level to ConcreteClass3::getValue() must be protected (as in class AbstractClass) or weaker in
  53.  
  54. public function prefixValue($prefix){
  55. return "{$prefix}".'ConcreteClass3';
  56. }
  57. }
  58. */
  59.  
  60. $class1 = new ConcreteClass1;
  61. $class1->printOut();
  62. echo $class1->prefixValue('FOO_').'<br>';
  63.  
  64. $class2 = new ConcreteClass2;
  65. $class2->printOut();
  66. echo $class2->prefixValue('FOO_').'<br>';
  67.  
  68. abstract class AbstractClassB
  69. {
  70. // Our abstract method only needs to define the required arguments
  71. // 我们的抽象方法仅需要定义需要的参数
  72. abstract protected function prefixNameB($name);
  73. }
  74.  
  75. class ConcreteClassB extends AbstractClassB
  76. {
  77. // Our child class may define optional arguments not in the parent's signature
  78. // 我们的子类可以定义父类签名中不存在的可选参数
  79. public function prefixNameB($name, $separator = '.'){
  80. if ($name == 'Pacman') {
  81. $prefix = 'Mr';
  82. } elseif ($name == 'Pacwoman') {
  83. $prefix = 'Mrs';
  84. } else {
  85. $prefix = '';
  86. }
  87. return "{$prefix}{$separator} {$name}";
  88. }
  89. }
  90.  
  91. $classB = new ConcreteClassB;
  92. echo $classB->prefixNameB('Pacman'), '<br>';
  93. echo $classB->prefixNameB('Pacwoman'), '<br>';
  94.  
  95. /*
  96. Object Interfaces
  97. Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled.
  98. Interfaces are defined in the same was as a class, but with the interface keyword replacing the class keyword and without any of the methods having their contents defined.
  99. All methods declared in an interface must be public; this is the nature of an interface.
  100. 对象接口
  101. 使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
  102. 接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
  103. 接口中定义的所有方法都必须是公有,这是接口的特性。
  104.  
  105. implements
  106. To implement an interface, the implements operator is used. All methods in the interface must be implemented within a class; failure to do so will result in a fatal error. Classes may implement more than one interface if desired by separating each interface with a comma.
  107. Note:
  108. Prior to PHP 5.3.9, a class could not implement two interfaces that specified a method with the same name, since it would cause ambiguity. More recent versions of PHP allow this as long as the duplicate methods have the same signature.
  109. Note:
  110. Interfaces can be extended like classes using the extends operator.
  111. Note:
  112. The class implementing the interface must use the exact same method signatures as are defined in the interface. Not doing so will result in a fatal error.
  113. Constants
  114. It's possible for interfaces to have constants. Interface constants works exactly like class constants except they cannot be overridden by a class/interface that inherits them.
  115. 实现(implements)
  116. 要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。
  117. Note:
  118. 实现多个接口时,接口中的方法不能有重名。
  119. Note:
  120. 接口也可以继承,通过使用 extends 操作符。
  121. Note:
  122. 类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误。
  123. 常量
  124. 接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。
  125.  
  126. */
  127.  
  128. // Declare the interface 'iTemplate'
  129. interface iTemplate
  130. {
  131. public function setVariable($name, $var);
  132. public function getHtml($template);
  133. }
  134.  
  135. // Implement the interface
  136. // This will work
  137.  
  138. class Template implements iTemplate
  139. {
  140. private $vars = array();
  141.  
  142. public function setVariable($name, $var)
  143. {
  144. $this->vars[$name] = $var;
  145. }
  146.  
  147. public function getHtml($template)
  148. {
  149. foreach ($this->vars as $name => $value) {
  150. $template = str_replace('{'.$name.'}', $value, $template);
  151. }
  152. return $template;
  153. }
  154. }
  155.  
  156. /*
  157. class BadTemplate implements iTemplate
  158. {
  159. private $var = array();
  160. public function setVariable($name, $var)
  161. {
  162. $this->vars[$name] = $var;
  163. }
  164. }
  165. Fatal error: Class BadTemplate contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (iTemplate::getHtml)
  166.  
  167. */
  168.  
  169. /*
  170. class BadTemplate implements iTemplate
  171. {
  172. private $vars = array();
  173.  
  174. public function setVariable($name, $var,$echo)
  175. {
  176. //Fatal error: Declaration of BadTemplate::setVariable() must be compatible with iTemplate::setVariable($name, $var)
  177.  
  178. $this->vars[$name] = $var;
  179. echo $echo;
  180. }
  181.  
  182. public function getHtml($template)
  183. {
  184. foreach ($this->vars as $name => $value) {
  185. $template = str_replace('{'.$name.'}', $value, $template);
  186. }
  187. return $template;
  188. }
  189. }
  190. */
  191.  
  192. /*
  193. class BadTemplate implements iTemplate
  194. {
  195. private $vars = array();
  196.  
  197. // Fatal error: Access level to BadTemplate::setVariable() must be public (as in class iTemplate)
  198.  
  199. protected function setVariable($name, $var)
  200. {
  201.  
  202. $this->vars[$name] = $var;
  203. }
  204.  
  205. public function getHtml($template)
  206. {
  207. foreach ($this->vars as $name => $value) {
  208. $template = str_replace('{'.$name.'}', $value, $template);
  209. }
  210. return $template;
  211. }
  212. }
  213.  
  214. */
  215.  
  216. interface a
  217. {
  218. public function foo();
  219. }
  220.  
  221. interface b extends a
  222. {
  223. public function baz(Baz $baz);
  224. }
  225.  
  226. class c implements b
  227. {
  228. public function foo()
  229. {
  230.  
  231. }
  232.  
  233. public function baz(Baz $baz)
  234. {
  235.  
  236. }
  237. }
  238.  
  239. /*
  240. Fatal error: Declaration of d::baz() must be compatible with b::baz(Baz $baz)
  241.  
  242. class d implements b
  243. {
  244. public function foo()
  245. {
  246.  
  247. }
  248.  
  249. public function baz(Foo $foo)
  250. {
  251.  
  252. }
  253. }
  254. */
  255.  
  256. //Multiple interface inheritance 继承多个接口
  257.  
  258. interface a1
  259. {
  260. public function foo();
  261. }
  262.  
  263. interface b1
  264. {
  265. public function bar();
  266. }
  267.  
  268. interface c1 extends a1, b1
  269. {
  270. public function baz();
  271. }
  272.  
  273. class d1 implements c1
  274. {
  275. public function foo()
  276. {
  277. }
  278.  
  279. public function bar()
  280. {
  281. }
  282.  
  283. public function baz()
  284. {
  285. }
  286. }
  287.  
  288. //Interfaces with constants 使用接口常量
  289. interface a2
  290. {
  291. const b2 = 'Interface constant';
  292. }
  293.  
  294. echo a2::b2;
  295.  
  296. /*
  297. Fatal error: Cannot inherit previously-inherited or override constant b2 from interface a2
  298. 错误写法,因为常量不能被覆盖。接口常量的概念和类常量是一样的。
  299.  
  300. class c2 implements a2
  301. {
  302. const b2 ='Class constant';
  303. }
  304.  
  305. */

http://php.net/

小结:

0-子类需定义抽象类所有方法,方法参数个数可以添加,访问控制同或弱,而对象接口的实现也需要实现全部方法,但是参数个数不可更改,且访问控制必须public。

发问:

0-框架中的实例?

//2016/8/29-9:11

Abstract Class vs. Interface
The difference between an interface and an abstract class may seem subtle. Remember that an abstract class is meant to be extended by a more specific class, of which you’ll probably create an object instance. As you’ve already seen, an abstract class might define a generic object, such as a shape.
Conversely, an interface is not inherited by a class, so you should not think of an interface as a way of loosely defining an entire object. Instead, an interface establishes a contract for the functionality that a class must have, regardless of the class type. For
example, in Chapter 8, “Using Existing Classes,” you’ll learn about the Iterator interface defined within the Standard PHP Library (SPL). The Iterator interface dictates the methods that must exist in a class in order for PHP to be able to loop through an
instance of that class.
Another way of distinguishing between abstract classes and interfaces is that abstract classes still have an “is a” relationship with the derived class. Interfaces do not have “is a” relationships with derived classes, although you could say that the derived class has a “has the same behaviors as” relationship with an interface.
In the next example, let’s create an interface for standard CRUD
functionality. The acronym CRUD refers to the ability to Create, Read, Update, and Delete data—the four basic actions required for many different types of content used in sites and applications.
Any class you use in an application that requires CRUD functionality could then implement this interface, whether it’s a User,Page, or Rectangle.
 
//一个抽象类会被扩展成一个特定的类,抽象类和它的继承类之间有一种“是一个”的关系,而接口是不同类的合约,‘契约’。
// 建立动物的抽象类,它的继承类都是动物而不能是植物;建立‘死亡’的接口,它的继承类既可以是动物也可以是植物,但必须执行‘死亡’方法。
 
 
Programming by Contract
In simple terms, programming by contract is the practice of declaring an interface before writing a class. This can be particularly useful for guaranteeing the encapsulation of your classes.Using the programming by contract technique, you will be able to identify the capabilities you are trying to implement before building your application, much in the same way an architect creates plans for a building before it is constructed.
Development teams frequently program by contract because of the many workflow improvements this technique brings. By defining the interaction of classes before any implementation begins, the team members know exactly what their objects must do; it is then fairly trivial to implement the required methods. When the interface is fully implemented, testing of the class will be conducted using only the rules defined in the interface.In the car example you’ve seen in previous sections, the ISpeedInfo interface could be considered a contract, as it is the only point of API interaction of which either class, Car or Street, needs to be aware. The Street class will test for this contract before accepting the object for interaction. One developer could then be assigned to create a Car class and another to create a Street class, and the two would not need to collaborate on the implementation beyond the IStreetInfo interface.
契约式编程

Class Abstraction -- Object Interfaces的更多相关文章

  1. Object Pascal中文手册 经典教程

    Object Pascal 参考手册 (Ver 0.1)ezdelphi@hotmail.com OverviewOverview(概述)Using object pascal(使用 object p ...

  2. .net Framework Class Library(FCL)

    from:http://msdn.microsoft.com/en-us/library/ms229335.aspx 我们平时在VS.net里引用的那些类库就是从这里来的 The .NET Frame ...

  3. Windows Python Extension Packages

    备注: 1.先要安装wheel库:pip install wheel 2.下载wheel,切换至下载路径,然后安装:pip install wheel库名.whl Windows Python Ext ...

  4. python 不同版本下载资源

    Unofficial Windows Binaries for Python Extension Packages by Christoph Gohlke, Laboratory for Fluore ...

  5. Atitit cms wordpress get_post  返回的WP_Post 规范 标准化

    Atitit cms wordpress get_post  返回的WP_Post 规范 标准化 public $ID; public $post_author = 0; * The post's l ...

  6. Google 如何修复 TrustManager 实施方式不安全的应用

    引用谷歌市场的帮助说明:https://support.google.com/faqs/answer/6346016 本文面向的是发布的应用中 X509TrustManager 接口实施方式不安全的开 ...

  7. JVMInternals--reference

    This article explains the internal architecture of the Java Virtual Machine (JVM). The following dia ...

  8. Delphi GDI+ Library

    GDI+ LibraryThis library enables GDI+ functionality for Delphi 2009 and later. It differs from other ...

  9. Scala入门指南与建议

    最近在学习使用Scala语言做项目,感觉这门语言实在是太优美了!作为一个本科数学.研究生机器学习专业的混合人才(哈哈),这门语言真的是满足了普通计算机编程(告诉计算机怎么做)和函数式编程(告诉计算机做 ...

随机推荐

  1. h5 canvas 画图

    h5 canvas 画图 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  2. jQuery+PHP实现浏览更多内容

    Ajax加载的基本原理:当页面载入时,jQuery向后台请求数据,PHP通过查询数据库将最新的几条记录显示在列表页,在列表页的底部有个“查看更多”的链接,通过触发该链接,向服务端发送Ajax请求,后台 ...

  3. 字符截取 支持UTF8/GBK

    );         $n = $tn = $noc = ;          || $t ==  || ( <= $t && $t <= )) {             ...

  4. google svn 服务器使用(免费SVN服务器)

    转自:http://hi.baidu.com/%C0%AF%B1%CA%B9%A4%D7%F7%CA%D2/blog/item/d6f6c6d7707d81d0a044df5f.html 1. 进入h ...

  5. uva 10246(最短路变形)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28972 思路:spfa求出每个点到其余顶点的最短路(最短路上的每个 ...

  6. CAD 快捷键Ctrl+2 Ctrl+3

    今天用cad,学习了两个快捷键,第一个Ctrl+2,打开如下 第二个是Ctrl+3,打开如下:

  7. Redis Key 命令

      Redis Key 命令     del key1 key2 - keyn 删除键为key1,key2-keyn,空格分隔. persist key 移除给定 key 的生存时间,将这个 key ...

  8. 设置完在Canvas的位置后,控件HitTest不响应的问题

    have a Canvas with a couple of elements on it like Line, Path and Text Box. In the MouseOver event o ...

  9. OI分类

    黑字:认识 红字:要学 未添加:要学 ├─模拟├─字符串│    ├─字符串基础│    ├─manacher│    ├─kmp│    ├─trie│    ├─ac自动机│    ├─后缀数组( ...

  10. 最近公共祖先(lca)

    囧啊囧. lca的求法太多了 倍增,tarjan,st,lct,hld.... 后边三个我就不写了,其中st我没写过,估计用不上,在线用倍增,离线用tarjan就行了. 嗯. 第一种,倍增(O(nlo ...