返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
( A/ w! z& {4 K+ ]( {" z- lPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。( a7 K+ t8 k2 ?% Q# d6 J
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。, N' m, S6 h6 T

9 b8 k2 v; N! R  e$ [. }1 ^; I问题
; h" V! K* \  I) W. j8 b2 j# A. e/ l. e4 i* a! K* C  M+ A5 C
1.对象的蓝图是什么?0 N( x) g& t, ^5 M8 Z! H% T
! k0 y! K0 Z" p4 N- c2 a
答案:____________
- _7 A2 M$ P7 p+ H0 ~+ b. m" C# u% V4 \6 b8 f1 F* g
2 E% {1 {4 g. f- T: j  p
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, ^$ T- o9 s( C3 Y
B.b
. Y* g' j0 r# eC.a! G- {! F" X/ M; _2 ~& w
D.d! P9 N" g% B" Q8 f
E.e
4 N, k2 d" x3 v3 B' l
3 ~8 a  g& `# H# |! R- e& b
& R8 n% t6 P/ C7 n6 b3.如何让类中的某些方法无法在类的外部被访问?& m+ W4 P- n: Q) W6 _* Y, w3 G2 k0 ?9 s
) O; g2 H: I8 m: l
A.把类声明为private0 |% @" h1 ]4 g$ I9 |
B.把方法声明为private
9 t  k5 O* c: o; Q  H) i+ d& r/ b+ P2 sC.无法实现
4 X9 J6 Z. x( z  Q, I0 d- vD.编写合适的重载方法(overloading method). f3 n9 X/ c/ E! h# o$ Y, ^
) r- s4 T2 K; f! }

) p+ [5 {7 [. j) N% z0 o$ H4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
8 m; P3 s, v. P; {- l& @
0 b$ Z/ D/ y8 c/ h  dA.MVC模式* n" I+ W) Y' A; b1 @9 L6 \4 W( R) M
B.抽象工厂模式(Abstract factory)3 A% h, ^3 [  w8 w$ |' v$ m" F
C.单件模式(Singleton)
  D$ W% _8 L8 ^D.代理模式(Proxy)7 ^7 z% e  ]; O0 I" T, X- P$ }6 g
E.状态模式(State)
4 i% m- j& L( {6 N( J% Y  Y
# `3 e% `0 O, H8 C5 j8 L4 J5 h
! m2 S( E0 G0 z( k5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?( l! {6 I- b' D! {, ?% r+ x7 E9 k$ T

3 v1 Q/ d3 g# DA.1个) u% {% Z( q, c; |/ L9 g# p
B.2个
6 k/ g6 A( {3 D  ?. _' [# y7 j* wC.取决于系统资源
- y+ a0 ?/ E9 s3 M4 g5 L5 CD.3个4 t# Z8 Q$ P. o5 C! d' ?
E.想要几个有几个% A3 A( P/ Z7 v. z: B

4 l) T, N1 f7 M( J3 a' S2 o5 y  e/ w8 t6 r
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.多重继承  m) K' j6 k" O* u  n6 x
B.接口2 r! m2 \* _* A6 u- \& C
C.抽象方法
$ j2 N; {. w  J2 P* tD.Private方法0 y5 L* T( }  x, s" B
E.函数重载(function overloading)
% b. p# e" _; v$ s/ S' q
5 w; y3 u; D( y2 ^% B) R, g: ~' t$ J' _; \) Y2 }
7.假设定义了一个testclass类,它的构造函数的函数名是什么?9 q+ m4 ]& g9 [( s  n* |
& H/ ^0 i. e9 H4 `  T; s3 p) D
A.__construct
1 ~/ D* O9 `8 uB.initialize, W+ z/ Y4 m5 r2 s/ q  z0 L
C.testclass
+ t% Z: L, E& e6 vD.__testclass; O! }- t1 ?- f& O: f
E.只有PHP5才支持构造函数
. d$ I. z# @! ?1 N' m
. Q6 p$ W9 a% ]& z2 r, S' M& S# a5 |1 g. y1 o8 N. V1 Z. d" }: n
8.一个类如何覆盖默认的序列化机制?2 K$ M4 ]5 f+ z* e- J& W5 D) s: O- ^

' X* J( K$ s5 c. o( r$ A4 kA.使用__shutdown和__startup方法9 Z$ @, W/ I4 {) |+ C3 O' _
B.调用register_shutdown_function()函数
% M. H' l1 A! S- X2 [/ ]* [$ cC.使用__sleep()和__wakeup()方法
8 R6 L- [3 r% tD.无法覆盖默认序列化机制
' l) o6 j* o! \1 sE.使用ob_start()将类放入输出缓冲中
" r6 Z9 K% Z! r1 K1 {/ `7 F3 P% d1 f( T# X5 C

& L9 o( ^. k! a3 D9 r9.以下哪些面向对象的概念无法在PHP4中实现?( E( r( H0 S3 X8 Q; _0 U! k

! Z1 [( v- _6 t  c2 E! b9 b@抽象类5 j9 I0 f' F: ^1 F6 C
@Final类# L2 }! @& b. }9 Z7 G! z& |7 w
@Public、private、protected(PPP)方法
4 V0 X- b4 N4 }  a  ?" ?7 O" Q@接口. W0 `6 \& t  S: S0 g. D
5 v4 ]) e& }0 `) i' V. [
A.抽象类
5 S/ l9 ~6 d! D& P% P) X  VB.PPP方法: Z( H3 M/ Y. [4 G' j
C.PPP方法和接口
, n4 p" e1 }$ XD.以上所有都不可用' E) J1 k, S* L0 f9 @( V
E.以上所有都可用5 R3 O/ }% Q' i! i+ ?1 A& W
2 ~5 s7 ^8 ]+ P- p6 T/ Z

" y; j& P; v5 _) X- Y1 A10.如何在类的内部调用mymethod方法?
7 ~, I/ d7 ]! d/ [+ H( E2 u' t0 s
& U1 i2 n: o% k) [3 Z' ]7 MA.$self=>mymethod();" ^0 l- \! I  c! X
B.$this->mymethod();
- U1 N( s& ]% t1 _C.$current->mymethod();" [9 l$ o$ A6 F2 a7 ~" D
D.$this::mymethod(), a& `  A5 m) L, k! D% N
E.以上都不对, ]$ f3 `$ ~3 c# B( u# m

  ?$ \. C2 a7 \8 P' o4 r: ?; P, {- R  c
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+ w; b$ Z  Q2 R- a% z
B.Null
# h; a4 S, W; D# `6 IC.Empty
& G9 Y1 ~* L% iD.什么都没有  I. M) Z  s! J
E.一个错误
9 v: C3 w* Q% W, [
+ z3 S# k  g, o& D
8 E+ u# w4 C# r" I12.以下脚本输出什么?

  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% R: B3 k% q$ G* E) _
B.5
8 X4 ^% [, g( n: V1 P3 PC.2% l- ^: \$ N$ u8 I
D.Null- d  u) {( Y  v$ i+ A, Z! Q
E.什么都没有
# q( ~  E1 _. m: K4 y# a+ \. R0 Z* {  h$ Q. ~
' |* Y4 ~/ B. 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& p3 ]+ h" F; ?) n* c9 [
B.10
3 R& ^7 C" L! O5 R; O. R5 qC.什么都没有
9 q- ~0 o, m  D' L7 h  J2 x' m4 W) f2 MD.构造函数将报错
4 V1 Y* {! F( u) b3 j4 Z5 xE.5106 M0 {) m! M0 p
3 b' D, L, ~8 F  E- f
3 {7 [' s2 j: J1 b2 w
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函数必须返回一个值- E5 O# D; E9 @/ c4 C8 O6 m) D
B.reduce_fraction函数必须接受一个整型值
9 J9 [0 `+ C/ |* I9 E. I+ tC.gcd函数有问题- Y! F- o+ ^9 \
D.必须通过引用的方式传递$eight_tenths对象
' V: L* |$ W# _7 q2 R" JE.对象的实例不能传递给方法以外的其他结构。$ ]1 R( }0 s7 ?% y

* @% Y( y$ T7 F3 J2 A8 ^1 {6 c: Z- s) p6 O: e
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法4 Z" T; n5 d# \! R
B.生成myclass的实例并调用mymethod方法8 X( Q: d3 ?. a7 d) \
C.产生一个语法错误
2 o- V; I7 u+ x, E. m" L6 KD.默认myclass类最后被创建出的实例并调用mymethod()9 D1 Q( d. M5 z; X, j0 n
E.调用名为myclass::mymethod()的函数
2 Z  ^) ?  ]! c4 W2 u4 w
( ^/ E' v6 c$ t+ I0 ]
5 m. @% M% W. }% o4 S8 W4 ^16.PHP中有静态类变量吗?
; L. D4 C/ H' M) E. C9 J5 M# j4 u. Q. v) g6 |
A.有
/ O% Z* E' M8 T& A; _; f% r/ EB.没有
; ]9 e, y1 ]9 ~: x6 ~  d1 g  e: ^# V; e+ Q+ O( f8 Q
( L" I& ?1 M5 N) K% u
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.14 ^4 R* L9 P! [/ ]+ H  s. _4 q
B.2
& I8 r4 ], M: ~; s+ i/ ]C.一个错误,因为没有定义a::$myvar
4 T0 Y2 k% ], w  {( y% gD.一个警告,因为没有定义a::$myvar
, {1 H' ~+ m. F4 J3 d; z- jE.什么都没有
+ h& S  w! Q( R2 M
9 u$ q1 [/ `1 H# x+ ]- G+ i5 c
18.如何即时加载一个类?8 L: q' }. k- W2 a0 f

8 ^: ^# @  I7 v0 g$ c/ K/ wA.使用__autoload魔术函数
6 F* a. m9 P- n# kB.把它们定义为forward类
$ y. R$ c' Q2 \$ |5 eC.实现一个特殊的错误处理手段
1 E1 `9 ]3 K& O2 I3 B6 mD.不可能$ r' p! {- t! G- l
E.用有条件限制的include来包含它们; p  A! O0 h  J/ e4 a

$ D/ a  s+ s4 M7 G; q4 V! E& _; t
$ [# [% t/ B$ `3 D  E$ S19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?5 B/ F2 N$ x) r! x
6 E" ?; O, L/ C% G* t
    答案:__________( Z  A% O( k" I) W4 E2 a$ v8 e7 f  \& y
+ K2 d3 j+ d' c% p. I) `
* A" C3 }& [2 F5 Z$ Q1 o
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( L, L6 v. [; H
B.一个错误# @7 B+ _( B! o' d
C.一个警告
+ m( ], i6 i  p. G9 D2 ]2 MD.什么都没有# J1 I7 a, J8 C. B* }
1 u" e& y) H. v3 e! i

, M( z5 L: {& {: ?9 Z+ L# o- v6 S" T! y' q, P; o% B! p
答案速查" P/ C) m0 O& _( [# ^( A9 t
1.类
" M* Y8 X- G, X3 E% _& l2.BCD: P) r) Y' m$ m- U6 R
3.C
: Q* G+ B7 W: a" e$ w4.C
% y  a- \; t( u9 D5.A
& h# h2 D4 p' C9 H6.C- @5 S  D5 [3 l3 d3 \; B
7.C" R( [" Z# q. J9 {
8.C
4 R9 T4 y  F1 R- x9 h9.D
$ O# S. O4 o$ s# ]$ x10.B9 P1 e5 o4 v) h. T$ b
11.D
$ h5 s7 K- l3 b0 l12.B3 i; s  v; v* L! U  M0 t% ~: @
13.A- e1 E4 g( U% U! h  o6 S9 A, Y
14.D- W+ |6 T) s; v+ H2 M$ O- e
15.A; `# i3 ]5 ?/ Q4 O% @, j( Y2 U* v
16.B
) I6 G; a+ \. q1 ^0 A17.A! y+ R6 C; q4 J+ e
18.D6 k+ R0 C/ {; W, F6 g. n
19.设计模式
  M0 m! \- u3 j/ l20.D
6 z2 p; C- l# W2 Q& B' u) b- h) R- I2 ~8 T" ^, h

8 Q$ c6 [+ w: |, ?/ S+ @
9 |/ U9 t( O6 e  v0 F答案详解5 ]/ @' j/ E% \9 H

* B# {: A& r! q2 i1.类是对象的蓝图(对象是类的实例)。
+ n6 S* S4 R) l8 R+ y1 ]/ @* u5 o
# F3 U2 R% ^1 r$ V  c6 N2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! H. f( ^7 T, v  Z9 S3 X

: d8 o6 {% F7 n, ]) [3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。, o' B8 j$ i' o
0 X8 K( F3 @5 Y* X. W  ?
4.单件模式可以限制一个类被实例化的次数。6 r% }/ f  Y1 q7 Y4 y4 m

  D0 }& @, |* Q7 s4 Z5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。0 ^2 W3 v2 T& h5 h7 H

: {& w7 z) L7 Y( Q, p& c" k6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。; v9 ^, ]2 s& r: u5 e7 G9 v6 t
) Z- Q& X0 q+ g& h  I- \; V
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。! F8 i( ?/ ?: i& s8 Q4 U! q$ `

8 h8 c- q; d0 Q( f# P# a& G- k$ S8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。9 ]# u7 i% G9 a2 r! C' H5 O

7 c" G# s- `! A) e9.PHP4中没有题目选项里所列的任何一个概念。答案是D。( {& K# b9 J* Z! G7 z* ~& n

7 s' `  q, x7 C5 _8 G7 E/ c10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( D) b2 c2 l4 s* x. j
2 G, _0 N$ O7 O/ h$ x1 w
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。& U) }0 \- @# \+ }! G/ V5 W

( U7 ]  c0 |% j8 I# j- H12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
  v( O4 Z& I% h7 P+ |$ E# h5 A( f4 C1 O0 x. x4 O5 q$ {% V+ U: B
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
$ F) @4 d4 W6 u( Y8 g$ ?. p* m  g. L% M$ o9 b9 k1 ~
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。! o" Q  r2 |$ x6 T- d
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:7 }. z, C& F1 g# o. h1 n. U
    function reduce_fraction(&$fraction)- |! w; o5 V3 Y" t
答案是D。
& m# d9 u" A9 V/ M! Y& S& |
. ]. [6 M, y0 A15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
$ f# g" \( h* ~; D$ o
3 c6 p% \  ]$ ]/ X- O# v5 _* R* U16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
, P9 h9 L) ]$ N3 {+ Y& r! f8 J. t3 }- g! B1 N; w0 m
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。9 L0 c7 _9 k" @2 |" q$ v4 U
; s7 D/ N0 d# n# x/ J# c
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。1 x( ]4 f! G& V+ A( [

' x& G6 i. Z) p7 g$ H19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
- d$ K" s5 e6 `7 q! z3 l& p
" P7 _: E  [+ n& {* J2 E20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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