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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
4 m, }$ f) W8 q+ nPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
  M( I& E5 S; m; D: l本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
3 p+ ~* l! H2 p
/ W$ A( q( j9 Q! S% M2 C* _4 \问题3 o! A0 w9 K" }" C6 b; N

" q4 B: L" Z" y. x) T1.对象的蓝图是什么?$ M0 F5 r+ b1 h' p
- |5 m  k+ z1 o( r1 [) m
答案:____________
9 y  ?( N7 B5 w& n& A: Y/ \" B: t" i5 I9 D( m
, N6 a0 m) L5 P9 p  ^4 v* N" y8 Z
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: P' a+ c2 d3 q
B.b
3 n3 {; `' o6 G# @$ u; sC.a4 o( p5 E, m- V4 W% x- r0 ]1 Q
D.d
& c3 K" g5 B* WE.e9 L2 j' a6 {) M1 g, u& \

! [0 ^& o+ n$ A  Y/ ]
3 u6 u2 Q: V( W! y5 R8 x9 G& q, O3 Q3.如何让类中的某些方法无法在类的外部被访问?( m  `) b, o: y

: [! n1 K+ }  \( \8 gA.把类声明为private% ?+ L  A: T7 [( F5 X, h
B.把方法声明为private" S$ w9 |# b3 p2 j  G/ ~  g
C.无法实现
8 \9 q9 J) q/ x, uD.编写合适的重载方法(overloading method)  k% w4 I, `8 ~* T4 Y9 m; q
+ ]# \' g/ O4 r

% ~5 j6 S/ a- T2 t- w& R4 g& f4.哪种OOP设计模式能让类在整个脚本里只实例化一次?' {% |# p0 X0 z2 `6 y
0 v' k1 l* D% d/ Y$ m' `$ y
A.MVC模式+ Q9 @) L3 w$ r$ S- j, S. K
B.抽象工厂模式(Abstract factory)
$ Z/ ]5 d; m4 O# vC.单件模式(Singleton)
6 q* x/ P1 f; v! {) u, U9 l6 DD.代理模式(Proxy)- x+ g" n( o* L8 @- ~5 {- ^" M6 y
E.状态模式(State)3 @6 p2 C) ^  h& h7 j8 _

5 t+ ~4 ^4 q4 @3 P' @' W8 J) ]/ R9 G( ^( w$ Z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?0 ]5 ^& p( u5 n; ^( O
# J4 B) J' T, l2 y6 L) |0 }) O
A.1个
- E# b( [  S; `7 O; z+ s( ~; W  bB.2个8 ?. _* y' H* r2 k; [# y
C.取决于系统资源5 W& L" [+ `6 y5 A# x
D.3个
0 b+ N* u, S6 I' Z& YE.想要几个有几个
0 X* p3 t( G/ e2 N! Q, @5 h+ h0 W
7 c( c7 p1 d" i& ~# L/ i& l' K+ m* a& w. n% s4 P; ]
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.多重继承
4 J1 d0 `) w. X9 k( ^+ QB.接口
# A; n# R. `+ o$ G5 f/ c0 e+ S* oC.抽象方法
- w# }/ y* H) g# t$ @& }  }D.Private方法1 P4 O- a/ k* p5 S% V
E.函数重载(function overloading)+ s7 v4 L; z, r

3 f. T% J5 f  p
. c2 p$ s- K* U7.假设定义了一个testclass类,它的构造函数的函数名是什么?
6 o- `/ X; N% A2 L! X9 D( G+ e* y4 D4 w& f' I( p
A.__construct
8 C" v! d% l8 f) nB.initialize! A. N, e! d2 d) ^/ `) K
C.testclass
3 _0 r. [5 m. w4 G. x4 P" P1 x& VD.__testclass
6 i* Q: }! O4 v) F2 ~" LE.只有PHP5才支持构造函数
  `4 I8 g0 |/ s2 z; d; \7 ^! }* i0 w0 J" I

- W+ c  Y) @/ f# L. v1 B8.一个类如何覆盖默认的序列化机制?3 t$ a! o! n. @, J* F+ ]
0 O) C0 j; r$ ~; W% R
A.使用__shutdown和__startup方法2 ~9 i! k, n9 Z  Q
B.调用register_shutdown_function()函数
8 s& B6 v% |8 @( \% w$ cC.使用__sleep()和__wakeup()方法
( {/ U6 z5 |" g  l, i7 q: O2 {: SD.无法覆盖默认序列化机制4 J0 A1 @! q8 P6 b2 {) D
E.使用ob_start()将类放入输出缓冲中- u% V: w6 a8 X2 M" ]! R9 T

4 E; j; S3 C! l4 K6 {& _, [" j7 I0 s+ K- i, r
9.以下哪些面向对象的概念无法在PHP4中实现?
+ e! [5 R2 @/ I. p* N  o. h
+ }6 A; H! e  _6 U5 P+ u" A4 t, x@抽象类8 {9 ~  ]8 J/ L  J" Z* J4 w
@Final类
/ ~6 }- `* z5 T$ P9 t8 m5 M2 N% L@Public、private、protected(PPP)方法
; g, p( u% x4 D1 R( e0 S4 Z7 C7 Q& `@接口& i5 s5 m: Y( k) D* e
+ P, k: A! r4 Z* `0 g6 Z
A.抽象类* I' R! d8 H8 W. n0 N
B.PPP方法! M. t) R! r+ R9 {8 F
C.PPP方法和接口0 G5 |5 W& R4 y
D.以上所有都不可用5 x3 s6 [; |' ]# t* ]9 Z( F4 ~7 l
E.以上所有都可用( \/ M$ _4 [% V, o
, K) \3 ^1 W9 p9 ?
  F3 z5 X' `) Y4 j3 ~# Y1 C
10.如何在类的内部调用mymethod方法?% m/ S' @7 _( y5 t4 D3 u7 J
- N0 y' A  z/ t
A.$self=>mymethod();
9 k0 h6 k# G4 tB.$this->mymethod();. I$ ^- t0 I5 L
C.$current->mymethod();+ D1 X. M7 ]# A9 I8 L, W6 V; g
D.$this::mymethod()
! i0 H3 F" s. }* IE.以上都不对
$ m: p  L8 D2 r- c7 h2 q9 ~+ ]8 \' t! {$ b; F; ^" k/ O
  T$ v0 p: Q' L! W+ b7 M" L$ U+ Z/ _
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
( `3 a6 Q6 d2 `/ LB.Null
; E, i  {8 ^# a) gC.Empty
1 V% G3 X  |% |D.什么都没有
9 q& }# W3 Y0 c6 XE.一个错误
6 `9 ~/ X. y8 A# F5 V
. C, O# l$ P( h; [- _& ]
9 @4 n  x9 m" X  A& }8 j) f9 f12.以下脚本输出什么?

  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% h5 T# K  y# U
B.52 k0 |( n. \9 ^
C.2
( y; \) d5 q; p* hD.Null
3 C, L' R( l6 `- KE.什么都没有4 g5 m1 L# m1 T( E$ }. Z

  E& c0 g+ |" z
" N2 W( _5 \3 b0 i& C& v* G13.以下脚本输出什么?

  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 k( r) B9 O; y/ j/ V
B.10
/ v2 L3 P. P4 u  S/ a' E7 BC.什么都没有- n& r! h9 L; x5 g$ C$ k
D.构造函数将报错
. F- f' |- k: W) p7 iE.5100 ?" _! T, p8 c* l1 o3 {2 W

# x  R' L' @- Q* H& t
# s$ X/ c6 g. c2 J8 W3 U0 I1 J14.考虑如下一段代码,执行时,$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函数必须返回一个值
; q) q1 B  b4 `! _( B. mB.reduce_fraction函数必须接受一个整型值2 `( s3 c. G$ P# W/ O5 i+ P3 I
C.gcd函数有问题0 Q+ Y9 p3 W8 f4 P
D.必须通过引用的方式传递$eight_tenths对象  }/ w9 k$ y+ S8 }
E.对象的实例不能传递给方法以外的其他结构。2 X. q' A  D' d( l2 z; p
/ p; m' }: @% D; M/ B: w

9 `  g, h! l' j15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
, M+ c4 k/ H- ]% I/ PB.生成myclass的实例并调用mymethod方法; g7 X. \) Y! ~+ `3 e
C.产生一个语法错误
* W$ l5 P; x0 w+ O* N1 J8 P! qD.默认myclass类最后被创建出的实例并调用mymethod()$ S4 V$ H. I: J; K' B: N1 w
E.调用名为myclass::mymethod()的函数
) m. Z* f/ P/ ^/ H  l  K- F: W9 O" C/ n' p  w5 f

: }; X0 Z3 J6 g! |16.PHP中有静态类变量吗?. z$ i6 m& f) G+ C

4 ?" F2 d  U" UA.有+ Q9 `5 V1 I4 Y- v+ ]% ]
B.没有
* O- r$ Q! j, x4 e5 ]6 C# S
! V/ f3 Q/ X6 U. }
% B9 E# s- N5 \! t: 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.1
3 L' s- H, P" O2 d' w$ K5 p* KB.2. b0 p+ B+ s6 m/ m$ }3 P' l( o, V  n/ }
C.一个错误,因为没有定义a::$myvar& `2 \, \. j! Z1 Z& ~* G4 H  w
D.一个警告,因为没有定义a::$myvar- x$ E3 X& g" [' d7 l) z' k
E.什么都没有! N& N  D. [7 j" g- D2 t# K5 \

5 l. N( I& D( d3 u" x0 q% ~5 X+ q9 K2 T& n5 z
18.如何即时加载一个类?0 f# u5 G( c* o  S/ t$ Y  l8 ^9 F

) v5 N8 k6 k7 d$ cA.使用__autoload魔术函数
. l" `5 b# Q8 I) i& ]B.把它们定义为forward类! }# u  r. V1 U
C.实现一个特殊的错误处理手段7 \# T+ i: a" X2 J" c2 g& b
D.不可能
1 g/ s; N. j$ j0 y, QE.用有条件限制的include来包含它们* U0 O6 \& o+ j. Z

% M# R- q: X3 u2 B% }) ^3 A8 J3 M- }. Q, \$ L: F3 r
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?; y& m3 m3 @! y5 c- S7 a7 S

. x  b) `* d! r, H: K) D    答案:__________
0 f% M8 G7 Y. L$ _% W
4 q. \. b/ V( q* b+ _2 l; P# 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
! B* s# k; \! p% m2 d) VB.一个错误
5 l& B3 n! T% S% Q! e$ `C.一个警告* F7 l9 P* _4 y; A5 ?$ e4 r
D.什么都没有
3 u! S7 Z, {$ L' Z# }, @3 V/ R/ P. V4 ^# x8 x: z

! d6 E3 y+ ]$ @4 R, e
' E% E' ]9 s) M) P- ]7 B- H答案速查1 Z) q+ m+ P# [8 b! `* D4 i. p1 e
1.类5 r8 R/ b/ h" f" h8 W. H9 p
2.BCD  {) R3 y" m: N9 [+ U9 ], E* t
3.C# f' }& ^, S2 `3 q- D
4.C
2 n0 w; X. e$ \; K5.A
8 ~* V8 {+ {2 u9 H. k' P6.C/ s, U! S8 {- X' Q9 `  v5 `
7.C
& H% X3 \3 |; C0 A: h' t9 _8.C
5 b! ~8 ~1 T- t9.D
' f7 S( {8 ^9 c+ a10.B: K) _  w4 f! ]4 C" J! r& I* c1 Q
11.D
) K9 K9 ?$ e! ]2 v12.B& B& [+ j7 a9 L8 o1 m
13.A$ `8 |1 F! Q$ P9 u/ @% }  Z
14.D
+ B- W4 x% A) m0 L4 f15.A% Q; y2 p# W3 D" R0 D& o( l3 _
16.B
& i5 y2 V8 e( N# e0 }17.A
! o+ i1 r. u$ \( c* E+ F- d( J% p6 R3 l18.D, Z: [- @1 q) U( |
19.设计模式
5 s( s2 |& T, \- F7 ?( {20.D
; c# f) Z. K- n9 N- o+ I' y/ Y4 p; p+ B) c1 h/ W3 m: M; l3 @" ~

( F: X. e/ u- u( g- V1 x
& h  p5 V+ r( x& n+ X' G  c$ o: F答案详解
% |$ ~) Q1 l! H% _, S4 }: W3 Q% s& F, ]0 b
1.类是对象的蓝图(对象是类的实例)。
4 Q7 e( o* w1 t  o  `% Y9 e
8 F, P. Z. _! s/ n3 y7 j+ s) H/ i2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
& d; b. C4 I9 h4 n6 ]- C
' u5 E7 P7 f1 B3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
, Q' g1 m' Q8 H9 k
' q9 A( X8 h# X  q0 ^7 ^4.单件模式可以限制一个类被实例化的次数。9 k- \' Y8 F1 Q2 n
3 U5 P: R" p' E1 D8 y! P. s
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。: `+ z" O' I* d6 a, z1 J

( P9 t: a; q& |+ M/ C$ K6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。9 ^% Y1 W3 c1 Z* S0 V4 y) ~
% S3 X; j/ a* _7 m9 {1 Q% O, [! m  X
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
: X2 w' c7 p6 t7 r7 g
) m% T7 J( ], B2 L! u2 u- h9 M  G8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。* p1 G( i4 u' w" }

3 w- N$ \% i% q) R2 @1 L9.PHP4中没有题目选项里所列的任何一个概念。答案是D。- c8 ^5 [' E. [& X+ U

) T5 T4 E+ r2 _$ I4 `" w10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
% r1 j( B5 H6 W& G" L8 c) X
2 \* }8 U* x) X$ F' U11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
5 Q* Z& R4 N5 s# J) d8 v% @. c$ v3 h
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。9 ?9 }- h+ v9 o
- Y4 N5 g' K5 `
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。9 @4 G8 G  B/ v+ J- ^
0 H9 Z1 P# A2 k/ u2 r
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
, D: R9 i; z% L1 Z回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
' M; q7 M. g( b0 O1 B    function reduce_fraction(&$fraction)
& g5 B& H3 X5 M# X答案是D。/ B( E7 ^, U/ x9 C  S; u* @8 L3 ^
* s, X; r$ y8 E, ]4 P: a3 W  e, \9 r
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。7 ?9 c- E" i6 E1 `# z6 X% s

  B8 q4 a7 K* o  Z7 S$ [/ Q6 i16.没有。PHP4只允许声明静态函数变量,没有静态类变量。& }) _6 p( L2 P  a
6 K( }) C6 a, q/ S9 U) c! b  b
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
) e8 v5 y- S1 e5 h! r
+ N7 q, D% U: p0 J1 K+ R* O5 \9 b18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。$ k# m7 C* @+ R3 K* N; u
, ^% G8 p* X& ?2 Q5 k2 B& F
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。# y$ M6 S  F; I* i7 \

6 G! G. l0 P9 h% E7 X20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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