转 PHP抽象类:无法实例化 (不错)

 

http://blog.csdn.net/kaituozheboke/article/details/52183726

一、抽象类: 无法实例化


类前加 abstract, 此类就成为抽象类,无法实例化.

举例:

春秋战国时期,燕零七 飞行器专家,能工巧匠.他写了一份图纸---【飞行器制造术】

飞行器秘制图谱:

  • 要有一个有力的发动机,喷气式.
  • 要有一个平衡舵,掌握平衡

他的孙子问: 发动机怎么造呢?

燕零七眼望夕阳: 我是造不出来,但我相信后代有人造出来

 

 

[php] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. // 燕零七的构想,当时的科技造不出来,即这个类只能在图纸化,无法实例化.  
  2. // 此时这个类没有具体的方法去实现,还太抽象.  
  3. // 因此我们把他做成一个抽象类  
  4. abstract class FlyIdea {  
  5.     // 大力引擎,当时也没法做,这个方法也实现不了  
  6.     // 因此方法也是抽象的  
  7.     public abstract function engine();  
  8.    
  9.     // 平衡舵  
  10.     public abstract function blance();  
  11.    
  12.     /* 
  13. ----------------------注意:抽象方法 不能有方法体,写到小括号就行了---------------------- 
  14.         下面这样写是错误的(有方法体) 
  15.         public abstract function blance() { 
  16.         } 
  17.         Fatal error: Abstract function FlyIdea::engine() cannot contain body 
  18.     */  
  19. }  
  20.    
  21. /* 
  22. ----------------------抽象类不能 new 来实例化---------------------- 
  23. 下面这行是错误的 
  24. $kongke = new FlyIdea(); 
  25. Cannot instantiate abstract class FlyIdea 
  26. */  
  27.    
  28.    
  29.    
  30. // ------------1----------到了明朝,万户用火箭解决了发动机的问题----------------------  
  31. abstract class Rocket extends FlyIdea {  
  32.    
  33.     // 万户把engine方法,给实现了,不再抽象了  
  34.     public function engine() {  
  35.         echo '点燃火药,失去平衡,嘭!<br />';  
  36.     }  
  37.    
  38.     // 继承自父类,但是万户实现不了平衡舵,(还有一个抽象方法)  
  39.     // 因此平衡舵对于Rocket类来说,  
  40.     // 还是抽象的,  
  41.     // 类也是抽象的 因此类加一个abstract  
  42. }  
  43.    
  44.    
  45.    
  46. /* 
  47. ------------1----------到了现代,燕十八亲自制作飞行器---------------------- 
  48. 这个Fly类中,所以抽象方法,都已经实现了,不再是梦想. 
  49. */   
  50.    
  51. class Fly extends Rocket{  
  52.     public function engine() {  
  53.         echo '有力一扔<br />';  
  54.     }  
  55.    
  56.     public function blance() {  
  57.         echo '两个纸翼保持平衡~~~';  
  58.     }  
  59.    
  60.     public function start() {  
  61.         $this->engine();  
  62.         for($i=0;$i<10;$i++) {  
  63.             $this->blance();  
  64.             echo '平稳飞行<br />';  
  65.         }  
  66.     }  
  67. }  
  68.    
  69.    
  70.    
  71. $apache = new Fly();  
  72.    
  73. $apache->start();  
  74. /*有力一扔 
  75. 两个纸翼保持平衡~~~平稳飞行 
  76. 两个纸翼保持平衡~~~平稳飞行 
  77. 两个纸翼保持平衡~~~平稳飞行 
  78. 两个纸翼保持平衡~~~平稳飞行 
  79. 两个纸翼保持平衡~~~平稳飞行 
  80. 两个纸翼保持平衡~~~平稳飞行 
  81. 两个纸翼保持平衡~~~平稳飞行 
  82. 两个纸翼保持平衡~~~平稳飞行 
  83. 两个纸翼保持平衡~~~平稳飞行 
  84. 两个纸翼保持平衡~~~平稳飞行*/  
  85.    
  86.    
  87. //有一个类是抽象的,但是里面的方法不是抽象的,能否new?  
  88. /* 
  89. 但是 --- 即便全是具体方法,但类是抽象的, 
  90. 也不能实例化.*/  
  91. abstract class Car {  
  92.     public function run() {  
  93.         echo '滴滴';  
  94.     }  
  95. }  
  96.    
  97. //$qq = new qq();   不能实例化   
  98. //解决办法》》》继承  
  99. class qq extends Car {  
  100. }  
  101.    
  102. $qq = new qq();  

 

 

总结:

  类前加 abstract 是抽象类

方法前加 abstract 是抽象方法

抽象类 不能 实例化

抽象方法 不能有 方法体

有抽象方法,则此类必是 抽象类

抽象类,内未必有抽象方法

但是 --- 即便全是具体方法,但类是抽象的,

也不能实例化.

二、抽象类的意义


请看如下场景:

Facebook 多国语言欢迎页面

user登陆,有一个 c 字段,是其国家

当各国人登陆时,看到各国语言的欢迎界面

我们可以用面向过程的来做

[php] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. $c = 'english';  
  2.    
  3. if($c == 'china') {  
  4.     echo '你好,非死不可';  
  5. else if($c =='english') {  
  6.     echo 'hi,welcome';  
  7. else if($c == 'japan') {  
  8.     echo '搜达斯内';  
  9. }  

 

反思: 当facebook进入泰国市场时,

增加 else if ,扩展性很差

=====用面向对象来做======

让美国小组/中国开发组/斯蜜达开发组 来开发Welcome类

争执不下: echo 到底该中? 日? 韩?

说: 干脆在wel()方法里,判断一下? 没意义啊

[php] view plain copy
 
 在CODE上查看代码片派生到我的代码片
    1. abstract class Welcome {  
    2.     public abstract function wel();  
    3. }  
    4.    
    5.    
    6.    
    7. // 这是首页的controller开发者  
    8. //$wel = new Welcome();  
    9. //$wel->wel();  
    10. /* 
    11. 说:你们别争执了,我只知道,我要调用wel()方法,就是打招呼, 
    12. 你们显示什么语言和我无关. 
    13. */  
    14.    
    15.    
    16. /** 
    17. 经理说话: 
    18. Welcome谁也不许动,各国开发小组开发自己的招呼类 
    19.   
    20. 另:为了首页的controller开发者便于调用, 
    21. 统一继承自welcome类 
    22. **/  
    23.    
    24.    
    25.    
    26. class china extends Welcome {  
    27.     public function wel() {  
    28.         echo '你好,非死不可,<br />';  
    29.     }  
    30. }  
    31.    
    32.    
    33. class english extends Welcome {  
    34.     public function wel() {  
    35.         echo 'hi,welcome';  
    36.     }  
    37. }  
    38.    
    39.    
    40. class japan extends Welcome {  
    41.     public function wel() {  
    42.         echo '搜达斯奈';  
    43.     }  
    44. }  
    45.    
    46.    
    47.    
    48.    
    49.    
    50. // 再看首页开发者  
    51.    
    52. $c = 'english'; // china, japan  
    53. $wel = new $c();  
    54. $wel->wel();  
    55.    
    56.    
    57. /* 
    58.   
    59. 以后新增了泰国语,首页的开发者,根本无需改动 
    60. 只需要增加一个泰国的welcome类 就可以了. 
    61.   
    62. 所以有一些面向对象的介绍中,说面向对象的一个特点:可插拔特性 
    63.   
    64. */  
posted @ 2017-03-16 16:08  feiyun8616  阅读(385)  评论(0编辑  收藏  举报