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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
' W, o% z% R7 P- vPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。2 T5 T% o4 B) S1 c1 |$ q
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。( a3 {! ~9 ~. P6 m; T4 j
5 Z& X6 [& v( Z, g; J% L
问题
9 m# y8 m" Q6 B5 C! f" m1 X  C
4 [3 l% j/ {0 K7 Z; w* l1.对象的蓝图是什么?4 O5 v* }* E* E; W. o
+ V1 l  M, U7 o4 ]
答案:____________
; a8 ?1 v0 a- b- X: @. q# `$ j9 p# I

5 r2 @  B1 Q6 l8 b. m2.以下代码执行后,数组$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- t, i# N9 j2 c) V6 E# w3 Z
B.b) a; S) ~! f  \" [# y9 g
C.a0 z1 M1 w* Y* y( y" C/ x
D.d
# T+ F: `7 d' m, a2 P* N: G% }! p1 kE.e
8 _& D/ y: t3 c9 G3 m* A; Z
3 {0 [1 w) G% ?: ]* V2 k' v6 L/ N$ q2 e
3.如何让类中的某些方法无法在类的外部被访问?
8 e; f9 w' Z1 S0 r, g  X& A; u
9 x' j* B  c- y' |. v, f. Y# DA.把类声明为private' x7 R# \: M+ q3 P  d% S1 Z0 _  p
B.把方法声明为private
! F( v! b" ?+ k9 PC.无法实现4 Y( X% X# F% ^  U" |& ]
D.编写合适的重载方法(overloading method)' p' k7 _3 H' z# T1 C( h8 v

0 I7 v2 \7 U( l, M) x6 x
6 T/ q) u9 w. h1 n6 J4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
) v; w8 g' R# Z
2 T  e2 }8 H1 {A.MVC模式" {  s+ r! F3 j: C' V4 M
B.抽象工厂模式(Abstract factory), F8 T' y) N. Y) Q' U1 X
C.单件模式(Singleton)
+ r( S8 f+ g  l! U( V; D! B  ^( u: L: CD.代理模式(Proxy)
& G/ M1 j8 A3 h2 D: \E.状态模式(State)( k+ d" }6 Z3 a5 k- y
: U" ]9 b5 L. g% u* e, B' _$ ?& u) U

! `, K5 I' ]6 `/ q' U5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?& g- u  |5 H* \8 N% i; n$ b
3 |2 ^  o9 U7 x; ~. z
A.1个
# x, b" k5 ]" ]/ Y( EB.2个0 \4 c# R: t  Z8 ?4 J; w
C.取决于系统资源
2 N- n9 V" q3 `# H. E% DD.3个7 V, p! i1 J1 P, _
E.想要几个有几个
# z- R) ]# I' ]' w8 \, j2 a8 D0 L7 d1 A( @2 t; j

$ L6 |3 Y2 `1 }2 Y9 C; w' s" }6.以下脚本近似的表示了一种在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.多重继承
: G. }1 o! K0 E6 ]+ Z! b' MB.接口9 `" e# Z1 O& T5 I8 `) H
C.抽象方法7 V: I8 V6 E3 _9 h5 b
D.Private方法5 [# k$ a* N/ ^4 Z5 Y/ y
E.函数重载(function overloading)4 [, J. `: D) N( t4 s% p! e

* P- v+ T  M! l+ ^
$ z* X% n3 k/ N7 O1 b7.假设定义了一个testclass类,它的构造函数的函数名是什么?- b; {& ]6 A, s/ }) ^

9 v/ ~) S$ P4 _" s' y: BA.__construct  o+ n  R3 C, Z* e4 `1 y3 m
B.initialize' H$ ?3 S" [) ]& [1 y% N( }
C.testclass0 `& r, x: ?  L7 M
D.__testclass) x' F. z  ^6 k* s
E.只有PHP5才支持构造函数0 v  D9 z; L+ Y
4 z8 L3 ^) b; s( V) G$ k# ^
' k) d3 j4 `/ E9 T( y" x/ {' ~; j' k7 z
8.一个类如何覆盖默认的序列化机制?1 M: O( i# W3 L' L$ t1 }

/ F% [3 Z9 v+ Y) a# k! Y% {8 m- LA.使用__shutdown和__startup方法
- ~+ T7 O* e) r! s, B5 a* n- N, YB.调用register_shutdown_function()函数
6 W- F2 F+ h* q& uC.使用__sleep()和__wakeup()方法
8 Z) L$ k. c2 t. g3 k! AD.无法覆盖默认序列化机制
: U- t- t4 i0 f+ O2 Y9 N$ j" C3 ZE.使用ob_start()将类放入输出缓冲中4 j+ y0 r3 _' O2 `/ f

. ?3 M* m6 s  k: u; s5 r' _4 b2 q* W+ v. h  T! P
9.以下哪些面向对象的概念无法在PHP4中实现?
7 S% s% Y2 F& w) M/ j
3 p) N: w& o9 g+ X$ Z) O/ R@抽象类# {6 b" F8 T7 l$ Y9 d
@Final类
6 ^! E4 |" l7 M4 E* U% s! s$ r8 m( m1 c@Public、private、protected(PPP)方法0 K5 r" |3 ^& ?! U/ s
@接口: m' d$ o% l; n1 m/ I8 h3 C! P

9 H; Q) F$ x  GA.抽象类
/ U# k, k8 m) |" KB.PPP方法
( Q6 n- S/ B1 `C.PPP方法和接口) q5 D- [4 i$ V3 {* y
D.以上所有都不可用2 N3 R4 Y% Z7 F( S; g! q- ^
E.以上所有都可用8 e5 V& k8 s- ^! c1 b. J( d

  T" N- ]3 |. F) t0 g' l$ F0 E0 j1 F
10.如何在类的内部调用mymethod方法?+ \; @" W' _% K0 d0 e3 z
, R8 D$ m, O* n
A.$self=>mymethod();
; {" ]3 t4 ]" `& H  Q9 a+ jB.$this->mymethod();
5 _/ b4 Q0 a5 T& B! CC.$current->mymethod();
: S9 E8 {' q3 G/ m- ~0 q" _/ gD.$this::mymethod()
  }9 W$ [* B2 I* d- lE.以上都不对/ F& @0 N- e$ j' z6 n2 A

' n8 W5 y! C$ Q3 C2 k+ n1 ?
% Z" y; L) D. B9 @! V11.以下脚本输出什么?

  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.100 T4 P' k$ @; w; f* e
B.Null
7 }6 u% Q8 A" Z) f* P7 mC.Empty
# j- ^: g4 Q& b5 Z- Q* HD.什么都没有) d+ H  b, N7 e- O' B/ F
E.一个错误2 O3 T/ A% p; r$ Y2 ~9 o6 @7 h
) Y) Z6 S6 @/ U! r! Y) O0 c: w
# @9 e+ N- J) R" f9 b" W& g/ e
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, Y1 R5 e3 m$ P4 ~% n
B.5
# e! v, \( v) r, TC.2+ G- ]: h/ N5 {* t- f) {+ B6 h
D.Null
, c2 f7 `6 O4 d1 n9 Y$ ?1 KE.什么都没有8 @# K. `( V$ q7 @" I
+ m" O" p/ ]" `; M5 w- v' j! D

9 m4 ?8 L- {1 h1 l8 M4 n13.以下脚本输出什么?

  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.58 o9 P0 f9 }: J& B1 p
B.10& K& @0 _0 g8 `
C.什么都没有- W4 S4 x% i- k% Z5 P
D.构造函数将报错- q( a% [9 b& v$ r& _# [
E.510
( Y, E0 w: _& U# X
$ U0 n  a! o* U! ?6 D3 L9 I5 B# n/ u/ z! h7 F: {
14.考虑如下一段代码,执行时,$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函数必须返回一个值6 U; D" {. Y# |+ Z
B.reduce_fraction函数必须接受一个整型值5 f4 X& I1 Y- ]2 W: x8 C, Q6 K. v
C.gcd函数有问题
2 Z) J4 [- m6 S5 XD.必须通过引用的方式传递$eight_tenths对象
2 [. V" w* ~1 ~) o5 @E.对象的实例不能传递给方法以外的其他结构。
9 r9 M; E0 U- S, }: r7 v2 s, U- a6 @! |
7 K4 H( f( N$ V& O
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
) @/ {& k6 K5 Q/ B1 B7 {% Z1 S* YB.生成myclass的实例并调用mymethod方法' A; w- Y; D( i" H, U
C.产生一个语法错误
3 _% |+ i8 f/ B. e% P$ t+ c0 R( _* sD.默认myclass类最后被创建出的实例并调用mymethod()
: q" u$ d# Z" n# N5 BE.调用名为myclass::mymethod()的函数& I1 O8 \# x3 d/ L, O" h5 M
& C2 h# C4 I+ W* E

& T9 L# ?; y4 H, u0 w16.PHP中有静态类变量吗?
2 o" C8 `  y' p9 L; `5 `( C
) l9 W( i9 H$ ?A.有7 R, u6 ]. n' w( O" f! ]% \7 ~
B.没有
2 r7 }4 e5 l2 w0 K( M3 J6 h, s, ~7 F) X( n9 Z# T: b7 {

; T: x: n+ ]' c2 _9 }% c17.以下脚本输出什么?

  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.17 X) n0 F2 B$ h! t6 J; g1 {
B.25 Y! T& J7 X8 @6 l8 n
C.一个错误,因为没有定义a::$myvar3 Z( }6 O! P) x' ?; Y6 j
D.一个警告,因为没有定义a::$myvar5 F; L8 F; B! @! b; W5 P7 j
E.什么都没有/ H/ F0 [4 T7 H& U* Q+ E' \: @

+ h8 W- ^- ^5 H' b$ w8 g( }8 b- z5 S6 g
18.如何即时加载一个类?+ t7 v  L! y- h/ ~; {4 p* p
) ~; s3 D' J; o# R. t) U" A$ i5 W
A.使用__autoload魔术函数5 c' L" n5 o# i2 ~2 o6 ^
B.把它们定义为forward类
. D4 Y% l! D  r+ ^C.实现一个特殊的错误处理手段
7 b" c. Z4 `2 t& m6 T5 N: k1 N& Y7 vD.不可能1 D% n1 y- q0 S4 ^' I
E.用有条件限制的include来包含它们+ W' ^; [9 E& a3 |

$ q4 o' f4 I; f7 k8 ]2 q- i- N2 c- P+ X( v3 D5 F
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
  t2 c4 Z& U/ o& m% Z
1 a, S  \) Y" ~5 y% `  h* E6 w    答案:__________- }# c+ v: n: Y! F$ ]# X  L
( D2 t6 P) ]& ~, q# A: g

  `: T- y% s2 w( a' g+ Z6 K1 X20.以下脚本输出什么?

  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 called, o- L- X7 |, W7 o. @4 Z9 G
B.一个错误) T" b. {' f3 ]1 ?) L/ z4 e
C.一个警告
' ]# _/ Q+ J) Y5 W% a; D8 l6 CD.什么都没有3 A' w8 }: D* i8 a- V' S
' V" G4 x/ ~, v

* w' b; I) ]  Y) u. \& M
; r% I( K5 D6 T/ l% G答案速查
) I3 h9 v0 I) x9 t1.类
" A% a/ a! K% F) m; K& f2.BCD
. q+ o7 ^) s0 N3.C
% `, R! g! ^. X8 ^  M4.C
# z& g  U) X  q7 a5.A
2 {0 X; b7 C9 W- m2 n9 R* [1 F$ |6.C. Q  p, L9 Z" x7 h/ F
7.C, A3 F8 L& M+ `, J) [/ P+ g1 r- n3 s
8.C
" o; p$ p5 G3 Z. ~; J9.D
  T: L8 k  w* }) n' [# I- P3 y10.B" D7 l. @# ?. x6 _7 U8 v
11.D+ X3 s0 \: Z+ b7 M1 t7 D
12.B
4 c+ L! o' u9 `; t. O13.A: {8 T7 n' ^9 o9 L
14.D
7 u) }! L( K: V( v' o) e: r+ V, r$ P15.A. U4 P/ S& N4 J& O8 R3 J! z
16.B
9 `6 ~$ v. k5 ~* T9 [17.A
8 n3 l& S6 H: D0 s18.D
; k4 a$ v' x1 A0 A% R; G19.设计模式$ \7 Y& A. W# J) ?7 P
20.D/ m# R: P/ S" ]* K& v7 h

/ O9 G8 _# C& N+ [6 O' X/ d) w3 g. s
/ `: n0 ~0 D  F' |4 N0 D! t7 l# C, v- R, k1 f
答案详解
0 P% ]0 |9 |  r  a5 z2 ?# \* K( m9 f. N1 d! u3 E2 ]3 _
1.类是对象的蓝图(对象是类的实例)。
3 a( q5 K7 K, Z* |# \3 ^2 x
: }+ \, j/ q8 w8 j" d6 L5 A3 e2 I2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。5 F" f6 Y! {+ `  `4 P  p5 M- l9 O$ L* ^

' R/ _# m. ]2 i9 A2 U' P7 x3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
% }0 d& J* S/ g) X  S6 L) }9 A" h
4.单件模式可以限制一个类被实例化的次数。( b0 A& Z0 s& W8 ?: `. ~+ X
+ N) i/ K$ o$ h1 o9 d
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。$ d0 g& @' B% \+ z' M5 Z/ H

4 {7 i) ?6 A7 ]  z6 m8 D, _6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。7 s; q* T" F/ A- H9 K2 n2 g
" {2 `$ P) X6 J2 k5 z8 ?: Q, t( V  W
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。* Z: h. L. |& a8 L: y1 L

$ Q6 N" v( `) ~" w' l1 Q. T8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。, ^. ~, z! s/ Y! x! L! y; c& C
5 L$ f2 `( w! V& w9 h: p4 n$ v
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
' y; Q, v& K: G- ~" N  [
' k+ d. B; u2 s10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
$ N7 W1 b. P9 F# Q& O0 K7 H
+ Y$ r+ k; f6 u- S11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。9 {# q) \9 V" M# H, w# t
, Q. b, r4 a# y/ T
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- d1 ]9 {0 O. n$ C/ ]0 I& v6 T
" D9 |) p8 i, A0 |$ _
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。* L3 ^  k/ @# L. P" {2 O( F. l

3 b% R' `( }8 C0 o2 T" h4 f14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。3 C4 v- ?3 S& L% ~5 p
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:1 F5 }  X- F( B, n" ?. a1 M
    function reduce_fraction(&$fraction)$ d7 ]9 |, Z" Z7 U) @5 c* H! t
答案是D。
' T4 W. d7 d8 _9 |4 Z: F( F) L( P. m
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。+ @# j: N% g4 l$ @( T& N0 S
' b* b- t. v  `, _: ?$ @
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。; y- Y  ^. w4 W# o

+ ^5 b1 ^, m3 E1 {" Y17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
! y+ |+ h: g' y# M5 k8 ~$ b9 K
: O6 H9 N% [! h2 w: s/ c' _18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
$ k7 V8 |8 C5 b6 g% l& P+ [6 ~+ f2 v  S. F  w" m/ G
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
. I+ n+ `5 N  _/ _
6 X/ g" v! f0 v) U20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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