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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。- u* r. V" e/ a% ~- T$ i4 [% h  t
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。0 [$ B4 k: i% `% h# i+ @
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
8 L# f9 g" {) C) `6 s" X# {- U" c
问题
( c8 e; \: g6 q# w4 `/ K
1 \& z+ k# ?/ W0 L1.对象的蓝图是什么?
6 `  x7 [2 @5 p0 a  A: G( z
* e" s, H6 ]7 E$ z# Q) Z8 u' c答案:____________
- }( U2 b3 y; \" M, _+ M" i; Z$ J9 L( g. [

2 f# x( f! [* \$ q' h* }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
' ]7 x# G& R: t0 Z: L8 y5 V1 O0 \B.b
  N+ ]. K. S! k1 T) LC.a4 y) n4 i3 o/ L4 x8 [- ^! d
D.d/ m" ~# i5 l4 X+ i! I9 i# k
E.e
  h; O& Q, i9 L$ l  ?3 `* e& w# q5 |* [5 ]+ y
" o5 h( r+ B' Q  x. A, C
3.如何让类中的某些方法无法在类的外部被访问?2 [5 D$ j) L$ d5 g. R
* B1 A' c: R2 ]
A.把类声明为private
: G# q7 L; h6 W( KB.把方法声明为private$ o& U9 L5 ~# M+ E- c- I& A' I4 w
C.无法实现% U/ y5 w6 E' Z1 i
D.编写合适的重载方法(overloading method)
: l% ?1 Z# o' u. h0 H# B8 Y" N, x/ ~' g: k. c0 ~1 q1 g+ E  y  D

; {% R; I1 k: a  g2 f+ i* U4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
4 Z( N/ ?  D4 E& }  `1 s0 i5 u. D3 k/ I( I: f" U1 i
A.MVC模式" w7 T& o' r  v8 _' @
B.抽象工厂模式(Abstract factory)
' k( ~7 E* o8 o9 m' hC.单件模式(Singleton)
$ X* n8 E( P+ x) g  n. o$ GD.代理模式(Proxy)* [/ Z# }# P1 O: Z, a. @
E.状态模式(State)
" _) s, \4 n+ U) C3 m- \" U% i) M9 v4 x
0 I: i# Y5 s! Y+ ?
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?/ U+ C- \) N. k+ P3 X

1 E9 {( ~2 N, e- r( E  aA.1个
+ `9 E1 ~6 C% UB.2个
7 b' `, I# h, e# r, g' C- TC.取决于系统资源) [) w& G# l! ]  K: |
D.3个
2 m1 p$ ~* Y1 G! ~E.想要几个有几个
, {8 J4 J1 K% I% ~' t  l' ?9 i# g6 f
; c1 H# d0 U) s" T7 o1 c
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.多重继承9 I: `' m, C5 v
B.接口1 a: O3 H& l9 y2 O; u
C.抽象方法& d5 P9 Z' Y* g& @
D.Private方法
* Z) x8 U0 a1 q0 I% h& z) |$ g; F. T/ hE.函数重载(function overloading)
! q& \- T, d. V  g6 _2 N  A3 _  A+ M" B4 v, y9 o& U5 I
: j3 Q8 X/ m  A4 x: Y' B5 d# N# I
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
' t$ X% `: E! B- i4 u  b. j8 n& w5 |4 L) [
A.__construct
& X2 e. e4 F" ?/ dB.initialize7 s- b  O0 k# H. `
C.testclass: U! m5 f+ {7 p2 {/ G
D.__testclass' u1 J' ^; U! t! s: L' {
E.只有PHP5才支持构造函数
: A/ R" M' B" i1 a$ s8 y! F% y* a. }# D7 j) ?

5 L" v( t' S4 }7 t$ G8.一个类如何覆盖默认的序列化机制?" O0 k' K1 k+ l: E

: h* v: E' m  E$ L' H  D  V! sA.使用__shutdown和__startup方法- c2 S7 g% }: ?4 E2 A+ M5 ]3 Q
B.调用register_shutdown_function()函数" D9 Y! H" g1 Z0 i( I5 {3 J& [) N
C.使用__sleep()和__wakeup()方法
2 E# B3 r. @7 X  C  `0 qD.无法覆盖默认序列化机制0 F9 j0 b$ P$ R" z' p7 Z  A6 r
E.使用ob_start()将类放入输出缓冲中; ~8 b3 m! B/ z, ]
* L! ?. U% Q' t4 M3 F2 {
5 m- u$ D8 z; A* r. z3 A. ]- j
9.以下哪些面向对象的概念无法在PHP4中实现?' N. h: d  W- A
! }0 E( `) Z2 G# R( V5 [9 r2 p
@抽象类
" k/ `! R3 l9 J@Final类
+ c% F5 S# W% @" ]; k- r@Public、private、protected(PPP)方法
( v7 C+ V9 h+ n% ~@接口
( |/ R3 }/ ]7 E# k2 Z5 {# p0 F+ @0 W4 d+ {! F, u
A.抽象类
( v0 r' q2 W9 j  y3 WB.PPP方法
/ D  E2 ~9 @) f& E' nC.PPP方法和接口* }: w5 O+ C8 b
D.以上所有都不可用
& x5 c1 \' ~1 {* k; b& W- B! c8 @E.以上所有都可用, e  {' @8 }7 X3 s( f

  m# v0 J) j) r2 D* W3 f' s, Y0 E8 w2 s2 ~' w' y
10.如何在类的内部调用mymethod方法?3 ~6 l$ h) F/ Z: a( I; G
& J* ~0 J1 h, l, t. c4 ?
A.$self=>mymethod();# Q% R( X9 X7 N3 w, C
B.$this->mymethod();
( H  O& Q: `& i0 U, w$ \; |C.$current->mymethod();$ V. G& t, @0 }7 k- A0 c
D.$this::mymethod()+ o3 m$ ~* D4 s+ N
E.以上都不对
- E" T, T. j8 z, z- T
, y+ @- W9 o& q- q# h& p
( ~- B: ^+ F: V1 V% _9 k- L11.以下脚本输出什么?

  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" d1 T* `4 Y& r
B.Null, N. {: l. i, H' g; y
C.Empty* Z$ |  V. [3 @* S4 }; y0 J2 L
D.什么都没有
( q& K0 a% W4 a  D5 C0 e- ^E.一个错误
- U0 h( j  F: B5 }
; {+ J! x! f& G* l
) K$ n8 a2 P& T1 z; q0 e6 e12.以下脚本输出什么?

  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
; J2 Y, @6 f3 q% F# n5 m* k9 ]B.5
. K0 V+ a* F+ S! _( r% bC.2
" o+ x: j, s! J( r% yD.Null
' W6 L2 q/ D0 \0 z- q5 t0 a2 YE.什么都没有
% P2 @  r: g) t( y. Y5 T4 w8 I- M; Q' j/ C- f# y, B6 `
6 c& ~' s" t7 R  F) ^& ~5 ?
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.52 x& j, Z0 ?) w+ j- [$ X
B.10* E2 ], r5 E8 j5 b* R6 l. K! E
C.什么都没有
8 U0 q9 I9 \1 e% g  X* WD.构造函数将报错
# m3 @& U0 D- @7 {E.510
# E1 S3 Y3 a0 x& b/ @! p$ Y& v0 p- |1 v7 A; C

2 M9 Q, ^. u5 K14.考虑如下一段代码,执行时,$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函数必须返回一个值  n: ]5 k4 E9 m; J0 m
B.reduce_fraction函数必须接受一个整型值
! `% p2 R$ J% h. q" k( p/ YC.gcd函数有问题) W- E& Z( w; q* }1 `/ g
D.必须通过引用的方式传递$eight_tenths对象- A$ {- C2 A4 w$ z/ R' c
E.对象的实例不能传递给方法以外的其他结构。
$ h" T5 n# p/ P, w% y8 {* j6 O' _. p9 V/ e/ ?% j3 B3 Z
9 y6 Q. @+ j4 p9 C# z, j* [2 G& U
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
; z" N6 v$ Y; f) lB.生成myclass的实例并调用mymethod方法' X, I' B+ d6 m2 o
C.产生一个语法错误
1 a- j  @. S  v) nD.默认myclass类最后被创建出的实例并调用mymethod()
7 e+ w) c  E+ D: ?) `E.调用名为myclass::mymethod()的函数+ [5 p; d' X2 q& B; m
9 ~3 p1 y1 P6 I

9 x' ~- R& ?- w/ E16.PHP中有静态类变量吗?/ r4 Q  s0 T/ ~- S  \( x4 E
) j5 _5 i+ t# W, z7 B  G
A.有
( b2 A3 }: j0 }. n' x6 s0 p1 lB.没有& A0 M6 U. s( @1 C, y# x1 a
8 k+ _! f  B% G
# e# i8 H' s) E: S" Q. U& s; V
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
) l/ i8 E  P; E# o4 q$ s9 xB.2
- _) e2 j( U7 |. W, RC.一个错误,因为没有定义a::$myvar0 w, O1 x( [3 g- F9 m
D.一个警告,因为没有定义a::$myvar
! S/ J4 u! }9 q" W+ J) r1 {1 |' jE.什么都没有$ d6 e5 D3 P0 R+ j9 e
3 y% u0 x, X2 g. x( ^

4 N$ l* p. [$ ?+ n# H' O+ Q18.如何即时加载一个类?
1 l  t- ~- a' M. ]: @4 n0 Y. E2 T  N3 ~1 k( z8 f
A.使用__autoload魔术函数
+ c+ f! h/ r) H7 s, zB.把它们定义为forward类
4 y- l1 p: n4 _/ M0 |C.实现一个特殊的错误处理手段
2 J7 l% D1 x5 FD.不可能+ p. |* N: K, F- A. f7 p
E.用有条件限制的include来包含它们
7 M( R! _0 o" z, B, G5 s
6 V; O7 c# J+ ~% M* k
3 `! u% ^9 l6 y. k19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
7 l# N( H* |& T1 S6 O1 B" ~4 b5 A8 O  u; ~/ A3 f4 S
    答案:__________
) N; y) z- G* Z3 x" b) k0 h# n" U4 O: q. f  C- d, x* W
' D* [3 M" o4 l8 R2 n1 l
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
& Y7 z4 O9 q! d, f$ r6 P& W9 P+ bB.一个错误
& u+ r) |- N4 F' X! g8 Y- ~' `C.一个警告: S, L* e7 \0 a
D.什么都没有
$ V* i$ e, ]8 z& H8 b" F% S( T, P
# P& U; t/ a  O5 D2 A& M% V0 g3 n& x" u3 _, V

3 y$ H* U8 V! d% n, p0 b答案速查" H$ Z, A1 V6 m+ }( w7 g
1.类. d1 Y3 Y4 B4 i4 ]; G# B
2.BCD: e7 o" x5 s% |; B, \
3.C
6 i' \: u, ^* r2 v) h5 \' U4.C, K$ }$ u% ~+ M4 ~) r( r
5.A5 ]* J# H' T4 |$ ^# n
6.C
; |. e  O; S  @* n. `" r/ B7.C
% k  `9 E: R) ~; x* b4 O+ G8.C
# h; l' T: V7 I* }6 B& n9.D
, {2 x, g; W2 I10.B/ [6 ?) z& M: o/ F1 g# Z+ Q* @" a
11.D
! K; P! e" k' d6 F% k( T12.B
6 x& B- a6 g. i* k& m) {. G13.A
% |" X- M; q& t' i: o( c14.D
6 n# B) ^% k6 r: }" b15.A3 \; ~( l$ V; f2 i' P
16.B( V8 \5 G+ a7 _) {' n! Y
17.A
/ g$ ~0 Z9 C" R# L$ ?! s% f3 T# ?" q  N18.D, f/ r8 B  r+ E
19.设计模式
5 L* K1 Q3 E& g5 i1 `# ]/ ]20.D/ l/ k  x, l" g5 O/ K0 z

/ r& @1 i: a6 e8 u& X2 [- `/ i4 b' L! m6 \# G/ O9 g) R
' X! ]5 ]" i5 F# D+ y, X* g. E; h
答案详解) F0 U3 L2 V% k' l

9 K) P0 O2 B3 B/ L1.类是对象的蓝图(对象是类的实例)。0 U% p0 K3 Y# H: h

0 I/ ]2 V$ U+ X7 V8 O% j% Y0 |* E2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
! r+ e/ V: ~# z. y4 H) ], G! r# q; d
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
: Z" q5 X% a1 D
/ T5 G/ T- M2 r& Y9 v4.单件模式可以限制一个类被实例化的次数。
7 o' m& g$ L# P' w# c( Y+ W2 y' z: ^- }- d. z# i( `- s+ q
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
! P& `  q3 v+ |) l4 R
7 F& U2 R# O9 _( @6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
) k% m( S- M; k# S3 ?, M9 F3 d$ C: I6 b6 ]  u* ~$ g
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
) [& V- K& P4 \/ i! }# Z/ R! H- I. v/ h2 n
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。# a9 W% R+ a5 l5 v1 Y2 m

$ n7 ]. S  a  U* {5 Z9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
) i+ S4 H/ v3 i8 a, [0 V$ a: W8 {$ K2 Q3 }# X9 F. S
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
* h% U# S  m! k# j; ?) T
& ?+ V5 ~8 y; T7 g, Y/ z11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
8 n1 h; Q5 y7 d- P8 P$ \
" q7 d1 h: V  N* ~7 s7 t" P9 S12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
& ?- P7 ~4 u# I' i% o0 R$ n7 ~# z4 t- V& U2 }, B
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。" L/ j% _$ Y; D' h( p: M3 G5 U% g

0 A, F! O+ Z) F# x14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
* }/ K/ a/ }0 C( M" Q. G3 m5 ?回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:0 F" J( S3 d# G5 p$ K
    function reduce_fraction(&$fraction)2 I5 y0 e- X6 D
答案是D。
7 V; W( d& s( P8 e0 @. t% ?% o" `: ^/ H" u# F2 n6 w$ v6 Q
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。) {- b4 Z6 S( t) u$ q

2 G$ |1 ?) L7 p5 R) Y16.没有。PHP4只允许声明静态函数变量,没有静态类变量。; P+ i2 L' ]1 C) h  A5 A, K; Z

* j/ P; D! R% j' r17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
/ p; h5 k% A3 R: ~6 L
5 r" _2 |# k/ X% v) d2 U18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。# b& R! ~3 ^2 u# H' f

" q' \) B# N1 m3 Q19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。6 s5 O5 A/ K$ _
6 ?- l' t" r- H4 j. D
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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