Board logo

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
2 Y8 ]/ n3 j1 u- ^$ Z. GPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
& I( x7 ]- d: k( I本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
* d4 q0 L" |1 }, T& H; m# Q2 d, G# M
问题
1 W- u8 C0 s7 h' ]  P) ~6 N2 a# o* I* P" S) _( i, ^, f
1.对象的蓝图是什么?( [8 L, H5 b5 h+ e) T) A# G. L

( `3 W& C  h# ]& g答案:____________
' j1 g$ a0 d9 _; M2 Y) D/ p( w. X* S" k( x5 T; O2 R+ w2 K5 f7 j1 b$ C

. a2 F1 D$ r9 X2 Z. M5 _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- ~( S  m2 i  ?- _( O# J
B.b
6 j5 W' j) W2 g) IC.a
: K) R% @4 e7 W, ?3 ?7 AD.d5 C+ [2 H. j" G1 w
E.e$ `2 K+ ?  m8 f

* C+ Z) Q# b3 O4 c: S9 v
7 A8 P. E" Y0 P( G- p3.如何让类中的某些方法无法在类的外部被访问?
8 p( a& w5 }5 r# }/ k! s3 f+ F; z, r. [) P* K. H% l) L  M
A.把类声明为private% u: E/ I  f9 H3 v& [8 `( q
B.把方法声明为private8 L1 ?2 w/ R& Y. c; Z
C.无法实现! V2 g& V& u6 w1 z, ]" s
D.编写合适的重载方法(overloading method). |4 b* D" g1 i( w, d* Y* a
4 j- S7 e  P( l: C/ H

5 G# }6 k& K5 X+ S9 A& [0 p4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
( M2 q' f% w2 U/ k5 }+ C9 }
8 }* U5 J/ d. K, q  H9 {2 [# VA.MVC模式  U" {( n6 U9 Z
B.抽象工厂模式(Abstract factory)* k9 V5 c& M3 U& o: N: b5 }  M
C.单件模式(Singleton)
! I; \# d, o. g  H' aD.代理模式(Proxy)
" y$ W. ^6 G% J; TE.状态模式(State)
- q: l5 I2 j- Y3 d
, [. O8 }# p5 M+ h. \. n$ s( M4 g" t; c8 R; K1 t$ l0 d
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
& z3 q/ I' i) n& G; U, z( o7 @& k3 c
A.1个. L+ g: F- q4 p, m" j! ]! N
B.2个1 z: \0 n1 g9 M8 U8 B
C.取决于系统资源8 H1 f8 |$ w8 d6 H: |  C2 T& w1 L
D.3个
% W! y/ G+ p9 k8 S3 pE.想要几个有几个" {7 n, g# }$ F

1 H# u& G& z* o4 S7 g! F) r0 B4 A' j$ D8 u' d
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.多重继承  C7 a6 n# N3 T3 ]  j8 L/ L4 j
B.接口
1 o+ c5 P& T! ?/ b" j1 _/ cC.抽象方法
6 p% h' o; L) t0 ^& XD.Private方法
: A7 S" {( D0 k# d" PE.函数重载(function overloading), N5 B- i' E5 a" w
& O& U0 R1 B% l( b" Y+ L# _

2 j7 Z! F/ X2 L! Y# j% u7.假设定义了一个testclass类,它的构造函数的函数名是什么?
$ }: e3 Z; b7 X  y: |- R1 g* k& S8 R4 H( R8 t8 b3 V4 ?* _( y' \! I! o
A.__construct/ V9 d6 ^1 b( n  @3 v  b
B.initialize: F/ f; M5 I0 v, u+ S
C.testclass
% X: }3 Y  G1 k# t; _D.__testclass0 O3 q8 b8 z) B" ]1 C$ j# P
E.只有PHP5才支持构造函数
5 o  d# `* C' A% u) D6 l4 h6 v- s
- i$ a3 b1 Q& Q$ e- n9 Z- o6 x& @5 \& [7 M6 x( I
8.一个类如何覆盖默认的序列化机制?" U! R: ], n' O) B+ O: l; V

+ c+ k$ e( |% W# E) |! T6 |( |A.使用__shutdown和__startup方法
4 A: d. V) w. F' TB.调用register_shutdown_function()函数
5 j3 r* n* D6 @6 X7 y/ Q- w. E- AC.使用__sleep()和__wakeup()方法4 H' X3 j/ x! G. ^7 J* R! z
D.无法覆盖默认序列化机制
$ ~1 {- U8 j% F' H8 \( RE.使用ob_start()将类放入输出缓冲中/ ^6 }1 R+ w: z1 g; ^9 F- F
* y0 L! J5 R2 y+ [, p

$ C5 ^/ m  [: E3 k) R) j9.以下哪些面向对象的概念无法在PHP4中实现?# D( w" _" O+ \' h( i0 q1 p
- o) I+ i4 N8 {$ h7 R
@抽象类' X2 J: o! R5 S9 [3 _
@Final类0 @% V6 y* ~$ ^# f+ t: l
@Public、private、protected(PPP)方法
' f2 J' y# H& E8 X( v8 J. z, u  A@接口
/ K; h4 V% B! J0 c, U1 P' z8 r& w
A.抽象类, ~* ~% H. C8 F0 l, L0 f
B.PPP方法
4 ]2 s" ~; R: A8 MC.PPP方法和接口5 t7 ^. x! v$ z6 _$ F
D.以上所有都不可用7 R4 B0 B) R$ e/ i: ~) D# D
E.以上所有都可用
# @8 K/ h: R* Z  {; \! d! h. V& b1 G
8 j% \4 Z2 ^7 l& H  h% _' w- ?6 L
10.如何在类的内部调用mymethod方法?/ m7 z( o( [  `3 \* D( D% f

. E# [! S2 L9 S  u0 f$ z1 V. N/ _A.$self=>mymethod();
0 p* C, p0 K* b' A' XB.$this->mymethod();
! r9 n- |# A) k4 G; G- I; yC.$current->mymethod();
/ j! o! K8 d/ Q# FD.$this::mymethod()
* A' T1 S- j0 {% R+ r: I1 AE.以上都不对3 b/ ]3 [' @- Z; Q  b+ x0 U

3 j. j1 E+ q* W- A0 U# }6 E7 @3 o. [. O5 G
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" F$ N; M  N7 p+ N% ^/ v
B.Null
2 P% i/ l4 x" {) `/ A4 M# |, UC.Empty2 }% w" Q# B+ B) i
D.什么都没有
/ R& }! B/ R. z& nE.一个错误
( Z: Y4 v0 @5 p! R# Q! Z4 X: d" w" n( Y" }' e) I' B2 e

( m9 X8 ]% f6 S% h12.以下脚本输出什么?

  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.106 M! ~2 g4 W& T" `/ e
B.5
4 s  L" E" q6 \* S6 eC.2- r$ Z* @; G; J# g6 E
D.Null& ?0 ?( ]6 p/ B- C) e
E.什么都没有
+ q) o- W7 p+ L
* D$ P* P( ~/ l4 R' H& P6 ~& o' Q, T* o! }0 j7 `& ]
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: j) W$ f: T2 |4 s6 _
B.10
4 I$ s" h( q# l8 f( r$ y0 YC.什么都没有
+ d2 i9 i, c$ z2 ]: A9 Y+ X0 l% ~D.构造函数将报错
% \: d: i7 X6 M* E/ [+ ^( [, UE.5105 `1 x) T4 Z4 B

' |0 V5 S% D3 e2 }4 Q# |% t- v% |- J% p' M
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函数必须返回一个值
  q+ U6 C5 J$ i- G( i& ^; x8 IB.reduce_fraction函数必须接受一个整型值$ u/ @' H* H5 X7 y& o. P/ {$ a
C.gcd函数有问题4 R# |# j  {* q/ T% C
D.必须通过引用的方式传递$eight_tenths对象
# z7 e9 k& [+ C8 g( D3 oE.对象的实例不能传递给方法以外的其他结构。! i2 K2 t+ ~# [; ?2 r# e

, A' T8 J5 _: r1 _  i  G- n( r
( j, p, Z0 p, m$ ]0 ]3 H15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法" ]' l  b6 l$ r! K# W9 e/ Z& c7 O
B.生成myclass的实例并调用mymethod方法
7 o- i3 U$ l1 J& ?( d& Q2 u* H5 ~C.产生一个语法错误
7 [$ V, d/ [. S) cD.默认myclass类最后被创建出的实例并调用mymethod()
5 R0 y  p5 D. C" XE.调用名为myclass::mymethod()的函数
. p' I  ~. c2 h  m) q
( z! K" C9 D7 ?. u8 A) O7 n* j  y; X( M# x9 {( T+ e# E
16.PHP中有静态类变量吗?/ O4 s7 `+ [& q# s8 N. z! \
) `% g; X. Z/ @' ]8 A9 ]( x
A.有4 D- R8 s+ T( o, V. w+ a
B.没有6 M% K7 X* M+ ~% V0 o* t) q' Z
. o4 l9 l' _( V4 n9 ^% Y8 H

/ @5 b  J" u4 W17.以下脚本输出什么?

  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 c8 T2 U- b5 c  v5 D
B.2& Y  C' a" U( F/ s. u. ~
C.一个错误,因为没有定义a::$myvar- W  A: e7 |% ^
D.一个警告,因为没有定义a::$myvar7 u! u: b  l$ n( i$ G) E" q2 X  ]6 K2 z
E.什么都没有8 k4 G" u- L' `2 k8 ?

. h. U* e: R, i5 y+ Z5 `2 I9 h" C' z  G! I- ~% C% J" s
18.如何即时加载一个类?
. d5 S. b- \# i& n5 ^) P0 h$ k/ j6 X/ J7 L2 D8 u, j
A.使用__autoload魔术函数
* C* C& G" G" }: f7 zB.把它们定义为forward类
0 a8 |* d& ?! ?  W" mC.实现一个特殊的错误处理手段
1 W6 y0 j9 F* kD.不可能
* x1 ]  u8 r( B% yE.用有条件限制的include来包含它们
4 C7 ^. H8 ^% e+ g, j. Q0 J5 c4 h  l, `' L% I. y% x

2 |1 h# l" \' W1 k, x& H$ Y9 I19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?" g0 F5 G, Y6 k1 A  r
, J8 ~% j1 s) T2 g( v
    答案:__________' F" `  W$ M1 h0 z1 X: F5 G! e; f
6 C" {* s9 E/ G8 g$ _

2 h( m: S. v; ~" M- ]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
8 g; ^" W9 T8 h) Q2 ^( e( X: ?B.一个错误
$ N, @  M+ J# X$ u/ b: \C.一个警告
% m* S5 g; @# [% ]6 y; b1 uD.什么都没有- k! ^" f8 W2 H1 \

2 G$ G+ w2 _. g) L/ b$ ]* `7 K2 i7 T$ v! {1 |: b

: h7 w8 k# l7 q5 ~$ F答案速查
3 J; q. Z9 `  q- L$ G4 b2 U( h  a1.类  ~: l+ ?6 s3 P/ ^
2.BCD8 j8 Y7 M# \3 o$ I* u6 v
3.C
7 u0 q6 ~+ e- k) P% }9 t4.C- {" V, }9 _$ E( I! N: [0 w
5.A9 }0 r' N. q6 p6 {0 H6 X7 Q
6.C( Y; w9 X) m7 U' W5 \5 u: [+ [1 F) H
7.C
& s4 k' W4 S" f7 v8 ^5 u  ^2 h: Z8.C
3 `- `" a! N! V5 T& g+ y9.D5 i1 q* f) [/ t
10.B
9 L7 O2 ?/ k  N11.D
4 P5 k& [( Y/ m( g; Y$ O( P12.B$ J6 ^: _0 e. ?; L
13.A) H# D" A5 o: j8 \7 U
14.D
/ b* L* V7 ^: f3 r, f3 C' }6 h15.A
5 e3 r( B) J" q3 x16.B/ V% r! C+ l/ F) U
17.A! R2 X7 a2 Y) }5 {/ _
18.D
/ c2 @! G0 F5 `19.设计模式, |1 G- M( e# z+ `2 O# N: i# W! M
20.D
$ o) n" _; M! C1 \4 N9 c4 e
' w' Z) M6 u; O; X# }0 b( D6 _; G/ H% J+ r0 y1 S* S8 N. T
9 w4 x1 x% R: F) K% c0 T* P
答案详解( \% C' f4 l7 ]- b7 I$ x
% S  m, O$ \! k: d( b0 p
1.类是对象的蓝图(对象是类的实例)。
& a7 F8 ~' ^4 o  J4 O) V% }9 x# [+ z7 k  S7 e5 V& s) D
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
. j* o" Q2 S% u/ p* b7 p; M" w0 B) Y- M$ V! e: S, c
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。2 }/ M; g, h# ?4 ]7 Q" `( |

1 y4 |4 v, N6 p' n4.单件模式可以限制一个类被实例化的次数。* d! D' W# o2 c9 A7 I' t
' B3 I: l. Q/ D0 s: ^' C) ?
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
0 J! ]5 K3 G8 [: [; A& {8 q+ O* z2 @' v1 B8 L* [' j
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。, {5 |2 ]4 k- d; r! R2 Q

+ X4 m6 K3 w  {% ^8 L7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
- ]: v& c3 X7 d' t& S3 Z+ L8 v" i$ }* S( t2 H' x( Z
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
0 s: n" n' |; s+ j+ T4 x- [6 T/ y& Z" O8 `& }
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。, W. @0 n6 h) j  ~

' W5 V0 v5 T% f+ g) g10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
* N# d1 u! E9 R- w7 h: z9 j0 |1 P0 m8 D) A
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。' E; J: o3 X  l' c$ S

0 F& l% D& t+ s* J% O5 o* s3 ~0 S12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
. r& h3 f- o  z3 W2 ^
+ ?! W+ b2 t# b. W# [* y/ `' `( z; B13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。6 [  M7 N! U/ v' ^1 l! b$ u  h7 Y! ?7 s
3 l0 T: D6 x: U+ D* ]
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
. b  d8 N8 f8 K1 h6 n% h回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
* S# r* \7 `2 U) n1 Q+ p  _    function reduce_fraction(&$fraction)
# P9 V1 _4 h9 S& Q, |答案是D。2 E/ M) X* X* p/ ^8 p- C& q

1 o8 |2 [, s. M+ p, T15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。4 u3 n- [% ~  |5 g4 |
7 w7 T; h5 F$ i8 h4 E+ i# b
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。# ]! |$ D5 H# n; `* o! {

  ^& O* U( m9 e: L# C/ \17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。% [1 m5 O) ]2 @" X! e
* l" H- B' f5 f+ ?  V3 ]' Y4 d. h
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。  H9 B' b/ e4 Z9 @  W) S
& `: [& r' O) w- t4 J+ j5 l
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。8 w, ?' i1 X: {8 H$ C4 Y9 x3 r0 W

5 B+ t6 `3 J. }( S. r4 f20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




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