程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> Class Abstraction,classabstraction

Class Abstraction,classabstraction

編輯:關於PHP編程

Class Abstraction,classabstraction


  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 
 61 $class1 = new ConcreteClass1;
 62 $class1->printOut();
 63 echo $class1->prefixValue('FOO_').'<br>';
 64 
 65 $class2 = new ConcreteClass2;
 66 $class2->printOut();
 67 echo $class2->prefixValue('FOO_').'<br>';
 68 
 69  
 70 
 71 abstract class AbstractClassB
 72 {
 73     // Our abstract method only needs to define the required arguments
 74     // 我們的抽象方法僅需要定義需要的參數
 75     abstract protected function prefixNameB($name);
 76 }
 77 
 78 class ConcreteClassB extends AbstractClassB
 79 {
 80     // Our child class may define optional arguments not in the parent's signature
 81     // 我們的子類可以定義父類簽名中不存在的可選參數
 82     public function prefixNameB($name, $separator = '.'){
 83         if ($name == 'Pacman') {
 84             $prefix = 'Mr';
 85         } elseif ($name == 'Pacwoman') {
 86             $prefix = 'Mrs';
 87         } else {
 88             $prefix = '';
 89         }
 90         return "{$prefix}{$separator} {$name}";
 91     }
 92 }
 93 
 94 $classB = new ConcreteClassB;
 95 echo $classB->prefixNameB('Pacman'), '<br>';
 96 echo $classB->prefixNameB('Pacwoman'), '<br>';
 97 
 98 
 99 /*
100 Object Interfaces 
101 Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled. 
102 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. 
103 All methods declared in an interface must be public; this is the nature of an interface. 
104 對象接口 
105 使用接口(interface),可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容。 
106 接口是通過 interface 關鍵字來定義的,就像定義一個標准的類一樣,但其中定義所有的方法都是空的。 
107 接口中定義的所有方法都必須是公有,這是接口的特性。 
108 
109 
110 
111 
112 implements 
113 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. 
114 Note: 
115 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. 
116 Note: 
117 Interfaces can be extended like classes using the extends operator. 
118 Note: 
119 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. 
120 Constants 
121 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. 
122 實現(implements) 
123 要實現一個接口,使用 implements 操作符。類中必須實現接口中定義的所有方法,否則會報一個致命錯誤。類可以實現多個接口,用逗號來分隔多個接口的名稱。 
124 Note: 
125 實現多個接口時,接口中的方法不能有重名。 
126 Note: 
127 接口也可以繼承,通過使用 extends 操作符。 
128 Note: 
129 類要實現接口,必須使用和接口中所定義的方法完全一致的方式。否則會導致致命錯誤。 
130 常量 
131 接口中也可以定義常量。接口常量和類常量的使用完全相同,但是不能被子類或子接口所覆蓋。 
132 
133 
134 */
135 
136 // Declare the interface 'iTemplate'
137 interface iTemplate
138 {
139     public function setVariable($name, $var);
140     public function getHtml($template);
141 }
142 
143 // Implement the interface
144 // This will work
145 
146 class Template implements iTemplate
147 {
148     private $vars = array();
149 
150     public function setVariable($name, $var)
151     {
152         $this->vars[$name] = $var;
153     }
154 
155     public function getHtml($template)
156     {
157         foreach ($this->vars as $name => $value) {
158             $template = str_replace('{'.$name.'}', $value, $template);
159         }
160         return $template;
161     }
162 }
163 
164 /*
165 class BadTemplate implements iTemplate
166 {
167     private $var = array();
168     public function setVariable($name, $var)
169     {
170         $this->vars[$name] = $var;
171     }
172 }
173 Fatal error: Class BadTemplate contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (iTemplate::getHtml) 
174 
175 */
176 
177 /*
178 class BadTemplate implements iTemplate
179 {
180     private $vars = array();
181 
182     public function setVariable($name, $var,$echo)
183     {
184         //Fatal error: Declaration of BadTemplate::setVariable() must be compatible with iTemplate::setVariable($name, $var)
185 
186         $this->vars[$name] = $var;
187         echo $echo;
188     }
189 
190     public function getHtml($template)
191     {
192         foreach ($this->vars as $name => $value) {
193             $template = str_replace('{'.$name.'}', $value, $template);
194         }
195         return $template;
196     }
197 }
198 */
199 
200 /*
201 class BadTemplate implements iTemplate
202 {
203     private $vars = array();
204 
205     // Fatal error: Access level to BadTemplate::setVariable() must be public (as in class iTemplate)
206 
207     protected function setVariable($name, $var)
208     {
209         
210         $this->vars[$name] = $var;
211     }
212 
213     public function getHtml($template)
214     {
215         foreach ($this->vars as $name => $value) {
216             $template = str_replace('{'.$name.'}', $value, $template);
217         }
218         return $template;
219     }
220 }
221 
222 */
223 
224 
225 
226 interface a
227 {
228     public function foo();
229 }
230 
231 interface b extends a 
232 {
233     public function baz(Baz $baz);
234 }
235 
236 class c implements b
237 {
238     public function foo()
239     {
240 
241     }
242 
243     public function baz(Baz $baz)
244     {
245 
246     }
247 }
248 
249 /*
250 Fatal error: Declaration of d::baz() must be compatible with b::baz(Baz $baz)
251 
252 class d implements b
253 {
254     public function foo()
255     {
256 
257     }
258 
259     public function baz(Foo $foo)
260     {
261 
262     }
263 }
264 */
265 
266 
267 //Multiple interface inheritance 繼承多個接口
268 
269 interface a1 
270 {
271     public function foo();
272 }
273 
274 interface b1
275 {
276     public function bar();
277 }
278 
279 interface c1 extends a1, b1
280 {
281     public function baz();
282 }
283 
284 class d1 implements c1
285 {
286     public function foo()
287     {
288     }
289 
290     public function bar()
291     {
292     }
293 
294     public function baz()
295     {
296     }
297 }
298 
299 //Interfaces with constants 使用接口常量
300 interface a2
301 {
302     const b2 = 'Interface constant';
303 }
304 
305 echo a2::b2;
306 
307 /*
308  Fatal error: Cannot inherit previously-inherited or override constant b2 from interface a2 
309  錯誤寫法,因為常量不能被覆蓋。接口常量的概念和類常量是一樣的。
310 
311 class c2 implements a2
312 {
313     const  b2 ='Class constant';
314 }
315 
316 */

 http://php.net/

 

小結:

0-子類需定義抽象類所有方法,方法參數個數可以添加,訪問控制同或弱,而對象接口的實現也需要實現全部方法,但是參數個數不可更改,且訪問控制必須public。

發問:

0-框架中的實例?

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved