Board logo

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

作者: admin    时间: 2008-4-4 02:24     标题: [Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。0 l" Z+ O5 b' V
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
$ o9 n, }5 p* J; K; l本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
0 }: y3 u% J7 j% h; P( A8 O7 U
0 f, v  C4 _* V6 {- H问题; l/ W, A5 K' u4 L2 n: X; k
3 ~  a* [3 M/ F# @7 M, M$ R- r
1.对象的蓝图是什么?4 P6 B: e3 x+ e. f7 j

& e( F# L7 n# y7 v8 r: o答案:____________
- S) I! s: Z9 s* O) E+ g% @5 N; A/ [1 E6 V
7 i/ d; v% |! q$ K3 u
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.c0 c& _  u! H% O' P* l0 T
B.b
) w* X  Z% U  ?) r& F" Y: `8 F  dC.a0 m1 x: R2 l; P' F' b' _. F
D.d6 [& n2 K3 ~( |& _8 ~/ t& H7 g! k  Z
E.e
( l/ l5 e7 Z& {+ y5 D& P! M# P! S1 U' ^  g- `

9 f* E* }) H3 f- Y' B; X3.如何让类中的某些方法无法在类的外部被访问?
6 Q7 C1 O2 H; B/ M3 g6 ^( F: Z' r5 J6 y! m8 B
A.把类声明为private; ]) ]& e9 c% ]; S+ X
B.把方法声明为private; F- Y  n9 |" b, V( @. [% S6 v
C.无法实现
2 Z# ?9 R" ~6 ?, F8 |6 i+ c1 [& FD.编写合适的重载方法(overloading method)
2 N* A) n/ H- a" h( |9 F+ L5 E
' _  q0 G# {$ m& Y( ~  i
- c" ]$ u0 y9 ?8 {4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
4 J2 t: B+ E8 B4 E2 A% y
( j0 Q- U! l0 H  RA.MVC模式( ?* Y4 P# ]$ b8 R6 O. \
B.抽象工厂模式(Abstract factory)
4 V; R2 U; [8 g4 t3 HC.单件模式(Singleton)
, I! Y- D6 o8 X/ W, r! b: ID.代理模式(Proxy)
/ z& H1 N0 V7 T6 I! VE.状态模式(State)" b& H1 B+ I  o5 C1 M- w/ N1 Z

" Q* T4 G* r, \  b  Y" A$ J' s- r! M+ M0 V& ]7 B
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?' h5 j7 ]! b; f: E4 ^  y0 G; n

3 h3 X* O" @0 lA.1个: i" R8 s: w* G. A% J
B.2个: t" |8 {6 {/ E! k& r
C.取决于系统资源. }4 [( t% n) C  @7 G( k/ Y* T
D.3个- e. j/ t( _% Y4 d. Q; y7 @
E.想要几个有几个. r) ?2 S9 l" N: e: R( R

- q( z! `( f, ?6 `: r; `+ ]9 N0 L* r7 R  Y: w/ n' x
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.多重继承
, |3 E. i8 Q5 `4 S9 NB.接口+ p' t4 p& h: G7 y+ F
C.抽象方法
. V0 w) S* ]; C2 hD.Private方法8 z; f! S) n3 }" q2 S$ U
E.函数重载(function overloading)1 \! ^! x, {" z' c7 b& D- Q

/ N6 i( n/ n' I0 p; A, T9 F2 o5 m; z3 w  D# b
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
, }' X( v0 o/ Q
  h7 X2 E" u6 J6 EA.__construct0 D. ^" ~# [: [; v+ \
B.initialize
- i: _7 Z7 P9 Y8 f+ BC.testclass
' u  h9 r! O: A3 ^5 g4 ^7 k5 A1 GD.__testclass
' [: K- Q) C0 [" XE.只有PHP5才支持构造函数2 x. J/ n' v2 |7 l$ w+ Z

0 a. K! J  N$ p, W5 d! d
' i$ L  t7 q  P- j- }8.一个类如何覆盖默认的序列化机制?7 Y  e# H- S: T' i
: E4 k  L) L) \$ K5 s
A.使用__shutdown和__startup方法+ V5 Z5 N+ g, _: V
B.调用register_shutdown_function()函数2 E- a" T: g/ F+ `! _
C.使用__sleep()和__wakeup()方法
6 s* `4 `; q5 o- m4 Y, FD.无法覆盖默认序列化机制; @( J9 ]* d9 S
E.使用ob_start()将类放入输出缓冲中
6 N: H  |; {1 a6 N, j8 j1 z; e) s1 Y( O) q8 t
2 v( s+ F$ k# X. Y  C
9.以下哪些面向对象的概念无法在PHP4中实现?
. H7 N4 }7 C+ m$ p& Y3 }8 I! M0 [0 F3 H2 G+ h! F, P
@抽象类
1 v, g' N- J) D. [) a( r' `  }8 j" S@Final类3 D7 L/ N# c" s4 a" y/ @
@Public、private、protected(PPP)方法
+ E; I) H$ s$ g/ M@接口
) z0 d! a9 G9 O* r# L
0 s" W1 @/ t2 w' W8 ^A.抽象类( S8 V! l) N$ ^: X
B.PPP方法
$ f5 ?. B" K$ z: VC.PPP方法和接口
2 y% [4 j; ]$ g9 ?0 @4 RD.以上所有都不可用
$ q) x  b$ v. ~8 C0 ^  k2 R& V9 h- UE.以上所有都可用/ _& ~6 I- p; b" ?" A2 ?

6 c7 K8 d, F; B' g4 O) k. j9 L, N% s  S: G# u3 Q
10.如何在类的内部调用mymethod方法?$ A4 Y0 ~% Z- r0 C. n
: T! N& Q5 M! Z7 Y  W0 ^
A.$self=>mymethod();& o4 k% u) f$ l2 H8 z3 Z
B.$this->mymethod();. @6 K" q2 f) c7 e9 P
C.$current->mymethod();+ d, |% K* @4 J; N3 n( \) C
D.$this::mymethod()5 C( e  s" a7 ^% A- ~  S, K# M7 N
E.以上都不对- I, u( Y- [: Q% ^# U" e  r
% }6 ?8 J/ ]3 h8 r
0 k0 j: z$ q( g6 V) @( j
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
+ ]% L8 P; J; y) ]$ vB.Null; M% p4 Q+ o- @9 B  @, P
C.Empty1 `+ C) @9 w7 k
D.什么都没有
3 ~+ n1 v" A! T% _/ {8 }% s8 mE.一个错误
; E7 C: k5 B  o3 h, G% Z; K+ T3 K4 J' Z( a  I& O) w

