获得本站免费赞助空间请点这里
返回列表 发帖

[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
! s; F  {; N: `8 E- ~& NPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。: A6 S; d$ \4 e1 V
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
. S% V6 D+ A) ]) c: o- q3 F' F1 L& z+ l8 ]6 X
问题4 F" y& ^6 Y5 |- t" [$ y' `
( ?8 a/ e' g. B5 Q
1.对象的蓝图是什么?
( G( |1 T6 G  K" z
3 E. \$ r( M3 E* q答案:____________
. _9 O& ]/ H; \9 P2 m+ q' y
6 S" F8 e4 B2 ~, q$ v6 [$ z  B! f  [
; b' s: A, ?6 G$ {# R' A$ R2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)

  1. <?php
  2. class my_class
  3. {
  4.     var $my_value = array();
  5.     function my_class ($value)
  6.     {
  7.         $this->my_value[] = $value;
  8.     }
  9.     function set_value ($value)
  10.     {
  11.         $this->$my_value = $value;
  12.     }
  13. }
  14. $a = new my_class ('a');
  15. $a->my_value[] = 'b';
  16. $a->set_value ('c');
  17. $a->my_class('d');
  18. ?>
复制代码
A.c
3 Y( Z. W4 W6 M5 WB.b
, A% v  w: w3 @7 X8 G+ R4 r3 FC.a
' }( a; D* ?! E! v8 z+ dD.d
0 M4 X  c+ j4 O5 |& e3 kE.e
$ o- D* e4 U* `; k, ^2 ?2 `. b# x7 C9 B+ u" ]1 `) S. c% s

4 b- Z: }/ s3 q$ _6 M9 a9 t' Q8 Q3.如何让类中的某些方法无法在类的外部被访问?
  J( q3 H: i; g) J2 A& r' q6 e$ ~9 ^6 B2 H3 Y% V) l
A.把类声明为private& {1 [$ ?( [. Q/ q- y) J
B.把方法声明为private" |% v7 N7 I4 O; y9 K  P
C.无法实现/ H% H3 D9 J5 ^5 R7 J3 d$ F: Y
D.编写合适的重载方法(overloading method)6 p: \: @% A- M! R2 L/ j& v

6 i+ f9 u4 q9 T: P0 y/ n
7 o8 C* Q4 M# T2 G) Y6 j: |: V9 W4.哪种OOP设计模式能让类在整个脚本里只实例化一次?/ r; @+ r5 A# j
8 I2 B* b# y5 H" M% J! p
A.MVC模式! s8 g! Q& I+ q5 e, _
B.抽象工厂模式(Abstract factory)
$ E) A; a7 {0 x7 m; h$ RC.单件模式(Singleton); A* ~8 H3 r8 `! }2 V; ?8 V4 Z
D.代理模式(Proxy)8 G, P1 ^& R/ l+ S8 ^' S( P
E.状态模式(State)
5 ^9 N8 B7 X& Q1 [$ a
8 G' I. _- a% ^/ ?0 Z4 h2 m5 o+ {; u) E9 @! i0 |
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?+ ^, j6 S7 q8 j# n* K. R

! Q4 ]$ y4 J+ Y- e+ ^3 oA.1个2 _* q+ h* K7 P  x$ j4 M
B.2个
5 R. M; }7 z4 |  bC.取决于系统资源
& y* I* D0 ]3 n3 F' [D.3个! _5 x- n6 ~8 _
E.想要几个有几个
/ F: X) \, a4 V2 D" m; @; w  ?/ r$ T( C0 Y" o: o8 W: r

3 T. M& q4 R# o' a% U+ y6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?

  1. <?php
  2. class my_class
  3. {
  4.     function my_funct ($my_param)
  5.     {
  6.         user_error ("Please define me", E_ERROR);
  7.     }
  8.     function b()
  9.     {
  10.         return 10;
  11.     }
  12. }
  13. ?>
复制代码
A.多重继承
7 _5 g; g. H3 [2 L6 G. v" f  JB.接口1 ^$ S; ]) m1 W* c
C.抽象方法4 q/ U8 r8 o1 o8 z$ N
D.Private方法* ^+ M0 J2 {, t9 s$ k
E.函数重载(function overloading)
& e, t3 p( X7 Y0 @0 d0 A4 K* ]
7 s+ g( e8 |2 M* B/ j- o
' h' X4 _2 G* A' a' ?3 T7.假设定义了一个testclass类,它的构造函数的函数名是什么?- X1 ^: Y7 y; _! q! J% Y

  h3 _- R  V' {! m  i( ]- HA.__construct
4 B# a& Q! K, _' RB.initialize
; U7 u$ e' r8 n5 p" b5 }" Y- K) zC.testclass
% ^: |# I( I' oD.__testclass& b: _) p2 M2 [  l' K+ z5 Y( b
E.只有PHP5才支持构造函数
: ?, j% Q  J8 |0 ~2 m/ ]
$ p& \) V4 b2 ?/ A6 D. |+ h# c! j8 F* F7 G% r
8.一个类如何覆盖默认的序列化机制?
  }/ z" {% o" f$ T1 H5 H  p* O3 P+ X
A.使用__shutdown和__startup方法0 G% j) k5 u9 ^! G5 O/ h
B.调用register_shutdown_function()函数7 f( @/ a& s( W; n8 T$ w$ c
C.使用__sleep()和__wakeup()方法7 w$ R; `4 E" j+ m) @6 L0 Z$ [
D.无法覆盖默认序列化机制
/ p8 X! v. I8 pE.使用ob_start()将类放入输出缓冲中
8 J$ `5 \/ e6 `! p/ E
* a" Q; K1 ]7 c3 P) X8 j! a
9 d6 v0 |/ [+ q5 ^8 X  c' T& V9.以下哪些面向对象的概念无法在PHP4中实现?
6 j- |" [" y. i' N" R
9 Z, g# x$ z* Q# p5 c( I& E; u@抽象类: j0 b8 G& d  \, W. l
@Final类" E# F4 W: e5 r$ H' |1 q
@Public、private、protected(PPP)方法) v, Z' q, a3 }& V3 E
@接口
$ N2 l3 p% W9 G$ z) H
, B5 S) d' |: N; f6 o; o) nA.抽象类
' i, r' F" y1 _/ {/ j+ fB.PPP方法7 U$ @- w# J* I
C.PPP方法和接口
6 _$ k  c0 R+ V; B" t* `  B4 JD.以上所有都不可用
+ ?1 R& w( B4 x: U7 L1 nE.以上所有都可用7 q2 r( L3 S, d: L

6 E, l2 I0 C; g5 H0 P" v( {3 h; `7 b  ^% H
10.如何在类的内部调用mymethod方法?
$ x) P* b! b7 k$ F! k* P% n7 c& r* J1 f* u$ h* f8 f
A.$self=>mymethod();
0 L3 Q* S/ P! t! s' A5 @$ E# ]B.$this->mymethod();
% y& i2 q" |% w# e4 F! K; SC.$current->mymethod();# v( }4 J  ^" I* q
D.$this::mymethod()& L. V% _; S# [- [
E.以上都不对$ U  ]6 R4 Z- Q
  r( Q2 M! _" n

1 i6 V% u  T! C11.以下脚本输出什么?

  1. <?php
  2. class my_class
  3. {
  4.     var $my_var;
  5.     function _my_class ($value)
  6.     {
  7.         $this->my_var = $value;
  8.     }
  9. }
  10. $a = new my_class (10);
  11. echo $a->my_var;
  12. ?>
复制代码
A.10
: |2 C5 D- t# @2 w, n4 yB.Null% Z1 k8 S) S2 d5 w
C.Empty9 c) N+ P: p- J! E
D.什么都没有
1 U! D  ?. |, q  m& p2 }( Q- [7 IE.一个错误- ]0 H) L3 y( `( N+ y" A
% g5 _5 s$ d8 O9 a2 A; ?4 W2 l
9 I- \  E# r5 C. h+ R8 A
12.以下脚本输出什么?

  1. <?php
  2. class my_class
  3. {
  4.     var $value;
  5. }
  6. $a = new my_class;
  7. $a->my_value = 5;
  8. $b = $a;
  9. $b->my_value = 10;
  10. echo $a->my_value;
  11. ?>
复制代码
A.10
$ t# Q  o) I+ u3 r" F  p! mB.5
! @. A$ e0 T( T' hC.2$ T+ G5 c. l: x0 ^
D.Null
- U6 n0 d; K4 `( f, Y8 W: n5 t: WE.什么都没有7 d" o1 R2 c, i! g

& u7 M# [; d2 Z! G
6 C1 J9 u. Z: x1 p# S2 x13.以下脚本输出什么?

  1. <?php
  2. $global_obj = null;
  3. class my_class
  4. {
  5.     var $value;
  6.     function my_class()
  7.     {
  8.         global $global_obj;
  9.         $global_obj = &$this;
  10.     }
  11. }
  12. $a = new my_class;
  13. $a->my_value = 5;
  14. $global_obj->my_value = 10;
  15. echo $a->my_value;
  16. ?>
复制代码
A.5$ s  `! z5 f4 f! v/ D
B.10
1 P2 y4 Q( P+ ?6 cC.什么都没有
0 @/ S' J" u1 ]4 n; [. ^D.构造函数将报错
! ?! ^) {$ Z  Z5 FE.510: r7 G+ q" C4 _7 N5 e8 O
% c. k) p: B2 {) w8 t2 _' G0 S% \

  S8 K6 ~8 a9 y3 g& V14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?

  1. <?php
  2. class fraction {
  3.     var $numerator;
  4.     var $denominator;
  5.     function fraction($n, $d) {
  6.         $this->set_numerator($n);
  7.         $this->set_denominator($d);
  8.     }
  9.     function set_numerator($num) {
  10.         $this->numerator = (int)$num;
  11.     }
  12.     function set_denominator($num) {
  13.         $this->denominator = (int)$num;
  14.     }
  15.     function to_string() {
  16.         return "{$this->numerator} / {$this->denominator}";
  17.     }
  18. }
  19. function gcd($a, $b) {
  20.     return ($b > 0) ? gcd($b, $a % $b) : $a;
  21. }
  22. function reduce_fraction($fraction) {
  23.     $gcd = gcd($fraction->numerator,
  24.     $fraction->denominator);
  25.     $fraction->numerator /= $gcd;
  26.     $fraction->denominator /= $gcd;
  27. }
  28. $eight_tenths = new fraction(8,10);
  29. /* Reduce the fraction */
  30. reduce_fraction($eight_tenths);
  31. var_dump($eight_tenths->to_string());
  32. ?>
复制代码
A.reduce_fraction函数必须返回一个值
* c- f7 \- O; D2 gB.reduce_fraction函数必须接受一个整型值. [: S. j; P5 \4 \: q
C.gcd函数有问题/ U. M8 n) P& N$ q+ h7 w" b
D.必须通过引用的方式传递$eight_tenths对象
( _' x/ G1 {' PE.对象的实例不能传递给方法以外的其他结构。
$ o- o: w# W3 N& t0 E% L- \- W- f3 q

+ ~; n! J3 g) s2 {- K15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
4 M& X- K. m3 {" e+ h9 t! CB.生成myclass的实例并调用mymethod方法5 d; f( q& a: q5 Y- O
C.产生一个语法错误
9 Z/ }+ K! f- K2 S" [& l: i* {+ WD.默认myclass类最后被创建出的实例并调用mymethod()
5 ?7 e* |8 c! V/ D1 [, oE.调用名为myclass::mymethod()的函数
) C, R& q' t9 f  ~/ G8 E4 [+ j) W4 p
3 T  N. Q0 \6 h# R4 K  `6 m4 {
16.PHP中有静态类变量吗?- q' [) t, z2 r% i) |& V7 P
8 q* g1 P9 @6 e/ Z6 _# M9 l
A.有
% ^# |& t' W2 |0 q8 nB.没有6 ^" `& v# ~+ ]7 Q# S: W
! ~1 Z( |' H2 N: }8 d6 |  H- B7 b1 P

; [( P) _7 v: H17.以下脚本输出什么?

  1. <?php
  2. class a
  3. {
  4.     function a ($x = 1)
  5.     {
  6.         $this->myvar = $x;
  7.     }
  8. }
  9. class b extends a
  10. {
  11.     var $myvar;
  12.     function b ($x = 2)
  13.     {
  14.         $this->myvar = $x;
  15.         parent::a();
  16.     }
  17. }
  18. $obj = new b;
  19. echo $obj->myvar;
  20. ?>
复制代码
A.1
/ O. |! w: n. B+ j7 e, bB.2/ ], E5 \, `5 M& I. s+ C
C.一个错误,因为没有定义a::$myvar& @- H  R( U; k9 e
D.一个警告,因为没有定义a::$myvar; g& m* R' v# C; R- \
E.什么都没有
1 o1 J0 O  _5 B. w/ l- d8 w' j2 @
( H0 s  _7 |) n& m3 _& I7 j
. N7 _7 ?  i1 I3 l0 O18.如何即时加载一个类?8 B* g8 ]0 M5 S8 w

/ T% p* ^: H. M4 c- m0 WA.使用__autoload魔术函数+ E' G" l) E' R$ r4 z
B.把它们定义为forward类. o: T* w/ m- h
C.实现一个特殊的错误处理手段
6 j5 X2 y9 h; C( X8 Z3 @! ND.不可能
/ b2 Z- A  I5 G% I2 j5 }7 xE.用有条件限制的include来包含它们
1 D% d( t% |7 |9 w# i
- s9 T* U- z2 |4 J! ^( z
* s/ g: C* h' M0 k; K0 A; j+ n0 f+ n19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?/ ?1 E# D5 r1 L

2 z- q. j2 H$ w; J9 I5 P, g4 M" u+ a    答案:__________
- J; S9 A, b3 n( q$ [. [2 R/ v0 r$ K! l1 Q. Q6 X/ J

$ i1 i3 T$ t- g2 k5 G20.以下脚本输出什么?

  1. <?php
  2. class a
  3. {
  4.     function a()
  5.     {
  6.         echo 'Parent called';
  7.     }
  8. }
  9. class b
  10. {
  11.     function b()
  12.     {
  13.     }
  14. }
  15. $c = new b();
  16. ?>
复制代码
A.Parent called0 s: M7 L" g4 u0 a; t1 F/ D5 _
B.一个错误7 ?+ u! y* I9 X6 e( k
C.一个警告
( j$ \* U$ y5 R; z- m: [% z/ Y# k1 yD.什么都没有6 z7 e/ {" ]5 Q8 Z1 O
7 E% k- p* `' A( G: G/ Z; N
% w% E& L, W% s- P
4 B1 b# Z- c$ t6 f) `
答案速查
7 m1 J3 X* ~( R: _1.类
2 B" x' S0 v+ g; w8 E, H. }2.BCD! \1 A4 w& @" _1 s1 Q
3.C. O  y1 K% g( {9 w7 j/ V( E! S
4.C1 j% }- f7 H1 R- e/ g) ]
5.A
* S! l$ ]& s0 p. t( y, \2 C; ~6.C
0 G& E/ z6 |/ m$ G) m7.C9 Q! i( j' v3 E) r) G
8.C
6 E/ v" r# }) ?! ^5 J  o9.D
4 Y0 b) Z. d! E# N10.B& h. U& R- y$ c5 l/ o5 U3 a
11.D
6 N5 b8 c! w( z! `# x12.B; }8 I1 W6 t# \7 W4 o* {4 z
13.A7 _  K0 g0 @; C. g: e$ `- h9 @
14.D' @/ y# Z: N8 R  C- n3 R
15.A0 P- e2 |' i0 A
16.B
, V. q. A/ D/ ~4 ^0 n1 s8 V- ~17.A
, Q! X! v2 E" p( J' _+ Y" w  _18.D
7 d1 F/ u- U8 V19.设计模式4 t( c: D6 ?) t! ?5 a% `( H7 _
20.D
# G3 p9 c) T- O5 D  h7 k; }  m! e8 r5 A8 K' h( o& k

' t3 _6 H" N, R+ r# f6 f& @8 O. [! M
) K' W, H0 c2 }- D0 c: k( }3 X答案详解
3 k& p! F, a# D' z3 r* u% a5 u3 w
1.类是对象的蓝图(对象是类的实例)。
) b9 U7 r. U. d; U* l2 u( v& H4 `9 u4 Y0 P4 V% f
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。* A1 }1 L5 g' d+ U* c. J

9 {  \+ E2 G- A/ [# j3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。: B2 `- o# \& m( I+ C1 U6 i
6 L5 g, u$ E/ Z; X, t7 a
4.单件模式可以限制一个类被实例化的次数。
+ E: _9 m5 z& s7 g# l) w0 C! Q8 _/ F% m( ?2 a+ R
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
8 M% f' {$ F# f9 D' ^8 V5 z* p- {  G, J: p% F0 ]
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
$ y2 U# Z, y2 v4 k) L: t3 s) {  c' E( w% V# p! Z
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。6 r& ^: l$ Q5 ~. V. p  e2 X+ F4 @
; `8 `1 z4 ~- K
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。4 ]/ H; t. [( b1 d& [) I: D3 O

/ H/ }7 J3 a9 b6 M  w; `8 ^4 J) G9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
; R; C1 H* k. f4 m- w$ T7 j, [6 y+ r: }6 }1 E7 ?+ L; f- K  D
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。: ]9 l6 s! Y3 e" _/ R* S& H( k

5 S+ k4 ^" ]$ ^0 e% G; ]11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。# {* [3 D. x: p) R, n
. C- o) _5 `5 S/ V
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
, E4 ^, S! C/ _9 s3 }! t; z% t) ^, b5 M; @# M! P% F
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。/ |; ]$ E- B- u5 T2 r: M/ ~0 U6 M; }

% q  m5 u. l3 |. P14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。" `# i1 Q$ h4 H1 c: f# r9 k
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
# p( ]4 u# P4 E; A! t7 D5 Q    function reduce_fraction(&$fraction)
/ k( v5 B: ~: n$ w7 L7 v答案是D。
( N9 J( }% S& c& A; F+ [
1 }! w5 _  H# y2 N; p+ t15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
) u- T. e5 t# n# v( A5 d  g/ a4 ?5 X2 f6 T& d. R' q
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。% o  C  b2 h: d1 ?
0 I. ]% q) h) K4 X/ G& d+ ?
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。" C% a! e0 [" |, k& t( M0 {
  u# K+ L, {+ q6 Z8 o9 W% j5 E
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。! Z, g" b' g0 M  m/ x

( V4 w! T0 v2 v- |6 g, I19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。; d: L4 N3 N5 y- P4 I6 w
: W! R1 @6 |: u6 I$ L
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

返回列表
【捌玖网络】已经运行: