返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。& B+ i8 X9 C1 z/ t/ [/ s& Z# e
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。+ c: q- |; N* f1 j4 x* N9 k$ m
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ A$ [& c" {& v" k( P# D0 I6 W; k* c  c& T0 {1 n' {, _% p; w( `
问题
: X2 h4 ?/ F) y
* P0 b: u$ M: I! K1 ]3 @1.对象的蓝图是什么?
) ^, V3 ~% @/ P& K! i1 Z7 _' x4 V. t4 ?% v0 Q
答案:____________2 A$ g# m. j+ G1 ^3 k2 `

& ?1 [" M1 J/ L7 x" P) f
: R4 L- o- z( Q2.以下代码执行后,数组$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.c8 G5 V  q) m2 I0 s  m# s6 A
B.b( G4 V% {( U& S7 H" F
C.a7 j6 t# l3 h' u2 K# C$ J
D.d: T5 F: n# A5 E5 D
E.e# ~/ r2 C! o- I
) j' F3 G6 R9 F3 E2 e% U

9 P! c( t9 |- C3.如何让类中的某些方法无法在类的外部被访问?
+ ?& P& V0 h2 s1 j4 M: x; r/ G* i) U/ I. x6 `
A.把类声明为private( ~, D+ {1 o. P8 r# I2 d
B.把方法声明为private" f7 ^, t  L( K9 N4 l* ~2 O
C.无法实现7 x! F, R& C2 Z  Q
D.编写合适的重载方法(overloading method)
5 G7 _$ P# R% ~+ ?
4 x5 \( G" E" z8 Y6 h/ ]0 T4 r) ?) o/ x: I) C8 @
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
5 U: n. s3 D2 n' }2 V5 c. V/ S! q0 D( k5 [! ?
A.MVC模式) a: E* }% F  R- P) `2 I# ~% l
B.抽象工厂模式(Abstract factory)+ a7 o. |# |% W' L& |# \' g
C.单件模式(Singleton)
- J$ C( d( h" k4 RD.代理模式(Proxy)
' o" i( m7 r* J6 h" j, K9 e8 Y' J2 sE.状态模式(State)
- ^3 ]- }/ h5 F& Y0 m7 e1 U
3 t& A9 c+ I; j# k1 @3 K6 |- Y8 r- f
7 m& T0 T" w* n' _" P$ b, f% L5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
, N7 N" f$ Z  u5 P: q, q9 l- f/ r2 R0 X" v
A.1个
* e& P/ Y5 x3 O6 o  Z5 e9 _) K+ O; lB.2个
; F% L1 H: ^5 _C.取决于系统资源
" Y. q7 h# Q" R/ ]' N% `: ^D.3个. S, V0 x! A. k$ O4 h
E.想要几个有几个5 F4 {+ N! ?$ _" J

" E3 s4 W8 L; c$ Q# w# q1 z3 e+ J8 u4 t
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.多重继承. \1 r9 ^0 t/ e/ K2 ]2 m$ v6 y. W- i
B.接口
+ N* s& r, x# |! I0 p8 ]8 o- XC.抽象方法
6 h0 t& i3 k8 t3 d/ T  R, `( A+ TD.Private方法3 r3 p* _2 y* w% ~# B) j& j
E.函数重载(function overloading)
6 Q7 h- C; |( }& {2 s, P5 X( ^! u8 a. U
! A* o* k; m  x
7.假设定义了一个testclass类,它的构造函数的函数名是什么?2 `2 q% v( r8 p) S. M
9 q" U$ t, k% ~
A.__construct0 c" z9 V& U; G( S% |' r2 u
B.initialize
! O8 j. v+ ?' c  @2 hC.testclass6 I5 F2 E: y6 J3 m6 l7 W- M
D.__testclass! J' s3 f- s) S) L* ]
E.只有PHP5才支持构造函数
" D+ t2 ?) D9 I1 H6 w+ Q6 h% |- M- Q
# J8 _+ s+ T  h8 u6 t* p* P7 U& Y+ y; H4 x% W
8.一个类如何覆盖默认的序列化机制?
5 M+ T$ X& c& ]9 h; u4 \' {2 Z& x3 X# ^
A.使用__shutdown和__startup方法% F6 ~7 i, a/ g; |& d$ H9 R7 u
B.调用register_shutdown_function()函数! I' P; r/ j0 M& {" F
C.使用__sleep()和__wakeup()方法& c, d) x% ^# ]3 d6 u. H# a: S
D.无法覆盖默认序列化机制5 ]  V# i4 S' q% H& e; v
E.使用ob_start()将类放入输出缓冲中
; n; }; r$ N: u; H# Q
3 I5 D& ^& |( y# C2 D
3 a+ N+ M1 |' d) M, x9.以下哪些面向对象的概念无法在PHP4中实现?
/ U8 D9 q( G: N1 T6 |: _9 C( r7 X$ h& C0 `" b
@抽象类
% u1 O9 d2 G3 n4 H( r@Final类* U- z2 \- H3 B9 C% l9 R
@Public、private、protected(PPP)方法: |# [1 Q+ y- S/ S# Y: Y5 u) @
@接口2 M* L  V- r6 }& I( }+ f

- R" A# l. L* a9 }" oA.抽象类
$ Y9 r7 }% [# ]7 B4 aB.PPP方法: [( V9 e* `" I+ }$ o
C.PPP方法和接口' [9 o. `8 x1 P. `4 |
D.以上所有都不可用
2 h2 A, X* s. Q* @& F( O- N* ~) _+ JE.以上所有都可用' p& h. l5 A9 P& m/ z) ~

0 s% d$ J3 W% @/ l( V6 C. `, u
' N/ ?1 e0 m% q2 h10.如何在类的内部调用mymethod方法?
  K; T& z: x4 R( N5 s2 k* E* t1 ^9 p' J
A.$self=>mymethod();
# ?# u+ |9 u5 V6 H7 OB.$this->mymethod();
6 E  O7 G) D7 Z+ NC.$current->mymethod();
) A3 l4 g' }) XD.$this::mymethod()
! q' r6 @# f+ NE.以上都不对# m+ t% [! n# S! [1 o: o

! U& p2 {7 o3 D% ~" ?0 U- f
  L  T, o2 X! x/ y) X& Q11.以下脚本输出什么?

  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! s: R4 G* x7 @  W% u
B.Null
; `, U, v* s- u3 Q8 P- iC.Empty% x+ w2 n8 R& e( b
D.什么都没有
, `; {4 L+ ]4 @! m5 k% uE.一个错误6 g- e; v0 J' E5 @5 ]
7 l* S2 n/ W$ K
8 O+ j  f3 Y" c- y: c7 K( h
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
5 g# C7 B! n# w0 ]B.5
# n/ D2 F8 @) P- }% y( W$ q, ?% g2 `C.27 h3 B- p% w! T6 s4 n+ J3 ?1 K
D.Null! e* Z  E7 c- z
E.什么都没有: f) d9 `9 O9 o- K/ m1 A

6 p/ Q1 t9 r$ Q  E, ?. c- P7 ]2 G3 w# u( h7 F0 V
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$ ?3 W3 G+ b/ L2 g9 y! v7 k* e
B.10  K; C% [8 ?* x* G2 @9 l* l
C.什么都没有& I$ S: }1 a% W4 d9 r
D.构造函数将报错
  d9 i2 [& \* \! z. H5 IE.510
3 B8 ?) r0 |5 G0 F6 W1 r' X# x) z- s' L5 }1 F0 q
1 O6 H- S1 U& R; h$ M& W% \& _1 Y- ]
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函数必须返回一个值+ O! U# p5 u, Z! @
B.reduce_fraction函数必须接受一个整型值
& f( E. {5 J3 y. W& @3 m, g  bC.gcd函数有问题
4 K0 F3 L7 z" R; K  H' u4 RD.必须通过引用的方式传递$eight_tenths对象
/ [9 O9 ?- N6 ?: a; _E.对象的实例不能传递给方法以外的其他结构。
) Z) c* u) N; M' u0 y$ F6 k7 y
0 y7 T; [9 F, D* j8 }2 x
% s0 Z! `- {3 i4 L7 ?8 k15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法7 g6 `' [$ a- Z! f8 e. E' F+ ~( S
B.生成myclass的实例并调用mymethod方法+ ?/ y# H: q  B/ M  P" |
C.产生一个语法错误! |  D; n% l0 D! [% r# `# ~* i
D.默认myclass类最后被创建出的实例并调用mymethod()
, l* l" B1 |) a+ h0 qE.调用名为myclass::mymethod()的函数
, Q$ m+ D% e& O& m7 ]' T8 ~# P. {4 H' K7 l
: l$ a. B' V. E7 i' V1 e/ p+ [* X5 P
16.PHP中有静态类变量吗?
3 c0 I% n! f! }% _  x1 ?, D! g9 J- ]0 ^1 }; C% ^4 i
A.有1 C+ Z3 g% N0 M+ J# ?
B.没有
, {( x- F+ T% V8 r. ]% [' n' F/ ~4 a+ Z+ l8 r3 i5 ~

1 G4 ?+ J! N* R  F* e9 g8 R- B. E17.以下脚本输出什么?

  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 @1 h) X( [& E2 T" K+ l
B.2
! C4 C, W0 V) l4 B8 ]+ ~$ ~3 D& ~, tC.一个错误,因为没有定义a::$myvar) i- z, Z% C% B  B& J3 @6 U
D.一个警告,因为没有定义a::$myvar: Y# t5 {" q# ^' a# A5 }
E.什么都没有2 G( m  U1 s+ G  R. w

2 o" s( t% o# x0 m, j* `+ u# _# H3 t1 r1 s# U$ [$ v
18.如何即时加载一个类?
+ b9 R7 S( ~7 w& C  X
8 e7 P2 o7 q. e2 p+ x6 l0 v+ x$ p- uA.使用__autoload魔术函数2 Y* B9 i7 _, }) w9 N
B.把它们定义为forward类* [0 o6 z  x  t: h$ S4 v  m8 }( N+ V
C.实现一个特殊的错误处理手段; R! @% J- u' l5 h% |
D.不可能. E) k- j* I# o/ |) c0 U
E.用有条件限制的include来包含它们9 i* J! k+ }6 `0 q, `2 M# Q

$ y- ~2 C9 G8 K$ l2 G$ T9 u7 ]# Y! m0 f. j, `
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?' q3 R: Z2 Z" g/ e+ f
/ a5 f- F; o' u9 u# s3 u
    答案:__________! [. P8 ~; L$ l3 P& h: q, B

8 \  ^; k( K7 m: H" K/ |/ U
( Y- j$ V  y. z# `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- N; x& \# b8 x  l: |0 H
B.一个错误# |5 c0 `/ e+ K% V/ z1 K! [! @
C.一个警告) O5 j* }) t! r/ t
D.什么都没有
) U& u' h; t" D/ N4 m; U9 x% t$ }3 J: ^& S3 V% j  n" C

$ _9 M7 f4 M  v9 ^  P8 c+ h( n4 y/ F: f4 y. `5 X
答案速查
3 Z6 y8 I- _. r3 S1 U1 T1.类
5 g, D: T0 J3 P9 X2.BCD( v* x+ W4 i+ P5 R) Z% Z4 a1 ]
3.C
( l8 A0 G5 @1 Q; j) T4.C" G# B( o4 @5 U) }5 f) n4 E. g
5.A
6 X4 K& e. B! n" `1 O) t6.C1 ^! H4 K; q6 G  C! m5 E) ]
7.C
* z, k3 l( W" D$ I! U8.C0 |1 t. v* L7 O8 y0 {2 }7 i0 Z
9.D
% V/ Z% c5 r4 \7 E1 ~9 |+ Y$ p# I10.B
5 o" o2 }. m4 t( B7 |11.D
3 Q  b( b( i; ]" [+ C! t3 C; x12.B0 e) z2 S% I5 J, h
13.A1 e# L9 \# g" Q1 ^" m1 C
14.D- z% S# Z$ H  u2 _# B
15.A: T+ \( D3 w' f. Y
16.B" \% b8 s8 ~" c( D7 X
17.A
- ^2 t, H, i2 \18.D8 B- ~- d, u4 @
19.设计模式
1 d4 q& U- i0 I+ s7 ]3 v20.D5 s8 R6 L( v/ L" b% j8 W

9 z( b# K& ]8 M8 S3 H  y, |
3 M  z9 r6 `* k/ B9 u' W
2 j+ m' A* J, a7 a* f! W答案详解
* _/ z8 }. P5 P
- V/ d/ S2 W2 I) S* g" j. G/ y1.类是对象的蓝图(对象是类的实例)。
$ a  c$ A( _7 i4 {+ W9 Z+ t" P
  D% D4 U& f4 f+ A2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。2 Y- l3 y4 u1 D& z$ k$ c
5 G; T/ _$ y5 ^; Y( G2 j
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
$ e" k1 i( B. b  [  G' l; s7 h( v  C: \2 S' x
4.单件模式可以限制一个类被实例化的次数。
( i+ ]1 B& \' I* X2 R2 b8 A( t. D1 J* X! Z% R% q; x. m7 k
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。3 ]. z5 k( V3 u6 k% N

3 E8 H- u3 Y* s/ v7 @" p6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。2 f3 \! F& l6 k. }( O7 C6 s* P' d2 J

9 V5 y% X& ]: i# A$ q# o7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
9 P! m8 |3 c  F9 k! f2 u/ \9 B1 U5 L$ d) E* ?# K: O
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。; f1 {- K1 C  ~4 e+ J
" c" ~5 a2 ?' ]' \: n' M
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。5 P& r* Y. M2 I5 p# Q' g, a9 R
0 N- {5 C4 R& j* \
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。! j  j$ `( U: W$ J% G* H
3 s% v' q4 d0 Y7 `! e
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
+ W% t: Q8 ^7 Z, q! E1 C8 f5 }% G; A: k: o
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。( \& t8 \; y  A. o2 j& B9 [

. D1 @5 N) q* j) u3 S! d13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
" W1 j0 C; R) ?$ ^5 h
8 \) M- r- j) \4 O  m7 r14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
5 f/ Q) c+ o6 O* f4 n回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:" r  ]+ C7 d0 E8 e
    function reduce_fraction(&$fraction)* i: [2 S" `" i4 u! K: Y* }
答案是D。
" s8 ?* S9 |, D3 m& _% G2 z* {2 u1 {" a9 H
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ I2 P+ q& l$ }1 R- T2 u! X, t

& X& \0 ~- E0 I) F16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
& o* F0 u( K9 R' H9 H; T7 _9 g; a( s1 w' p
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
3 m* i1 K, |( _" C6 I' R
2 n: H6 J% v, I3 I18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
2 O/ e! L- D3 v6 f9 ?. {: g( V2 n7 p4 Q- M" A- l! x
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
' {% q4 H1 R/ \3 Z5 i* b+ N
/ O" c# C% E( _3 z2 ~$ D6 W20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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