! }2 R# S+ M/ I" P' R! F12.以下脚本输出什么?

  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
) W8 q: ~: i0 M6 `! N( O+ MB.5
/ ?$ L' p6 _+ _/ |5 aC.2
# Z8 f. I3 N' t, d5 M% E$ q; cD.Null
- }9 t1 K, K! K, r; y: QE.什么都没有" B: a2 y( F/ D4 s: d

( j8 j$ J+ d+ [4 z4 q/ Q6 o0 e1 r: o" B  p7 p
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
# H% }$ G: `1 K( Q$ T% ?9 sB.107 N: |: D. U& p- h3 J1 W2 ^% U
C.什么都没有
. W. k9 J8 Z) i* G% u2 V0 |: }4 f0 aD.构造函数将报错6 e+ g% B  r% J: z$ U6 |
E.5108 g% E, D& H0 q
$ j7 {' E" e' G2 ~) H
/ p9 ^. I" m0 {- u5 ]8 z$ b
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函数必须返回一个值. G2 Z4 Q9 J" f7 a3 K. D/ w( i% l
B.reduce_fraction函数必须接受一个整型值
" ]; ?2 Y/ I) V  z; fC.gcd函数有问题3 @, c- \; Q: ?" |* c  A5 W, e, J! r, |
D.必须通过引用的方式传递$eight_tenths对象
. B* j( V( ]7 C' oE.对象的实例不能传递给方法以外的其他结构。0 I: `, t8 P4 Y

/ C- h5 O3 q' T" e5 c. l
: \! l2 c+ t  y: h% H15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法# {, n) I, g+ t/ b
B.生成myclass的实例并调用mymethod方法( U1 ?" }/ J; t/ @' Z" r- k5 E7 H
C.产生一个语法错误. |6 f# E" \* W5 i; ^' u
D.默认myclass类最后被创建出的实例并调用mymethod()0 X" T. b! ?( `0 n8 g
E.调用名为myclass::mymethod()的函数
; P/ D* e  M6 |2 L: m- c
1 p' Q; N& R' j. N. D6 }4 I7 a% {1 q+ |6 z8 r) Q# B* `
16.PHP中有静态类变量吗?
, j9 C8 C8 @0 [" M0 ]" }( R+ R  ?# m5 s
A.有
! e% K+ t4 e8 jB.没有
2 p% ?8 t9 @# l8 F) t# I6 |- E) O( o) C& H" @

* I# @" r4 i# e, i17.以下脚本输出什么?

  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
4 Q, ]+ f$ n, n; j) z: x+ Y' xB.2: ?: P8 L" i/ i9 N
C.一个错误,因为没有定义a::$myvar& E" W- |8 s2 H! H
D.一个警告,因为没有定义a::$myvar
' ?. l/ S& ~' F  w6 rE.什么都没有
% _' _4 K( g& j1 A  A+ q" T/ {! z- ]1 K3 r+ s+ p
/ N, X) @( [/ U, i5 N* k
18.如何即时加载一个类?
7 q1 P% [8 V( u: w( c3 j) d7 }
- T9 k* Q: a4 tA.使用__autoload魔术函数
: @. J7 |. X- m% R, @* R3 w0 P# qB.把它们定义为forward类  n% ]9 u& D. ?( f8 L1 D; `
C.实现一个特殊的错误处理手段
+ D4 V( W! a) a) }# A3 BD.不可能
( L5 s- A6 d1 k& i# Y9 sE.用有条件限制的include来包含它们( l# @' J$ T4 M8 S

) H  [; V: H3 F7 q1 f- W9 B( }" [
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
- Y5 s8 k- j% o" v! x) i8 ~* l; q% E) M# F3 u% y+ f
    答案:__________
- Q1 ?5 B0 [. w. h  S8 W( k) b2 _3 f8 B: t) i2 T
* \. Y/ l! V* C4 x: A, T3 j
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
' I0 O" ?+ v5 P# VB.一个错误' s0 w5 I0 w" u/ P# }" o, {' Z
C.一个警告8 J. s: Y2 f$ _
D.什么都没有7 G) ?* [! p7 G9 U5 S

7 o0 p- |! U) g$ R# y3 Z" h1 _- [# u# f) ]- H* E6 _
9 j: Y8 ^( V. g/ [# }
答案速查
$ P8 I1 X% [4 M4 U1.类
7 X. M9 T) W, \# c3 ]( ?2.BCD$ O/ g6 `% M( c2 a9 ]6 ^
3.C/ R( T3 J1 S- n7 c9 a
4.C# w& ]( X" A2 G0 D# \
5.A5 X8 Z/ x' c% {/ U0 Y' @
6.C
: J- S7 T) T. H. s7.C6 e8 P3 s4 Q% P8 i" N6 C- x
8.C" R# h% H7 @) X+ J% K2 z- A
9.D
9 H6 W" }$ @" ^4 W# T' F10.B- E! y9 C' x8 s; o
11.D
) o9 s+ A8 _# d1 Y12.B5 }+ Q  f4 P3 q5 N, M* n
13.A
6 n" n- w, l8 z* n: x14.D; C. f. d6 ?. c% P. F
15.A6 g5 `. A. P4 [8 f2 `1 u! M
16.B
" B. n8 \/ n1 I0 d6 ?0 T17.A9 S$ N" ?! z0 j# w( k. e
18.D1 Q0 J) g* q1 `5 b$ c0 l7 i
19.设计模式
* n5 |/ E# }3 v' q, l20.D
9 K, A, \! c0 D# g7 S8 z* M1 T& e+ \7 P
0 n, z8 S6 X, X9 ~) A# `  u
; t4 d5 i0 i7 R1 j4 Q
答案详解( G- f& N, f5 M' m
7 i! o# B; ]  @* P0 u# J
1.类是对象的蓝图(对象是类的实例)。
3 c; T$ E4 a& D1 G7 @# o2 P$ y8 g: \( q  @) Y; k
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。6 E5 I3 L4 K" I$ ^

; L% n, @  ^3 A) G! A# H3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。9 O$ S4 e1 d) f$ W- q2 C
1 X. C, |& [- p* p8 A
4.单件模式可以限制一个类被实例化的次数。$ c$ E$ s! {, W
$ q% z; z; l: f2 a0 p; o' J! N6 H! F
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。$ @& _0 U+ _% C" N3 _0 t# u7 v

: J& i0 o, P& o- g; V4 Q# c6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& ]* _% k8 _7 z: y4 P- c& n5 ^8 x
' u" c* r# b$ c. T7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。# r; V0 P3 q5 u3 H3 v! q* n
& U3 R( j+ J7 w3 H1 {6 {
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。% Q7 J5 {, t* R8 ~9 j  ]
0 V- S" Q. e  ^# X
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。3 r; {6 K) V" [

6 l- @8 x! D! r5 n" j+ O4 V& c! A: D10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。0 O# E: y" x* {, j, G
4 Z0 M) Y* _" g
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
* _5 v* N  I+ S! u1 \
: w3 V! c7 ?5 C0 ^2 M12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。8 B6 l5 T; P' x

, K9 u2 [) [$ n9 T) `13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。/ z0 |$ r6 M+ {# t5 g4 A
. _$ N1 i! N0 {) s) W, k* N
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。) F; g, @* d: V( G" f1 [; z
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:5 T8 n5 u7 a( j8 ~
    function reduce_fraction(&$fraction)1 d) R9 I9 z! i& S! Z
答案是D。! S9 M4 |9 R5 d) D

$ q, Z5 c+ d# ^; q" g15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。: t5 D! w. S3 d7 s2 c5 h# e
4 n5 @( s+ A0 \
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。6 n) E# S. Y: j0 q
/ i4 L& h9 k/ C9 E: A" g% C' O
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。4 h; H& {1 s  U
) l) H% z2 P' S' B; z
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。6 c! n6 w! Z2 t
9 z# F- Y6 G; l& o0 h$ Q3 W
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
5 d2 u0 q( L7 ?- V( J* Q
- ]" ~9 V7 \6 z: k20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




欢迎光临 捌玖网络工作室 (http://www.89w.org/) Powered by Discuz! 7.2