返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
. |& z8 }6 U( Z2 H3 pPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。& X. [' i$ v* Z! \4 L
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
2 f4 q3 q, q4 I
4 v# L9 a4 a* B. i问题6 l# w7 a/ q- Q: y$ F, ~( m
/ Z7 n. W# L. W9 ?4 y
1.对象的蓝图是什么?
, y9 v! p" ]3 t6 q6 l4 }5 l8 p: J5 [/ v# f& p/ ]
答案:____________3 h4 b! ]' B% ?2 x# x. C
3 T! c1 T9 k- W% G

6 J3 D1 ~2 e4 g7 P$ v4 D2.以下代码执行后,数组$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
. G6 `/ X$ H5 JB.b  Q! t( r6 c% ^
C.a. ~! S" q+ @. `& ^2 j3 v
D.d% ?/ P! M) W1 S, W. f
E.e
4 r9 S: u: O5 j4 F
6 |' }5 w) ?& X3 p3 T8 [7 Y4 Y6 P) X+ K+ k. B" {) _
3.如何让类中的某些方法无法在类的外部被访问?1 m6 n* j# l7 w; s3 w- z1 H
( v7 f3 I( t! g) _
A.把类声明为private9 Y! h$ d/ f1 v- L" O# ^- y
B.把方法声明为private
/ _) @% j" n# p7 `6 }& a( wC.无法实现8 z$ w1 Z2 Y7 j6 n/ _
D.编写合适的重载方法(overloading method)) C8 T( h- t: L5 Y& ?; x

' v5 s& c: c0 i0 ]- J9 B
* R) o  a5 S# w: i, W3 Y9 L/ U4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
# M8 V6 S, T8 o$ Q2 U/ X0 U2 x+ [5 h4 v5 J
A.MVC模式
4 C6 a6 J3 z% B/ n- Q; OB.抽象工厂模式(Abstract factory)
, ^6 f  U1 A5 w4 M2 |7 c7 SC.单件模式(Singleton)  [( f' `( o) I, k3 i1 G' r* r& [0 [. z$ l
D.代理模式(Proxy)
' w# v1 B5 m$ P  \- y/ U8 |E.状态模式(State)) x# T9 L; g2 F$ ~
5 ^+ A9 d5 I) C: t( n* M- S3 i

* e4 p* o) t+ ?9 k: W5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?, F$ i, M# z4 s% O% {! c
+ Y% S0 `7 H: V. |) D1 N5 e+ l+ t
A.1个% ]! W- Q  ]$ n$ k/ R2 X
B.2个& q3 ^. Z  K7 ~. L* i7 N5 R
C.取决于系统资源
0 L' ?! b% N6 vD.3个4 W/ S; {8 l6 s- T- c1 V! L/ E
E.想要几个有几个, H9 c3 M( I& ?) ^7 ?* G" L
/ g' |* ^( R# ~7 Q
3 ~" H0 j, _, C& T- W
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.多重继承
" o0 W, ]8 x6 O+ t5 e% b# @4 uB.接口
" @3 o. p- _, \- tC.抽象方法# ?6 Q0 r) J0 c$ m/ I# F
D.Private方法4 _1 l# C: V% a1 j. s$ o, U
E.函数重载(function overloading)  V4 z  T. W/ ]$ N% m

5 D: G6 ^7 h" V2 M& k  S  D
6 [" P! |, \# Q% N7.假设定义了一个testclass类,它的构造函数的函数名是什么?
/ i) e' F" N3 q( u& n& g; S
9 V) R# \. B8 c8 DA.__construct
2 P; F! h9 F' K5 _% t# jB.initialize
# u; A- {! @4 x' n& [* a. s) L! K! I: aC.testclass4 n, |8 N/ _1 X3 R5 N2 P
D.__testclass# O$ M) x' ?: C9 t8 ^" b  z' Q
E.只有PHP5才支持构造函数
! _) c8 j/ R+ m3 z0 N3 B5 E
: P5 g, w+ s5 K+ V! L% W0 A5 {+ u7 z
8.一个类如何覆盖默认的序列化机制?
7 j! Z( I9 ?+ r3 ~8 Z, B& z7 C$ h" C) t4 F/ u9 o, a: l/ m
A.使用__shutdown和__startup方法/ D. [/ s9 g& N4 T( M7 Y
B.调用register_shutdown_function()函数
# c, J, i! [6 ?% h& N+ uC.使用__sleep()和__wakeup()方法
$ x; f7 Q  `1 u5 v, Z; Z2 d# \D.无法覆盖默认序列化机制
+ g% n4 \, C9 R+ J* f+ {E.使用ob_start()将类放入输出缓冲中
( Z2 o# h; D. Z5 Y' E. P' ?0 O# J- m4 Z  B
1 F, e' L, _1 I8 {+ f- b
9.以下哪些面向对象的概念无法在PHP4中实现?' {3 {7 P( Q) [
) h2 o  M1 t% N; E3 W: T
@抽象类
6 m) v4 ]- ]! d4 a@Final类
2 k( A: N. {  k, g% W9 u6 e@Public、private、protected(PPP)方法4 x3 D4 {3 a, o6 y3 M" v
@接口
5 b8 Y8 n( A& p5 V) O( h& |! i! E* Z5 I/ z. g7 r
A.抽象类" {: q- N5 R0 J6 W5 R$ i: I
B.PPP方法# ?8 v0 G6 C. c3 u$ ]* F
C.PPP方法和接口3 S9 P( X& T7 d$ m
D.以上所有都不可用
( M0 p2 b* t! h! z# l2 [4 k% Y2 _E.以上所有都可用
+ a# b% g" V$ J3 ^# g
7 C) a" ?5 d: }1 ?" C! M8 }% w2 x  d" c  b& `: W4 _. v
10.如何在类的内部调用mymethod方法?
, o0 _% f9 B5 n
. t5 l" b: @, NA.$self=>mymethod();7 R; m+ j8 X3 B  U7 D6 x; h6 a7 t" B
B.$this->mymethod();
2 H9 K! `( `: HC.$current->mymethod();, `$ G  b( l6 S% J) j
D.$this::mymethod()* f9 }  O% \, v2 `) P
E.以上都不对4 V& i) v* b& b) Y! P3 Y# l

7 P1 F. T$ P5 C7 J3 w, B0 s& s: L7 s6 z/ K
11.以下脚本输出什么?

  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" u$ K1 j3 C% F# x& S* C
B.Null" l# S9 l9 W2 T! e  X
C.Empty0 `  J- @3 r6 U8 R$ Y; @' ]
D.什么都没有
" x7 t1 l0 i! B% P* j  H; uE.一个错误
' H8 E1 C2 p1 _5 Y7 |
/ a- h5 v$ q" u$ n  W
: j$ c/ f8 G+ O# b& l" Y12.以下脚本输出什么?

  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.102 Z# {. k; m; w2 X1 k+ O8 `9 J
B.5
8 Q' C9 g3 c) V1 }, a7 V1 V; ZC.2
0 n+ U; @* M; O& I3 YD.Null0 q1 p: r. A+ R
E.什么都没有
7 J" U8 s( |" O
2 m- p9 n7 q7 T" }2 P1 y- e, a' c. `8 K# ]3 ?
13.以下脚本输出什么?

  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.54 C1 Y2 R6 R' D0 k7 [. U! o
B.10
  ~  i, S& o$ G. k7 K3 }C.什么都没有
- o( A3 `2 A+ P* A3 Z; wD.构造函数将报错; O3 r0 {* A1 d+ ?! N2 k* l% h
E.510; \' m7 C& x% I" a

) C# [: F0 r, `+ ^8 W
* l$ H, d  U: j+ k% I14.考虑如下一段代码,执行时,$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函数必须返回一个值( E6 r- y0 s, X) C) ?& p' h( r
B.reduce_fraction函数必须接受一个整型值
1 X3 s' A& v. O# ^0 B5 lC.gcd函数有问题0 n3 r0 Z3 P# Q- ^, p
D.必须通过引用的方式传递$eight_tenths对象
$ C' P5 e  k; i9 x& U. PE.对象的实例不能传递给方法以外的其他结构。1 `8 V6 D2 P- y4 `) `

" c7 z; p% q9 o- S7 B& @
0 q# f5 I- p$ @15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法# o4 N+ E3 y' S* ~
B.生成myclass的实例并调用mymethod方法
$ t0 n8 H& V2 |5 i2 yC.产生一个语法错误
, n- ]0 j1 @5 }/ C" Z9 eD.默认myclass类最后被创建出的实例并调用mymethod()
8 H0 o) M# E1 mE.调用名为myclass::mymethod()的函数' x8 ]0 {7 B+ N9 Q, t4 U) q
0 @: A4 V5 A. f5 s$ E$ J
- U. t, w7 \( U( t$ `( V" b
16.PHP中有静态类变量吗?3 }( E+ X$ q$ F' H$ b: \2 o

9 }4 v* _5 o9 a; H' ~) k" v4 X; hA.有  v4 L# w# Z, c1 o- b: k3 f% Z: p
B.没有* z7 {; y, ~; a& J+ T3 E  s$ u
. Y1 c1 W* A2 j  l$ |

& \6 K3 k% e7 K0 Y/ H! b- u' U17.以下脚本输出什么?

  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.15 \2 i7 [; s1 U( ^$ j0 o
B.2
0 D* y, F7 V/ r4 M- y3 p. cC.一个错误,因为没有定义a::$myvar
  r& d) e  t' [+ j) Y' D6 n% jD.一个警告,因为没有定义a::$myvar
! A) ?& i! V' ~: B6 N" wE.什么都没有
7 L4 A* e* O6 z, O+ P3 q
. ]6 o1 x. A5 r+ M2 d" t6 z& b* h% |  b0 }, [4 I. q8 d- p
18.如何即时加载一个类?4 \* i( N% V/ [- h

+ G7 n" h; r5 p# f- P0 UA.使用__autoload魔术函数
' `6 t5 X6 A) K4 l3 @: n$ h- PB.把它们定义为forward类
$ ?  V" `6 \, E+ TC.实现一个特殊的错误处理手段0 w/ a+ P0 V9 n; s1 l  G
D.不可能
) g5 m1 H) B6 V: W3 I# F: [E.用有条件限制的include来包含它们3 S' m( e3 Z' R. k, J+ A' {
: N: h! F8 W4 t5 W3 b9 n

, f3 A1 t! O6 c2 ~7 b19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?+ w% e8 n* H3 M, J% Y" p8 j
4 K. x! `: Z* Y/ r  d! u
    答案:__________
& w* \( c: A7 v( y6 {; Y( O
) ]& P3 m$ `( U- F2 O( S8 i2 @, Y8 U
20.以下脚本输出什么?

  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
/ v( ~4 r) W: s; ZB.一个错误, z2 |) b; p1 X7 s* k2 S6 f
C.一个警告% l: n; R( K" F2 v
D.什么都没有
' @" g# V, Q2 ^/ j" [
# X2 K4 N5 G+ i" B5 P5 O
1 h( U6 G! m' n' Q) f! v0 y3 q! Y
8 P' f4 L0 S- m! `/ `) V# R( m答案速查
  x# e) S  L5 Q- z! |& R1.类/ q  Z- s0 j) K; J! n
2.BCD# J3 ~* b# ?+ x
3.C. a+ m  @# F: e+ [# y
4.C
1 g0 m7 E% U. r# D& V5.A9 M4 `4 u: L" S
6.C% f, e# ^7 A; T7 T1 \5 \8 w3 M
7.C4 h) H3 s  Y# W9 w
8.C
/ g  g. W2 p+ n/ Z0 I9.D% p5 a5 M2 g( S$ c$ I6 {
10.B
; J# e) E) d5 @# s. C11.D! [$ u' S: i/ I$ N/ i
12.B
9 o( A$ ~$ e! l% U  O) R2 u13.A2 S' P' _6 z, E! R9 Y
14.D
. m% \/ G. @( N7 @15.A5 c3 \& h8 F' R& W3 d; ^2 ]
16.B/ P5 t3 m; X+ o" O! u
17.A3 ]. `, O, k: h  w2 ]
18.D
5 ]8 r; h. _% b, R* Z9 J! I/ {19.设计模式* ~' a- v0 d  N
20.D) `) Q7 |1 {) c. |
) E- ]4 \* ]% y* O

1 r# C& \# `- C0 o& t3 @, H( @  |  S( ]4 g. g0 B1 w
答案详解
2 ?2 g7 k+ V2 }0 ]5 i
/ `: W+ Q# v/ T# w1.类是对象的蓝图(对象是类的实例)。9 T) o8 P6 A, c# v

. E; d: n/ A) |( x. _2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
1 ^/ c7 d5 {1 C, y# ~' V! n1 P3 y: j- E: Q9 r
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。1 u& V. f( Y' b- H  T
8 u6 K9 `9 ?6 V0 U: o. T% T+ T6 d3 }
4.单件模式可以限制一个类被实例化的次数。
& ]  j' q$ ]( s# H1 h. h4 l8 d! m
8 ^( l8 z3 M" z# C0 t8 K" v. Z5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
. e2 Z$ Q, T7 D  H
* {/ m7 {/ c% P5 ^( m6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
, ]& M' X; |$ |4 @) A& ~2 B% f
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。" Y) N; Y7 _, k0 B/ Q
) V6 U8 l1 W) v  Q  L; q* o
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
2 x# h. k7 P+ b: e: b
9 T" |) d9 x% ?! R8 E8 @7 J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。2 K9 o( h- S7 M2 S$ O6 b
+ L" m$ [( x5 s2 M
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。4 x2 S' M2 |& p
: l6 p/ j5 S& e7 J6 c0 @( S- d
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
) }1 Z% _' m: O( R6 h/ Z
" |* F4 B/ U. @$ C12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。0 Y# P7 C3 i$ M2 ^
6 e# J: k! L1 @* S+ g# w/ Y
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
3 z0 P; `4 F7 ?; Z* t  ^: t! l
* h  s' Y3 H; c9 Q; i! U14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
8 K# z8 e8 }" h& |$ h: k9 i回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:- p; R. [! \! L/ o
    function reduce_fraction(&$fraction)
1 g; G9 C, y& v6 e/ \& C4 T# S答案是D。9 v8 `  ^, [% [

& o6 v+ D3 m+ r- i" c3 }15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。: e1 g( z$ S" c* l

( v4 X! J/ f2 v! ~* H' b; \16.没有。PHP4只允许声明静态函数变量,没有静态类变量。1 _: ?3 J+ q8 \% M2 {6 q; d
* z$ Q4 u# s0 r4 F' ~9 O
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
* r& n) E! e5 |3 y$ ^, o; l4 c+ k5 Q! V+ @: n! K! ~  v
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。; n1 K5 c! |, [$ M+ R( Y

- \6 o4 M; \0 ]8 h$ e5 ^* K19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。. t6 f# }6 m# t( |# H

; Z: k- S/ n3 k3 V& S* a20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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