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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
6 d( M' m. N; o9 U7 l$ ZPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。8 G6 y; i/ g6 P3 P( G$ r9 e1 j8 O$ Z$ N
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
3 b' A" p  R* \6 {$ ^9 ?
9 _+ C0 B: M+ \问题
$ N9 A7 }& Z( i! |, H' S( N9 i. h8 X8 f: q- H& G4 K
1.对象的蓝图是什么?% d& }/ T1 t4 G/ Q0 `
% \# p5 p6 @' q2 `# l4 a$ o9 J: N
答案:____________
. Y/ L& e2 j9 s5 e' ]5 P2 s3 j5 f& ]; `
0 l+ Q' B( l' M# v7 v2 W  ]
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
) ]: I- N0 s+ @- f9 RB.b
! q4 z! K5 n: bC.a' ?6 \0 e# A- T; `
D.d
, u9 b9 q/ x* O* L( a! q; NE.e6 G( o$ K6 Q( ~9 r6 H/ ~
. Q1 A4 N9 x% T; }1 y0 W3 k, _8 W; r
* P8 {) s! M% F1 \- C2 C
3.如何让类中的某些方法无法在类的外部被访问?
9 O- p' \3 }" E
  h* w/ ^; p- Q& C# b' \) J2 P; _A.把类声明为private9 K" z( [, }8 T' t# r& Y
B.把方法声明为private
7 ?) Z* c. m, c  V6 U( tC.无法实现+ r' W% V% g7 G' K- Q
D.编写合适的重载方法(overloading method)+ r: r1 q& P: q" y
/ z- H5 U) Z! Z- i, @

4 Q/ P9 D' Z0 H$ w' g5 F, y4.哪种OOP设计模式能让类在整个脚本里只实例化一次?# `$ i* j( v7 C+ x# o6 P8 y

, a, m+ }3 a/ Y9 i: _1 {( Q+ H2 ?A.MVC模式+ [5 U4 Z! m# `' ]& u4 i
B.抽象工厂模式(Abstract factory)
3 O* N# ?+ d& V9 hC.单件模式(Singleton)
' C' J3 e! p4 w0 y2 uD.代理模式(Proxy)6 v+ K6 m& u+ z3 h; d5 ?
E.状态模式(State)2 h5 A. b2 }6 P) w
, M; ?5 I/ Z+ u2 \* @

& ]# e6 ~8 t" D: H& s2 J5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?5 w& M% N+ f  j0 q9 C. N* u

) _& V! l1 \( \3 w) N" bA.1个
% H$ [" C" V' \4 Z) \* H2 ]B.2个9 ]$ [9 G, n! b
C.取决于系统资源
0 K1 j2 S8 T! Z1 H0 d, e8 _/ h5 |D.3个9 v, f9 l8 z7 x
E.想要几个有几个6 r5 ]# m: T2 B* K* n
) b! e9 g% M' V+ X
# X9 F& r3 {  ]7 F' W+ B
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.多重继承
* i' j0 C1 M& b6 h: T; b3 `B.接口  u5 A0 D% T5 N  `
C.抽象方法0 }+ E$ E+ I5 O9 N) T% ~3 p1 L" b) q
D.Private方法
2 c7 j5 L- {* {! t  N+ mE.函数重载(function overloading)
+ J& E/ @$ R, n5 O" ]$ k5 W: s) r# @0 r2 E0 E* t4 [* R0 ^* \

! }( e' s$ ~5 A7 R8 n7.假设定义了一个testclass类,它的构造函数的函数名是什么?! G7 J$ b9 }$ P  J

( m. a: ]; G" x' Z% ^+ Q4 FA.__construct
1 G: \/ y( S& \, qB.initialize. c7 `) e$ e! _& u2 S* E
C.testclass0 j+ W! t' v3 m# L
D.__testclass
# t8 W) d. u2 h. Q1 e5 A5 u; jE.只有PHP5才支持构造函数
4 h6 N5 M$ V" O3 S1 h6 @
$ X6 n3 i) V* h4 h
' |2 S( i6 k7 z* P* W8.一个类如何覆盖默认的序列化机制?
+ }0 T' g, ?7 S% M6 z7 r6 p3 S6 b; l3 b' ~+ Y; L% `
A.使用__shutdown和__startup方法
8 P5 `2 T% _% j& a( wB.调用register_shutdown_function()函数+ p3 ?+ M6 i' a" N) e# b# B
C.使用__sleep()和__wakeup()方法
, G; p/ r" l/ u) R6 W0 P( mD.无法覆盖默认序列化机制
& i9 f5 |) d+ M! o5 i. uE.使用ob_start()将类放入输出缓冲中- {5 L) x) s9 w
# C) s* q! U# F3 _6 ^% _) M  X
* r! C5 |, Z* @: Y9 J) T
9.以下哪些面向对象的概念无法在PHP4中实现?3 r! ^4 `/ _/ C- y5 ~
$ P: l! z( [  c
@抽象类
( v. F6 w1 v6 _" x- Z5 w9 b! v@Final类0 ?+ m, J9 {& o1 n- A7 K8 h0 b
@Public、private、protected(PPP)方法
0 O1 P6 [0 C! Y1 \@接口( e" i& ?/ r9 v0 n$ R! c

5 H0 A$ N' m0 B3 FA.抽象类  R9 z& H- x2 y! {/ N
B.PPP方法3 S  w9 D8 X' O0 d  S8 E6 f) O
C.PPP方法和接口
! s# W/ ?/ I0 fD.以上所有都不可用$ Y- p$ c+ V, ]; y- k3 |
E.以上所有都可用
: h  e1 k* J" z. u1 _+ G6 Q6 m% F, L- C, S7 |) ?4 b9 p
' `9 u) Z1 M6 {4 G+ o% Z
10.如何在类的内部调用mymethod方法?
) z9 B8 t& n0 K0 r, ^7 R+ z
5 S( p$ u0 A8 gA.$self=>mymethod();
, H  v" F4 Q' J' F) B% L/ IB.$this->mymethod();
! e( G+ t5 d- Q& V; K! N$ zC.$current->mymethod();
2 n- c7 G6 {8 aD.$this::mymethod()
: o% T# f7 B2 y0 A) G1 `+ o+ tE.以上都不对
  `0 u1 x. g% r9 C0 z2 f/ D. D# ]% E# {+ R" _1 R  e4 V
& u2 g" d$ g+ l1 Z2 \2 g
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
5 \' U6 K' c- U0 @+ z9 S1 NB.Null
6 Z1 t$ Y. c2 m( o6 aC.Empty5 U7 Q# J! ]3 R' y. `- H! K' A
D.什么都没有
( {! F: N' w: ^0 Y; qE.一个错误7 R; S3 M) w% u) W
$ D3 a" y8 _; q; Y; E% t3 l

( t* ^1 y0 J4 m( W. g2 Y5 m' f4 ?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.102 y1 }' u7 v$ a+ S
B.51 f/ y. F/ t. a$ D! z7 V& O
C.2) P$ t0 p  L; d
D.Null
0 K2 L) K4 @' F! W% _& c/ \E.什么都没有
# O+ s" _3 {* V7 _
8 `2 Z( e+ z7 f! @* n5 w7 k2 {  `& c1 K' Y" G9 j& j* U
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) W2 ?8 J3 J$ ^* C, }4 L/ L# P
B.104 `5 q9 y+ l7 C" `, v- E' [
C.什么都没有
* S; j. x/ J2 HD.构造函数将报错6 _; ]  R2 x+ G; K' K
E.510
- M9 [' @; G6 E+ q& m3 V
% }9 n& L5 \# R
# L: D# G) k8 W8 h2 c- b( H) |  [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函数必须返回一个值* F) ?& }3 z( w3 J8 Y! p/ k" q, R
B.reduce_fraction函数必须接受一个整型值+ Z) ~$ ]8 ]& }/ }1 \+ Q
C.gcd函数有问题& ]3 N$ Z& e; m$ p1 t( I* e2 l: p6 _
D.必须通过引用的方式传递$eight_tenths对象
4 K. ^* s. [* @0 R9 s# q& ~E.对象的实例不能传递给方法以外的其他结构。' E& V% T% s/ J9 Q' F7 `

4 p/ k; x2 L1 d/ ~/ w* p  w
" b+ H, u5 _, B' @4 b15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
5 |. i: ~4 E* s" z  qB.生成myclass的实例并调用mymethod方法
6 h, m  {: Z% t$ `; l$ ~/ a% }C.产生一个语法错误3 P/ j* ~! A9 ?+ C% t" m( X5 `
D.默认myclass类最后被创建出的实例并调用mymethod()4 L" j; U1 q4 [
E.调用名为myclass::mymethod()的函数9 m7 a/ U5 j( u2 I, @
) O4 U! t- M" z, r
" r6 |8 E: o* s' \! @- S" P9 j
16.PHP中有静态类变量吗?
6 U1 N1 Y& t! ]& A/ M2 G& `7 G8 k9 D& Q, H# c. @6 C
A.有
0 `% B, R, h1 D5 dB.没有/ Q# v" O: c# }( D  y5 ], S: M
4 y5 w$ D3 d% P1 z
8 G: X2 Y1 {: g* w  d
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; r/ ]- \( A2 M( M# [' M
B.2
& g& `# \" L" {+ y& V/ [C.一个错误,因为没有定义a::$myvar0 p' \7 P8 J7 J2 B
D.一个警告,因为没有定义a::$myvar6 K6 I5 [3 F1 Y% W* u
E.什么都没有% w7 v- I4 I+ Y( O2 G# ?6 j, l# {

5 @+ m. x* X; y" S8 T$ t7 t# K$ W# x4 w$ ]/ L: o! ^
18.如何即时加载一个类?
/ r0 a- l# ^- ~) g
7 T: u& K2 m# j! X( Y6 u& jA.使用__autoload魔术函数/ Y, T" O9 ?' x0 N
B.把它们定义为forward类# g2 r# w+ {8 A' j+ \
C.实现一个特殊的错误处理手段
- o' v# a5 `4 _2 M4 d. f* mD.不可能5 P. \1 F  `  ~. l' f& E/ Q
E.用有条件限制的include来包含它们
0 b$ @& Y0 t& w. \, G6 r  v0 x- v/ [5 D/ H

/ q$ s, G" l0 V2 X19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?  C" D9 t+ K0 @( T1 z! [; z

1 G5 _0 y5 B7 ]- r8 N  G    答案:__________
+ {+ k: j9 S9 X$ `& R4 g
/ h0 y; h' y9 [0 {/ b7 s/ r
( Q( ?' O1 O6 r$ e& h4 J; @, q" D4 ~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 called7 _( v. ?* k3 m3 `
B.一个错误
+ o7 p& Y8 h0 T8 NC.一个警告
) I: S( P0 K1 oD.什么都没有3 s' Q) a2 J) m- K

3 q3 d- B; }! ]  I9 d; i  o: h4 Z" J* t$ q# M- j) R  ~
% B6 O3 _3 Q, m* b8 A9 j
答案速查
# ~- P) n8 o5 s9 ~0 F- d0 Z1.类# }2 G/ V0 J1 v) z6 D4 \4 X
2.BCD
: x. b6 w1 J% S2 X3 B3 B6 G3.C6 ^/ V$ ?  J+ D
4.C# }5 B, A- b8 t" @! B8 C9 C( A- K
5.A/ t5 B, G- ]# x" A9 T
6.C. ?2 O" r% @: b2 Z
7.C
, ^3 }) A! H/ K9 F2 L. ~8.C  L8 A3 E3 X0 T, z3 b1 ?5 u
9.D
+ h, u+ |# O) x% T+ f7 Q10.B9 f( {$ T6 _4 f0 p+ n+ p; _
11.D
; \& U/ `2 E  @( w& s; S& S' @* m3 L12.B
; X; [, v/ A# f- d  B2 H13.A; s) p9 `! T5 [0 Z5 e
14.D/ Z& K+ h& s, E+ t2 u7 t7 `
15.A
2 u! N: b$ U+ ~; ^9 e: ]; J8 |16.B0 i6 ]7 C& r3 P! ~, }
17.A
, T! q9 Z7 b; ~4 v18.D8 ?: G  Y5 A$ ~. a* L, N
19.设计模式
+ f' X0 E0 l0 r- H8 F20.D; b9 t" ]7 y( v' R6 U0 z8 Z' V
, s* P  L* |5 z# P; r$ ]' h: a

& k# |7 R0 {! L' Z, q6 A) _2 p- ]  A# J# h3 w
答案详解5 G; ~! Y7 F+ n; Z, d
& o# s; R% z( F: U0 R% E
1.类是对象的蓝图(对象是类的实例)。
- u8 q+ K1 r+ R  @1 H7 Q: T  J$ a. O2 m2 Z0 |
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。1 h1 U: E8 }( H/ V8 z+ v2 W

: B# N8 o- @! c3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。0 f# G1 d9 A5 ~, D4 @; G
4 F2 ~0 b+ g1 z* Q8 A
4.单件模式可以限制一个类被实例化的次数。( P+ C7 h9 Z9 K2 w
$ R% h9 d5 k7 L3 ~8 v# U
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。# F# r! V5 R# L( y0 x' W
3 d2 G7 Z, H# U/ y, @3 r3 c6 V
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。/ T0 F, a# p8 b( Q
4 t. H1 A3 k9 N2 w
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
6 k' `$ C+ @% ?* ]# _2 F  e7 S/ `2 ]: N, P) i
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
; M+ [  v6 Q/ j+ J1 H+ g/ x  X/ }" q. M1 W# ]* G4 F
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。# b# ~  _' y* A2 Z7 w4 s8 t

0 b, B1 N( \$ b) k10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。+ R% {* A! C* Y) M

8 q. C* z3 a1 I% C6 t11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
" @: N5 p1 X& G1 W$ W& z3 V& @( Y! i$ d+ f6 O, s( I
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
6 q2 M, `* W0 q3 Y4 ~! L: t4 u1 k+ ]. }; K. t# T8 ?2 d
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
# |2 x) `# U, t9 @( Y( o( Y4 q: y5 f$ k% G: \
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
' D3 }- \) d5 G" D: L* E1 X回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
8 R) |$ o- g0 P5 N3 }    function reduce_fraction(&$fraction)
* {3 I+ n8 ~2 q# D1 k答案是D。
; N. j# D6 S2 t) U
( s; M& a+ P0 P3 n# p1 V15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
; O. l$ m- t2 p+ T; Y( Q) E0 Z, [; _' p+ _  e0 o# u
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。5 T0 T2 |7 Z; {8 {

/ j1 y6 q6 D: t2 m17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
+ o; \% _: p( `0 O! H
- N9 x+ G+ t& V' O, w8 s18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。' N% N4 N9 L+ a

8 G; h* d% E) h$ }+ @! B19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
0 m7 a3 i7 J& F* B2 n$ _, I' S' |5 t/ I, H# z. }* ?( ?% V- L- B* M
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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