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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。( A3 s0 c/ H! [  k* w/ v5 \
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
; L2 o3 Q& w' k! G$ r5 G+ C; x本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。: ?% G+ z0 B# N
1 U# g) ?. U3 Q5 t0 C" L5 }+ k
问题1 }6 E& i- }/ l% D# l# i! E, a& `

1 b: D$ B! L. [# A% K2 A& s1.对象的蓝图是什么?0 i1 i& k: |& w: ~* _, j% _

- T" \1 E; k8 N' [+ _( v3 \4 c3 p答案:____________9 R9 {2 x$ i9 W& T3 j* Y5 h* [

3 D; c: Y4 m' U+ x  ?5 |: M  V# V9 K4 _
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
& i3 K, |( e" S0 AB.b
  u( f6 B" D: E# z* nC.a; ~; @& ^1 H/ i5 \# I
D.d
6 L: K( f/ F- C6 r. ~- |E.e
* \+ y4 p5 E5 i- p) V! e4 @' l3 |: ]

9 F$ ?( C6 u) K# f, ]) m0 C3.如何让类中的某些方法无法在类的外部被访问?% Y8 l- P% I, J, }/ d# \
6 T, x1 m& [% x% Y7 h- j, `
A.把类声明为private2 d2 `4 L: |4 G4 {: ]  d# l) Y
B.把方法声明为private0 Y5 N" O! T; H9 {+ Z/ H! c8 K/ f
C.无法实现, U( V3 Z2 M9 J3 w2 p
D.编写合适的重载方法(overloading method)
; u- x8 [0 n6 D/ e0 R1 G% {3 R
  |4 C2 W. `. q
' H( S" x) p0 O6 V4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
5 n8 ~% _, R+ O9 g* f) M% C. `/ f' ^
A.MVC模式. N6 S4 c- v) J: Z4 g5 q
B.抽象工厂模式(Abstract factory)! W( a* N  d- x( T+ \5 G  K4 \
C.单件模式(Singleton)
9 E0 [& Z5 ?' BD.代理模式(Proxy)
( h$ t! s4 m1 V& bE.状态模式(State)
0 u) ^5 C5 j9 ~
! J, G! W2 f( C$ v, _: @
( b; ]4 }: Z  d5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?  V% e* c' p0 ]  p0 J+ R

+ q- R. a: T! M. OA.1个
/ Y' y/ U1 A, pB.2个
( a7 x; s' w9 I* HC.取决于系统资源9 B4 L- C/ b! Y. f) G3 D
D.3个: K/ @) L+ E  D* ~" F
E.想要几个有几个
8 }. R# |& j; W& b1 ?$ }) K* w/ w$ c7 }* s7 N1 y

1 V" K3 j+ B# e8 C& x* }# e( J2 i6.以下脚本近似的表示了一种在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.多重继承* M) r7 H$ H  S& r) b) Q
B.接口2 I' u% w. a. p% `
C.抽象方法
  i0 F7 p* p& d2 \. C, C9 VD.Private方法
" d% [3 q- O& f5 E7 VE.函数重载(function overloading)! C0 ~  r2 ~5 A
* X5 J3 |6 V, w! f6 }( P1 V
; G- A0 {3 B( W. q, n* [
7.假设定义了一个testclass类,它的构造函数的函数名是什么?/ g, n; g6 l* `3 E3 I9 z5 K. N; b

# Q3 i1 Q8 Q( Z- m) W$ tA.__construct
  @$ Q% B" S8 K" QB.initialize2 ?2 R6 c0 L3 O' u3 n" w( b$ _( `
C.testclass* \+ v0 l1 |5 S' L" @
D.__testclass6 [: a, g4 N( a3 _; V* Z
E.只有PHP5才支持构造函数2 b0 e! Y1 `  c

! h% P! ]* M! d: M- V
* S% y/ I! V3 l1 n/ F& y8.一个类如何覆盖默认的序列化机制?
& \' B0 y4 Z' J2 _6 U1 R/ r& ~6 k: g+ f2 s. R6 _% A  h
A.使用__shutdown和__startup方法
0 e+ z5 ?( V& Z" X. c* j% T: NB.调用register_shutdown_function()函数4 I2 Q9 w7 u+ }. Q% q
C.使用__sleep()和__wakeup()方法
3 l7 {# O2 d0 A! [$ aD.无法覆盖默认序列化机制, Q! @9 Q( j9 ?% B- ?
E.使用ob_start()将类放入输出缓冲中, n# e( c& K2 `/ L9 z7 a

! P5 H% j1 K  Z- g
! m+ Y* d' J* i3 ~9.以下哪些面向对象的概念无法在PHP4中实现?
- X& A7 Z, V2 S4 F% M2 {8 T. U5 x
@抽象类
: k4 x% A( `, L1 }$ O@Final类
/ {4 B# d3 K- q1 z+ \. k8 v@Public、private、protected(PPP)方法
1 l" A0 t$ j( t2 M! j5 G0 f( }@接口
( ~! X( V5 D. E( T' t- i/ T
0 g/ J4 R, h4 t8 Z1 e$ L! RA.抽象类$ Q/ B" M1 @# V) }' ~
B.PPP方法
6 P' k$ k$ `/ ~1 i( y+ G3 y; o2 `C.PPP方法和接口
: C) f! z4 |/ |0 U( \8 t2 |$ AD.以上所有都不可用/ H; Q% E& O$ U$ l8 Z) u  t  W6 X
E.以上所有都可用
8 \) V# k, m2 N; b  ~7 r3 s& V) f; V: j& P% H% ^/ k

6 ]6 e/ d3 J& i7 {10.如何在类的内部调用mymethod方法?
% b1 g- B% x# w6 k6 F3 H$ _
, P( S/ h2 r2 h, U: e  J! oA.$self=>mymethod();, ?- f7 m- v. c6 c: e" c9 F
B.$this->mymethod();# u. c# {. T- N( b, b
C.$current->mymethod();7 s4 w' Q  ^( {) K9 x7 k
D.$this::mymethod()
7 e$ {- b# |* T: cE.以上都不对
* _4 g5 H' _0 S+ P9 J/ x
) Z, {& C" g, E4 C% g2 u% G$ n% j5 m( D. T$ M& k/ c( F5 ~8 n
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.105 C8 c+ C+ m" b( O
B.Null
* o( c' F' B. k( x3 pC.Empty" P6 \- @; E  t1 h$ F4 B3 t
D.什么都没有
$ V" I# e0 S1 |' H  }  ^' z1 BE.一个错误
4 g* \0 u; A; R1 s2 ?' W+ m
8 r1 l% ^% C  Z5 m+ K$ ~! a" o% {! N2 y& f* l$ `6 O* o2 p
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' l) k2 D$ A% v6 M5 c: z1 U
B.5
0 G8 G7 |6 P2 BC.2
  _4 D7 B; B' _4 ~1 Z4 K+ n6 nD.Null2 o% k6 x" V6 t4 m
E.什么都没有
7 c" Q1 \' P' |9 R: O1 F5 N* y% b' i" j% M9 C, k1 q) R* n2 \

$ N& z2 j" Z3 i* W3 B: g6 \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
+ P+ D2 E! y" G( \B.10
, H. n" J( d8 _, }* f- O6 f+ P7 GC.什么都没有9 \2 o( p% e7 P- S+ V
D.构造函数将报错: }. N; I1 H% v7 B2 ?7 _8 \
E.510
6 n4 k( c% q* M6 h4 D: h
# b: |  _) l4 I- c: n. A, D0 @$ {5 k3 V
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函数必须返回一个值
# h7 ?  {$ t- k8 ]$ lB.reduce_fraction函数必须接受一个整型值; v& O( ?: ^  Y# a- c
C.gcd函数有问题: }& ]: u  l: L; d9 O
D.必须通过引用的方式传递$eight_tenths对象: L1 ]& m$ N. J/ F& u
E.对象的实例不能传递给方法以外的其他结构。
! ?$ l- U/ g2 ]& ~( P- @9 t
  v( W' E3 D' o$ P% [( R+ ?  c2 J* d- ]. Z  ~" L! f+ w3 A
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法, k' C( q0 l; F. n4 a
B.生成myclass的实例并调用mymethod方法
1 |8 O. k4 g+ |7 v7 M+ ~' A# yC.产生一个语法错误8 H! a( w  X  M5 @+ s" h  z
D.默认myclass类最后被创建出的实例并调用mymethod()6 ]3 Y( \$ T, x. [; a
E.调用名为myclass::mymethod()的函数
2 C' r; Y8 D( \+ n/ a
' b$ ?  ~3 F9 v% f6 T4 ]  c
9 F- K2 L' e1 A4 ~& a7 z16.PHP中有静态类变量吗?
8 Z' Z* y8 @+ t. M# S" ]' Q7 Z3 E' o& M! z  W8 R) b
A.有/ v: R/ z! j/ E' M
B.没有
( E4 ?2 R( ~9 b( A) w  R) Y3 r" W8 j7 {5 }0 i* a5 m
2 t5 a( F& O' r( \
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.12 \; P9 v7 o. K- a; ^
B.24 [- i4 q- B  V1 d2 u4 Y/ ~
C.一个错误,因为没有定义a::$myvar6 ~1 l5 Q: ~) s  v8 R
D.一个警告,因为没有定义a::$myvar% _5 {7 Q- q: r# |1 Y( a/ _3 B
E.什么都没有
$ m5 x* z! D5 I" _# X# i
! c6 \  k9 z* s% |! `: Q+ M$ B& K/ q6 ?/ S6 J' q) b
18.如何即时加载一个类?
- t) |3 S+ }0 j2 \
/ j7 a1 l  L$ b% [A.使用__autoload魔术函数
6 z' B) E& h3 c. L/ d; f& T% {B.把它们定义为forward类
/ D, G1 ]' o/ [" K6 gC.实现一个特殊的错误处理手段, g4 Z2 \' G) r) A1 _
D.不可能
- t# O, ?# m3 B2 _E.用有条件限制的include来包含它们. ^" ]6 j2 M# `7 j: a

$ j% b  E. F+ d' L9 v* j2 R7 \' o7 j9 l) b+ X* }
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
7 ^6 t: P) v& b2 M4 u5 O* w0 w2 P. V/ o0 g! j* O. S
    答案:__________& Y! u% C+ k/ k7 ~+ g( g0 j' [
  H; g* ^! u% m! [& [# e

5 v( c, P; c# F) Q20.以下脚本输出什么?

  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 called2 s% g4 n. g) s! @0 b5 b$ z
B.一个错误
$ O" e9 o7 b1 B* CC.一个警告
: |# `+ C+ G6 J; N  G3 `D.什么都没有
* z9 E3 I& Z( P# Q) w, e; E/ V/ V/ z" x& l( d
8 U# y% {! B& B) Z$ w
& q, s2 G- `' f- B) i
答案速查4 k6 u8 ^$ Q$ o! K+ H7 G5 F$ Y
1.类  u9 M6 I. o5 N# |# ]. X/ {
2.BCD0 d' Y8 l6 Y% \
3.C
' Z% G2 x% s3 J4.C
9 k$ I" a0 T, `% X! H5.A
' Q4 y# W4 r1 g8 ?0 o4 }6 B6.C
. \3 z; f" p- Z' d7.C
* J) d% |6 j( t! B; Q8.C
$ u4 g" W6 t5 s5 S7 \9.D
) ]+ b& T2 T) x2 N10.B
0 a' D. J0 f9 n6 Q" m! g0 v/ t, e- E11.D
- |; E& C5 ]) g' K, s" d  v1 S! k12.B4 h3 y# n6 q9 H
13.A9 L* j" f2 X# m+ Q1 ~6 Z4 I
14.D- Y' Q% D7 v7 Z! M" W& n( \. k" f" h
15.A
# }( I$ T' R7 x$ H+ M16.B/ w  _! h0 u; I2 h- X$ o
17.A
4 @% L2 }/ g0 k' i; ~0 A18.D' }, D7 h( f4 N0 |  ?2 ?
19.设计模式
8 q1 Z8 O1 w# w7 E20.D) B$ X& E1 m0 g7 o6 ?- `9 d
3 i3 r( O/ S: \" _, X; ^$ j4 o: i

# r7 ?5 u+ ^9 |" U0 L
+ H, o% y" o. @( R/ y答案详解
9 A  @+ z$ ]' K9 J: f2 S5 R7 F$ y- S! N( q1 X
1.类是对象的蓝图(对象是类的实例)。
- r' x' E0 v- a! A0 J/ I* Y" }' f' V9 G" j- G4 W9 J. U
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。3 a4 k- H+ u0 q& J; j
$ Q) [& |5 z5 o' l
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。7 x+ j" Y0 g0 K& O* P
4 h0 J$ k; \& `$ v! i
4.单件模式可以限制一个类被实例化的次数。
. w4 @5 u2 A" m4 {) |. e; e% d* E- g
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。+ M" I+ t$ H, [& K% Q

5 G2 @) }8 D- \: n" X: H6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。) K& E. H7 T: B* N% F# H
) P' R+ v0 \" I) Y% M
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。+ O& @5 H# c1 e- ~/ l
. ]/ B& _  k+ c  C& \9 V: {
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
; k2 b2 B0 k5 \6 d0 A0 T
' `: a1 d; q: Z; R6 y4 a- f9.PHP4中没有题目选项里所列的任何一个概念。答案是D。/ n! H7 u# Q9 L
- A4 R6 v# a" f5 v" U" J
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。, a: G5 I! Q% c6 x7 m
# ?, R' m2 ?. f1 [9 v5 p  m
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
: |6 ^  K' o9 g5 E; y. f6 ?4 Q" Q6 x( C6 Y3 Q7 X6 I
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。3 z+ Z0 d9 D- }: b$ h: U9 A' }
! k) Z# Z& a2 ?$ s  T
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
+ x1 m9 I3 C- {' }+ e# d5 r" g8 h% \) d  v# u" Z1 i
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
+ n8 C' [, I4 s5 Q# }: h- _回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
" |6 w8 |' U8 I+ w' ^. R7 \6 U    function reduce_fraction(&$fraction)
0 R- l3 B3 k" C) e! j, |2 b6 B; h/ y答案是D。
9 a& u9 q' {6 ^' U
- p$ K* t& ]+ ]9 z, R15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
' U0 D& G3 o8 ]- W0 J  D4 z+ L, N6 @9 o% Y3 y
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。0 G+ J7 Q& v+ I  K* m
( |, K. X, G0 j& n1 D' q
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。$ d8 J' m, G" A+ x" u
$ T; T" A* e7 L! \
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。: u& f. g( {  w1 L8 |/ c

: O. }3 N* i+ K6 H9 p) k19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
7 f9 f% Z4 H8 l
! N' t3 t# d; B. \0 s7 j20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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