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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
3 Q5 a3 U6 G+ DPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。' ~3 t* ?  j* k, ]
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。* C/ S0 p* M2 G2 v8 L/ ~, w
& C* S" F" r) T
问题
" D  S3 c$ B/ P# s; c1 R; M; l: j- G- z
1.对象的蓝图是什么?
7 O  h" d( l; c, Z. }& |' F0 p' ?$ z: u! ^
答案:____________
. r$ C) l9 M) M  `1 y4 J
, W0 ~9 G! k! q% c: c( S$ @" i2 Q, k1 o$ e2 H. p5 m
2.以下代码执行后,数组$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
7 Q/ q9 x6 {- L5 fB.b
6 D! ]/ Z: A0 e7 c. Z; L2 `C.a
6 P) d# \" [, s! s$ t6 oD.d
8 Q8 p' y9 [3 `; o9 B8 a3 z( CE.e+ E. F- J5 H8 Q( d# S
; s$ v1 }8 k- }, S% V4 d
9 ~* ~8 n# N8 S/ b6 {- ^: O
3.如何让类中的某些方法无法在类的外部被访问?' V- j- U4 S/ Q+ c7 e7 V4 {7 H- r
1 [- J8 \, a0 O& ?, ~- c/ H  n
A.把类声明为private4 j0 [1 Q9 C  T9 S, ?4 ~1 C+ B- l
B.把方法声明为private
% t! {- F$ [: \. EC.无法实现6 U# l6 _1 x4 d7 I8 a/ x2 N% O
D.编写合适的重载方法(overloading method). l7 o$ Q! ?* {( v

9 x7 H7 V6 C3 l7 ?1 x5 x' s$ m; P
5 {) S4 v6 R4 |9 n; ?* ~4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
7 X/ g: b5 B  X3 `7 f- L% V7 [: i, J& m6 b8 Q* s, ?2 b
A.MVC模式$ x) ?' o! J) K$ B: q2 ?) i7 F; P' f- S
B.抽象工厂模式(Abstract factory)
3 j0 G) @! {8 Q2 w' b5 W+ ZC.单件模式(Singleton)
4 F" c: g# h8 F) D, MD.代理模式(Proxy)
$ {0 a3 C) c4 s  W1 W; A' PE.状态模式(State)) V  h/ s, ~# [' B+ [

- ~9 H! }. n. z7 _2 L, S
/ C* ^6 u# e- \4 |5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?" B4 E' h, {3 K1 h
! x" [* r2 w7 ^! k1 v
A.1个2 V6 B' P2 b9 n# d6 o" f+ p* F; D* y
B.2个
- q; c& @9 L; K) w# x1 a8 pC.取决于系统资源
9 w7 x# O- h5 q9 DD.3个" y( k8 s( g" \8 F4 P* z% ?, E$ K
E.想要几个有几个
$ f& A( ]; [0 m- _- p
, u* U0 Q: n/ N+ I0 X' O& U3 Q; h) S' L: P) k) Y1 n( h
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.多重继承
- p; Y+ o! J$ R: ]9 I( [B.接口+ O" [- W9 X! y. g0 V
C.抽象方法# d- e& T$ |  P) m
D.Private方法
+ r. Z# r& J4 d3 M8 cE.函数重载(function overloading), e9 B1 |: p1 V5 S* l: O
/ V! e: F; l! F0 e! V3 T0 y
& m! ~! k5 C% L( v% a
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
6 z! U" i4 c9 q% W
5 d$ R  n0 Q" x, x5 D, ~7 V2 E1 tA.__construct
. j" `" i8 ?8 {: d+ y/ B- b5 ?3 |B.initialize7 M# G5 S2 M' b% J- T
C.testclass
4 L& ^& T8 ^# _D.__testclass
8 z1 s0 S( L% D% TE.只有PHP5才支持构造函数! r! Y3 S" n4 ]' v) u$ j$ M1 S
" e2 A3 g' O4 l* ?, X" _

) p" g* X3 W+ [) w7 n) [% y+ y8.一个类如何覆盖默认的序列化机制?
' b' ]+ L3 k/ j8 h; A+ A1 V8 X! D- |
A.使用__shutdown和__startup方法
/ W# j, p3 D3 J) F, }" Q. sB.调用register_shutdown_function()函数( o% O/ C. E; ?
C.使用__sleep()和__wakeup()方法1 p% B% o# c* |# ~
D.无法覆盖默认序列化机制$ K& n$ Z  J. j" `9 X* _' h# h
E.使用ob_start()将类放入输出缓冲中* g* R. `8 v, S  i, l4 Y

& u) B9 Y1 [5 }. _5 Y
1 v& k9 q! C; H5 P* x+ ], T0 Y9.以下哪些面向对象的概念无法在PHP4中实现?7 U. D/ C9 m# t; p4 d

+ V4 K; R7 L1 N* Y6 M@抽象类
7 [3 g8 @" l5 R" ^6 c@Final类, o( X3 I) K, Y- X; I$ @
@Public、private、protected(PPP)方法9 o" E6 q' ]2 N
@接口
+ k: p- K; {0 M2 F; }1 B: n' B8 K' y/ [% o) X$ @
A.抽象类
3 D2 h# z6 j/ s! MB.PPP方法. `* \+ f, M3 B. l
C.PPP方法和接口1 l6 S# _7 g) D+ p
D.以上所有都不可用
! z) N# @! Y( KE.以上所有都可用( f. @3 V1 T- t) x: z
2 G; d# G# w- I, G% b
$ D" K4 U  i4 c: b" k& B) I
10.如何在类的内部调用mymethod方法?
6 P% Y# L( [1 ]5 l7 ~6 d1 M2 _9 Y- @9 y+ F, K4 W
A.$self=>mymethod();
, ^, ~0 y/ `- s, s  xB.$this->mymethod();2 j0 p! N, O4 g- h3 B; T  N+ f
C.$current->mymethod();9 u, M: m3 I! H# t- B* Q% j# {
D.$this::mymethod()1 m% L$ H  K& @4 a% C4 ?. N  i
E.以上都不对5 e8 }7 U/ [( L6 R
6 ~( h9 E  ~& \: |

- u' h% F1 u9 \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# H& A5 t# i* R/ r0 _
B.Null7 L, d! n' H) A0 ^" J% B# M/ N
C.Empty5 A' `; e" j9 y& D" [
D.什么都没有
6 I& t% Q8 z/ t5 yE.一个错误
" u1 {9 C: D1 n
) B( s( R( O" Q5 [. E
9 l! K! M0 M/ K. O$ H" x12.以下脚本输出什么?

  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
8 H& J* r$ u, v( N- v( KB.5
0 ?9 X- o! ~5 T/ C$ A4 z* [) jC.2
  F7 [+ ]/ r( iD.Null
- D, F9 a# z7 q2 U$ WE.什么都没有
! @, H& f7 |5 L/ h
6 Y7 ~5 [0 E. r; H5 x* A; o! Q6 b2 \$ I
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.5
% f" E8 |* }, I  QB.10
1 e4 x3 |4 Z% Z9 o" PC.什么都没有
) R# Y$ a, @5 H/ TD.构造函数将报错
" k8 X+ d$ G0 {( g& {E.510
" X1 b& e- S4 H$ C5 v) ]6 q
' ?, N, X5 T% `+ m) w" O/ J' g; f0 a8 k
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函数必须返回一个值/ n+ ^: c5 n6 M5 ?1 A3 x
B.reduce_fraction函数必须接受一个整型值
! \* E% c8 w' p4 n2 D, aC.gcd函数有问题
- {4 X0 }+ z6 h; iD.必须通过引用的方式传递$eight_tenths对象
0 e6 q. L9 `3 n; r7 dE.对象的实例不能传递给方法以外的其他结构。
) N( Z& n2 p- E: n' e. T* A, r/ q7 C  U7 v, A4 S8 q
, z6 ?7 p6 Y& }' n4 @/ R7 n* {. j
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
% M% I' [- R+ q5 {- _B.生成myclass的实例并调用mymethod方法
8 p8 `# f$ e" P3 S5 m( k4 KC.产生一个语法错误
; _' i8 ~, [$ Z1 _7 v- u- I: FD.默认myclass类最后被创建出的实例并调用mymethod()
' U6 j" `9 y# {7 {! ]. V2 n/ K9 lE.调用名为myclass::mymethod()的函数
+ [$ p2 S% U5 g9 w" l7 Z& S
! n- Q; T. u/ [) U. p& {* c' c: l- p  f, u
16.PHP中有静态类变量吗?
0 h% c# B) \( d5 E
) v8 l3 c& \# RA.有
: C" O. c5 k; ?$ M2 uB.没有
- C! l1 T! a5 T+ u( q3 j3 A% H& r
$ k( O) [: ~6 i/ |3 j& S5 n& }  S; y0 v, g# I* z, a
17.以下脚本输出什么?

  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
& w2 v  z) Y' I& G; x7 EB.2) s2 p  v( V, j, j  ^* N
C.一个错误,因为没有定义a::$myvar( ^7 ]- f! z9 v& F
D.一个警告,因为没有定义a::$myvar
& n: p8 `# X/ M8 FE.什么都没有
( w  A) x! Q0 |8 g8 Q0 E% L  k4 F
: a# l- W- h8 G$ k
4 y7 i/ o, ]( K7 y- H* F18.如何即时加载一个类?
; Q8 F$ v7 L; S- B: O: N5 q, S2 H! b4 C4 M, R3 |! e
A.使用__autoload魔术函数
* O9 g; N/ k1 \! ?B.把它们定义为forward类
! Z2 S9 b# B$ e3 Y4 P& ]. r+ QC.实现一个特殊的错误处理手段- @6 P, b% [! a
D.不可能
& z% N) N: ~5 Z6 N: ?( QE.用有条件限制的include来包含它们
  V# \) L# k  I7 i5 v0 q* B
0 [8 C# T5 b$ L2 W- T% Y; ^- G
: q1 ?4 \) I) n, G5 T4 ^$ Q. v19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?- `. g. n, E& B
# }# V# U( s. u" R8 e: I; g
    答案:__________; f. Q+ U# H# y7 q: {; U. L; C' y

3 }7 i8 Y1 o8 j' P8 o1 t& q' W4 y" h$ U/ Q) A& ]
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) r0 Y- m" J  {# [: x1 [& s/ R0 L
B.一个错误+ d9 d/ U% T& S: c8 c8 X& ?" X
C.一个警告
9 U; X. M" S8 d6 _; z# [0 jD.什么都没有
$ S8 W2 h, K$ L0 W7 ~
8 k$ |; ~( W" s5 x, _
* j. f; C- w) R' N4 ^! w5 b! C* M$ [1 T+ `) s& S) U" t) _
答案速查
+ y" ~# E' I2 I* B1.类
" z( g2 _4 ?8 ?& s9 ~6 o2.BCD9 h( E+ {  U6 j- M. w
3.C5 F% G, D, B- A) o
4.C" h2 [* e! K- a3 l4 Q! S! j9 b
5.A
% x* `! q, g" p7 E6.C
6 C/ [; G1 \3 Z1 }; f7 J, s7.C
$ S; K" y* O) k  ?( b+ i8.C; h9 s) D$ O. g( y0 \7 Z
9.D& m8 k' x" h. U" y' w
10.B
7 e% [3 f! N& n* R5 F11.D, T) `* Q" g6 l9 s9 d% I
12.B! ~8 l- D: M0 ]9 a* \
13.A
# s1 B" v# o& n2 `! y14.D
! v- i, m- ~1 Z+ z, L" b- }15.A
, B* N( v0 n2 k( O8 W16.B
  f& u" V* L0 H1 N2 v17.A
" W8 W/ e8 }5 d) l/ e- i" S6 e18.D
3 t+ y: ~4 m) Z0 w$ W19.设计模式0 p! i0 v+ C' x7 _3 ?
20.D$ R; E) A6 w, b& k* O

, l9 w4 p% |3 x7 z9 z9 x; L' K
0 b& Y: u% P! z) A$ N  k, @/ g
6 v7 N0 Q: y3 B% ?; I答案详解7 n( Y1 D! m( {
: R# v% G4 F9 m
1.类是对象的蓝图(对象是类的实例)。
2 W( c- I- {  j$ u' B/ f1 V9 b. N+ E: K
1 T; V$ m7 T4 Q( o+ t2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。+ V# x3 o$ n9 j. ?4 P
+ |2 h2 `5 |. U9 z& [
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
( q: C6 R! P) n/ y8 Y! D
" o, k0 o0 U; B! h4.单件模式可以限制一个类被实例化的次数。
) N' z  |, e- C1 N0 k  H2 C# w$ A/ B; Q* c; \. G, a* B& v: f
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
. H4 g1 b. a. `! N
1 I- F6 j3 M7 v7 f/ x6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
, r6 n; D+ b! ?. z% ^0 i, @( B7 h0 J) G" f, M/ L) Z
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
; u& y- M0 I, f; k# Z" M& N/ Y, X
- g, U  F9 H: Y8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。; Z5 s5 b1 W- Y. ?: H& C

; N9 b0 S  ]/ w9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
+ K: i9 f) w' G8 ?6 D3 h& \+ O1 g7 G& y  X6 p/ Q
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
) P% S0 c5 w$ {
* L. o! T# j! _; \) u- X11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。8 C% W  ?- [/ z0 y

' o2 x6 V: u* A/ }6 ~/ M9 S12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。5 ?# ?5 p5 ^, f: G. U* E; @2 f3 D$ Z

- M3 F3 h4 k  g8 g13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。5 X  G  }3 W! k' d: A4 F

% X5 }/ g9 a5 Z1 v6 L- H( f7 f14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
; Y2 y: l0 O) V) R; `回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:- C+ Q& e0 U4 n6 E
    function reduce_fraction(&$fraction); ?! J' a+ H2 f  z
答案是D。" E, M" F$ U' T. |  F" H
2 w' Q  @0 `; p4 |3 b- y
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。; I8 j) K4 C) @( @
" |' r+ F9 j) B. [! W% @2 ]7 A+ o. f  Y
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。4 w8 O. _3 V) g" Q

3 S4 c( c0 e  D17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。6 u0 L: r; p, v! L

# K+ P3 d$ I( X, l' [% H" F18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
  y9 n0 v7 m  W$ w- {# Y( F* f
/ t/ G3 u; v. O; z: N19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。* B) g; o7 ?$ m" G8 ~
  ]; F& {6 U  _/ s7 q! k* F  J
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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