返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。7 b  s/ g% @) i* [
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
: r, Z8 C/ f) m& Y本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。) K( W, q$ X$ p% J

( H$ _0 F( @4 A问题) X. k7 C) x- u1 V1 Y
2 @+ t8 d. X2 h8 Z" n" }# ~
1.对象的蓝图是什么?
0 \: n" |; Y' L
8 l. C  h$ A$ Q: U; U* Y/ w0 X答案:____________! P8 C" ^/ V* |. s! V0 z# i
) _  H1 V& G. Z# `! ?. i* J! p
: O' s- M) o$ C5 s5 K8 i
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
* ?5 V$ l( F# g* [+ e! BB.b; `/ H+ d' |7 y5 P5 }4 v
C.a, r" c: q7 V; y0 z5 N  T/ e
D.d
0 O. i, T* C" W2 r8 CE.e
0 {, e( o( I4 t
5 m2 a8 J. s) X2 _" x
9 z8 I# o6 A. d3.如何让类中的某些方法无法在类的外部被访问?; \" ]) ?7 V/ H' W% f
5 N- K' ~2 j) P# e( D4 Z( E  L/ z& o: I" Z
A.把类声明为private
$ W& U, b( u  }. K+ @4 P$ K& O9 }, ]B.把方法声明为private
* Y6 o; P+ F+ D2 {0 D. q0 I6 uC.无法实现
! [0 J( n# R, }" dD.编写合适的重载方法(overloading method)
  ^) z7 P  c0 i$ O* t( o5 E8 O6 @! K# P5 M

% k$ f. f. {1 R! b. y7 k  {4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 F4 J+ O! n/ o0 A" s& K% u! F3 ?
( n/ {' C  c% U( p8 b
A.MVC模式) i/ A  P3 _8 {/ X
B.抽象工厂模式(Abstract factory)
+ E5 N  l5 I# d8 CC.单件模式(Singleton)
, a. v  E; Z) F* C1 Q( ?- s; N5 R+ rD.代理模式(Proxy)8 e( m7 n- x' U4 ?2 Q3 D
E.状态模式(State)9 j! o& O5 Z8 k1 ~4 \; v

. R2 Y* B, R/ A0 ^, t  T& @5 q  x/ h( `' _' Q- W+ p
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
7 B$ Z7 z% X& G9 S( p; L5 P! R: G5 a) x) p
A.1个' J8 t7 B+ Q' m9 R
B.2个
0 i1 ^. E2 j6 `, W( \4 ^& IC.取决于系统资源, t; Z- E. |/ y+ W$ E
D.3个
8 O9 a0 f9 ?7 q) y+ x4 K# hE.想要几个有几个
3 [! ?8 b+ q8 t. e5 [2 n" e# i: [5 p- P
1 c9 ^* |2 E% c2 Z/ L
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.多重继承2 }/ E2 V( u/ Q$ l) d7 Y, h
B.接口
5 V0 |% J! b9 j; i' ~0 ~/ A3 OC.抽象方法
0 K0 e# P! H. X: P- B0 m5 Q# ED.Private方法
2 T' ]5 s0 K* l. r( g; eE.函数重载(function overloading)! K& ~, U  P) @; f  E% E9 V% N+ ]0 ]
0 d) _8 G; ?5 b& V

' A  l5 r- i  ^6 R+ d6 K& k7.假设定义了一个testclass类,它的构造函数的函数名是什么?
! x: Z9 y) `- k: R1 G4 G6 n
4 y. w6 n/ U/ R3 `$ P4 o& GA.__construct
* [+ x* n0 L0 O& J( p1 XB.initialize
: }( L* ]; p6 J+ g, ^! ZC.testclass
1 Q+ K) w! \* s7 n; CD.__testclass
0 x: x2 }( O1 ?: L" X9 \- B$ VE.只有PHP5才支持构造函数
6 B$ A& {$ |; m$ i1 x8 {" Z% \5 m' W0 Y/ m5 L

7 ?; l% @2 l; `/ H0 j+ f8.一个类如何覆盖默认的序列化机制?
1 Q( U- C7 F1 I  S3 I3 K' R1 R/ C: y8 g4 j1 \
A.使用__shutdown和__startup方法0 y( e9 E$ S! V4 G# u) G! \! p
B.调用register_shutdown_function()函数7 {; m, R: s& V7 V
C.使用__sleep()和__wakeup()方法
: z, Z- K9 ^$ q1 S4 z1 F! B+ ]D.无法覆盖默认序列化机制: ~- O. i) b4 t/ J5 J
E.使用ob_start()将类放入输出缓冲中% c$ H4 A7 p; z+ t. O2 I

3 ~0 }5 H, w3 `5 Y5 {6 o9 o" _3 B# e: g' u$ F, s3 a4 q3 A
9.以下哪些面向对象的概念无法在PHP4中实现?
: J# q- I. Y3 l6 o+ j4 T
- f' O/ w6 o4 g( I6 f! G@抽象类
' M5 ?1 X$ `9 c# t  Q- J@Final类
" n! h: w: j, b) |( Y* A8 p@Public、private、protected(PPP)方法
) _8 {' P) T, X% M8 g6 N& R8 J@接口
: k+ j* g$ [" e$ A4 O0 i# Q& U+ F; h! J) O
A.抽象类9 w( p; @+ @8 p' v% T6 H( r! f3 T  I
B.PPP方法
  ~2 L7 O# s. q* V! }C.PPP方法和接口1 _) H" v" B# X/ \) u  a
D.以上所有都不可用7 r; h' J& p) q  [2 W& H
E.以上所有都可用: Z. n6 c. }* u! i! ~4 {
" r1 R, i) U) Q* j6 n

& P5 N, O- ~4 H' ]" F- B+ b+ n4 [+ x10.如何在类的内部调用mymethod方法?" P) C) S1 y! x, v
. z* m3 e7 B# w; B" x: H
A.$self=>mymethod();' L  z9 |! p; O( l
B.$this->mymethod();/ S: H  T# S- m
C.$current->mymethod();
# E$ ~" u9 D2 [- vD.$this::mymethod()9 q3 g% Z$ d1 {
E.以上都不对. a8 P0 X7 }2 L, ]5 w  ^1 G0 N
; [" q) g7 W' X

* @" i8 E4 ^. d8 r& K; A* G11.以下脚本输出什么?

  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. q. m: ~( t* y9 N3 N5 c  T6 _# U1 p+ D
B.Null
' L. U. w$ \; UC.Empty
1 s4 _( q& a. _3 pD.什么都没有; T0 Q/ x5 n. b8 s/ u5 `8 E& s
E.一个错误
# f3 X' y7 W/ D3 Y3 K
: |# o0 s- g% N, K. I5 |8 [) P, z" h, @( O5 q' t$ I1 N
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
% V' D7 @: ?/ G7 b0 |B.5
4 \6 k, G  r6 ^9 mC.21 q( _9 Q$ O- L) M0 x
D.Null# `& ]! I3 K. e2 h: f, X, F
E.什么都没有
1 j2 z" F: W+ Q1 L/ ]; h7 t9 m3 \3 G& {
0 e. p, ?, U& B) Z
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
7 _8 k) E, W* |- U! e( l2 K* aB.10
7 P5 g1 `6 d6 j* K: e3 PC.什么都没有* k$ e0 m/ u+ q
D.构造函数将报错6 v) J$ J1 ~6 |  y. G0 g5 j& z7 H* f
E.510, H2 ^+ ?2 L. F& J: b4 S. \
+ H& N4 s; [2 S! U, [
* u; R( Y6 A* Z' r
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函数必须返回一个值. c& b0 ~6 K* f0 r' @* m8 ~' p+ N
B.reduce_fraction函数必须接受一个整型值; T0 G( z3 g; O: W! z* {
C.gcd函数有问题  `+ Q2 W7 k2 i! Y9 J8 c5 {. @
D.必须通过引用的方式传递$eight_tenths对象: E: N$ H, w) M2 }2 n* O& x* g
E.对象的实例不能传递给方法以外的其他结构。" G+ X/ p  U1 q, c3 h5 t) K

$ _* N# x7 _5 N6 }  x4 r( h
7 K+ c; I% {* e6 \2 l15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
/ }" y. y) K; S) ]! E% s/ aB.生成myclass的实例并调用mymethod方法) `& v3 u  m' e) J6 ^' R
C.产生一个语法错误
( k9 S& N; X4 q6 F1 UD.默认myclass类最后被创建出的实例并调用mymethod()1 W: ^; S4 P" h. {# R
E.调用名为myclass::mymethod()的函数
$ \6 x1 j. v% i5 A4 u# a! m% G& o/ i6 K9 o8 @% `7 R6 O

& f0 N* N8 K% z7 f2 A  N) G' r16.PHP中有静态类变量吗?3 f4 r) |0 W0 Y/ Q+ h% m: s

9 l5 [' {5 f; ZA.有- ]4 S- \3 S0 f, E, |9 q
B.没有/ C/ `: ~# n* j! T7 M+ t3 s) m
' K! ?. B/ p. E& h
! o' O* K7 w) i. z. ^) C
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  w# k9 y4 m1 V% l* F6 q2 Z; |' w; ~
B.2
# Q/ a3 I+ A0 l% n- \4 FC.一个错误,因为没有定义a::$myvar
% V$ Y3 |6 h1 G7 v$ cD.一个警告,因为没有定义a::$myvar
4 g0 Z/ O! N8 n  o) U1 `E.什么都没有
/ `8 z" F$ U4 g% k! u
& I# U3 n. B8 E5 d1 J
5 }' u7 n% A  R% E7 M18.如何即时加载一个类?
0 H3 N; F* h7 z5 T. V- M
  L, K3 P7 v' a" `# d9 g7 [% JA.使用__autoload魔术函数5 D  m( B5 K9 u6 S3 q  O
B.把它们定义为forward类
4 P. c: c5 f/ p, B7 lC.实现一个特殊的错误处理手段: e/ d* i; p5 w4 I  L- z
D.不可能3 r) w" t( r8 A
E.用有条件限制的include来包含它们
+ l# f) |' z# l5 X6 @
- M' q6 }1 p* k. [: u' n; O, A8 ?: z$ v4 s
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
+ E7 q6 s9 z- t' U+ a, M! E+ @8 e* p2 G
    答案:__________7 G$ I' r+ n/ u0 N
" w" M9 i0 o# t& P3 R/ a) a

% X0 h6 V/ j" O! B9 [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 called0 ]) V( U5 u( s4 u
B.一个错误
* h! C5 z  Y/ J* HC.一个警告8 `# {1 e" o( t7 Z/ I
D.什么都没有
2 }2 d0 o7 I; s# \0 p3 N6 @: `0 b9 z
+ A) e1 R* m0 k5 m5 q
2 v1 m5 Z" C, @2 [6 ]  \
答案速查
5 g2 N  ?& u6 I# o& V9 f1.类5 N7 p: U7 |: h% t; f; F
2.BCD3 W" g$ d4 W+ S8 K0 ~. f3 U
3.C
% n/ U% {$ m7 `$ O) Y3 R% S4.C! U* M7 m' @% d2 Y! G& b: k% E$ @
5.A
8 e# H# p& O# @  i; K6.C
* }& M! m9 T3 U' y* A. `7.C
; H! ~% t* u5 U, S8.C* k" g/ `, x7 W! [: t& o
9.D
3 k# p0 f! @0 A  Z& A10.B
0 H, B$ O% a7 y/ T8 W6 D+ q4 d11.D! F4 ]4 C8 Y# V, i  F
12.B2 O& x5 e( ?! ^# U1 r
13.A4 X- X4 c* G3 ^! G
14.D
/ {* h' o0 ?3 e' q0 ~' g3 l15.A
( J. O# a' x- R/ U. j3 ?16.B2 j+ z' {8 v& o, n5 Z2 G- c
17.A5 M" _% Y0 l8 p: Z3 a4 N
18.D
, u: I. ~& E  w7 d$ L19.设计模式0 c0 ~( q5 H% M+ \
20.D
0 B3 @; w, }  ?$ B" C
) I2 j, x, e& ]' q1 ]
* s2 j4 Y- \8 |% r2 C. y; z- I% I/ X2 k2 [
答案详解
# m7 v7 Y; A$ a" d2 M) F/ a0 X# z+ H0 I7 d: y( ~; x4 S% g" X7 F
1.类是对象的蓝图(对象是类的实例)。+ b" `, D. m" g2 r0 U2 ]
. L' r- x( T/ n* ~8 S
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。/ r4 B* h: E% f2 f  ^1 I2 V
$ u, m4 e/ N' c9 m* W, b
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
) c6 Z' }' k" O% D( L1 h' a9 v/ Z4 F$ f
4.单件模式可以限制一个类被实例化的次数。* V. s2 T8 ~+ S, U8 K

$ Z2 x% Y/ r/ H+ _& K/ j* r5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。) K* A: v1 t/ f8 v9 _  X5 D

1 n# [' @5 d4 Z. @+ [6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
1 k; ]2 k7 U( ^  d7 h. u/ n; b0 h; x& q# u# \
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。2 n4 _; q5 D8 z/ O% Y$ B

1 p' [. j+ i4 P+ u4 q8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。* b+ U, f  i1 R: t

! w7 Q. \) a/ {; s+ K  Y9.PHP4中没有题目选项里所列的任何一个概念。答案是D。! {  p& O4 \5 S+ {( z, @
, v8 C+ Y2 t. V. p. L# o
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
/ k. v9 g& J7 Y. T+ G
: \* B& n% c0 ?* _# j; a) Y11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。2 u' H- u/ Q9 s7 l- C5 X
& m1 I/ r6 C4 b! f' Q9 ^, ]
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
# I& q6 O- ]3 x4 n: z( C
) S; C  P3 ]' c: N& [13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
* t* {, ~/ c# X+ C% E# c  U1 R/ L) U& U' y" l
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。; p2 h" ?7 Z( p0 u- X* N
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:5 \* }$ N4 J; g' ?3 l& `- y
    function reduce_fraction(&$fraction)$ a/ T" \4 F4 k+ u* _
答案是D。6 K+ ~4 a- c: ^) E

: A/ k' c7 J2 v# h  n# R/ b15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
2 C' O  A& o6 P1 M, B  l# C+ {' ~5 X- d! S5 ?% y
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
. x& e1 ]" R& Z% x0 W8 q. e" |
9 }. [" a) ]7 ^: X, |. A* v, t' b* }17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。3 T' D1 f+ j' y2 x5 N' o% a$ B8 e
9 H4 B0 w* m7 q. @
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
8 O6 h1 j. c7 F* c; M0 u. t) T% w) b( r$ h
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
8 I" t9 g# e# b5 \' f" C  Z3 l+ T% f1 k& G$ [4 {
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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