Board logo

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
  r/ G4 R5 l# I2 p2 P! YPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。1 I# m; D4 ]( @& H) x" H' h: w. R
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。3 Y* s8 f# s8 e

2 n' k5 R; K+ n: P& V问题
5 ]+ \& ^1 e0 m' u6 m+ G
: n+ E6 c4 v6 T" c; y7 R4 j9 j- l  F- J1.对象的蓝图是什么?
% Y: t8 E, J! N6 B" {& b+ b/ x- E( _& e: W% D1 `) \. o
答案:____________
8 c; \% L& w. X9 `' Y3 S& V/ `) F* \$ m: C7 V# M: `0 u

. s8 h; h7 ^& l6 m# d! F! l2.以下代码执行后,数组$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" ?/ F' a( n7 Z3 N7 i
B.b( O; ?8 d, \8 d0 R. O
C.a  m1 |! |6 h% D. |% ?
D.d
7 j: J& v  o- z5 S4 i7 sE.e
0 l: i0 D$ V3 G* @* g$ w6 \0 d9 S- X+ v- N1 i5 _
* g# T1 p# T* f% x9 X
3.如何让类中的某些方法无法在类的外部被访问?
# N; p8 b/ y0 t+ r  G  N  @
. ^5 D' p5 x- {$ @) ~, _A.把类声明为private
& k: G0 Z7 |$ B, i5 F+ E% tB.把方法声明为private
9 g5 A3 q" {( x7 v# xC.无法实现
/ g! `* q0 h' A8 I) v' hD.编写合适的重载方法(overloading method)# v: M" T- E/ p4 ~5 V' L: T

& S( U$ E" ?! H9 J1 Y/ g& V5 E, o
) ~% H1 {& X9 q  k4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 ?3 p- K3 i  A- I7 Q8 \: E
7 }' [9 z: p! k9 C# U/ w7 Y
A.MVC模式
1 _! X. w& f& a$ g& q& W. @% CB.抽象工厂模式(Abstract factory)
  W# [; P! u7 eC.单件模式(Singleton)
% C& S4 K8 R5 XD.代理模式(Proxy)/ L3 T; E6 \& X7 [. U7 N8 ~
E.状态模式(State). a4 q! j3 [) h; o9 |# g' g% X: v
. d) K) }) T, n

; a, W1 d! F$ G5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?. k3 {( C0 h* y/ q! p8 S, `

, {/ Y4 V9 P; H4 b1 d* g8 }A.1个5 G& o% [% @- t9 j9 f
B.2个
, c" _" P4 C# Z. W( F% ]5 w' qC.取决于系统资源/ {/ X* l2 Y$ l' Q
D.3个
* A0 u& q5 Z! o! x; n; S2 m5 e" VE.想要几个有几个
7 y+ U( \0 Z% Q; B8 c
5 [  X( Q9 w/ z
  h5 E% g' G8 q' S% [  n  n6.以下脚本近似的表示了一种在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.多重继承
) ^, {8 b  o+ s4 \: R5 N% ]B.接口2 m/ B+ Z( I7 ?9 a! y" N: B/ {
C.抽象方法
9 u/ i. }; i' Z; m/ M1 Q/ A9 @! L& ~5 uD.Private方法
% h% \. t, U% [" a2 B  ]E.函数重载(function overloading); q! e5 u  S7 ~) \! c; V* B4 g; p
: q/ f2 g& `& o1 s& u) @

7 l: f+ o/ @% o# m7.假设定义了一个testclass类,它的构造函数的函数名是什么?* G4 q% O' \- _+ l# B0 B: E
1 ?: q' N8 L% O6 J5 l" Q5 Q# o+ n
A.__construct) N  I& h0 d  S, k4 ~1 o- [
B.initialize
4 w# f9 F* N* d" [C.testclass4 w% ^5 `% l: i4 ~( b2 n# ]
D.__testclass
5 U; y! D" J9 M6 o# k+ }: o/ TE.只有PHP5才支持构造函数
& [3 C$ d& i' K8 {0 Y1 F+ ^+ z  b5 E0 O/ @" |+ @, O
. d0 c9 q' f9 `7 Z
8.一个类如何覆盖默认的序列化机制?
! Q! @( |3 L; A$ u2 b2 l" E8 Q3 \
1 f/ w' n, T, d. b" l# JA.使用__shutdown和__startup方法7 j' n# |! m! u
B.调用register_shutdown_function()函数
$ v5 `( x$ C3 gC.使用__sleep()和__wakeup()方法: r9 z7 j$ `% B7 S- z* ]' j2 A: _
D.无法覆盖默认序列化机制: d* p' F- r/ X+ R" E& K4 q" Q+ `
E.使用ob_start()将类放入输出缓冲中
% D2 `( z1 z- _+ J. G
9 |6 X1 O* M6 F9 ?6 j% b: m8 E! r4 G, q4 \  V* _8 b
9.以下哪些面向对象的概念无法在PHP4中实现?0 I- s) Z2 i: H9 B3 J. \# y# N

2 _$ b  k" i3 Y0 G@抽象类
" h2 V) x( I1 g$ k$ A: W@Final类4 ]8 D/ B8 ]/ W3 f
@Public、private、protected(PPP)方法4 [; `* A/ O  S' d" ?( x; q+ Q
@接口
; O9 W, ?0 _; O# G6 @6 ~4 @2 ?0 Z& V+ C$ ~8 ^0 E2 _/ n
A.抽象类" }4 [( D% |5 i% O
B.PPP方法. w9 O# r  {  a+ P! Y
C.PPP方法和接口0 U* f5 Q4 }3 `! u6 L. C7 e2 \7 k& |+ B
D.以上所有都不可用
9 l& Q7 V% ?! X  o5 B7 t9 a9 RE.以上所有都可用3 w0 r: v0 {- Y
1 o- T0 |* P, [! B# A: N
& ?  A' w9 e9 f$ z% j
10.如何在类的内部调用mymethod方法?
  x3 j# `6 _( j! j- ?! q5 t3 m  V; n* ^- x" W
A.$self=>mymethod();. X/ e( h# B: T9 }  n$ U  V
B.$this->mymethod();5 ~& V0 D( r9 N# n7 h3 a
C.$current->mymethod();
5 c2 J7 L- V8 V5 S- s) j3 SD.$this::mymethod()
. Y  [& m! Z. ~5 Y6 ^& h/ m; {E.以上都不对
5 ?4 n  G! A2 h7 d
6 k$ c) ]- r0 q8 _0 A. {: M8 j9 @+ F5 k# j1 [! b
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.109 \5 Z) ~. L3 C8 @
B.Null
( G5 b6 v- U" q( H# {* JC.Empty
0 _' q" `4 v/ q% _' Z; W  o4 h& uD.什么都没有) ?% M/ O% o+ B/ l
E.一个错误  G$ ~2 b. m  |' w( B) j/ L5 f
+ R! b4 R: S" s- j; G1 b1 R

" a8 M! a$ Z0 [8 C; f6 O12.以下脚本输出什么?

  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
1 H- T: f: l! u8 sB.5
( s) U% [* {; y' d! mC.2
* _. K7 a# \& B* A/ x- h  qD.Null2 ]" E1 `: k, h' R4 Q0 l# a
E.什么都没有
  d6 J" t) D5 j- O1 q2 |
) ^) Q- {5 I) g4 [
. b: K7 \  y  @( M+ i* z& y13.以下脚本输出什么?

  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 N2 z/ x9 q1 T3 F" \) U! H3 tB.101 J$ ?/ _" d0 ^, r% b% p6 O' R
C.什么都没有
  P: ~/ d6 j) i- n+ w) SD.构造函数将报错
- z6 F$ H& e- q6 x! RE.5109 k% k# v' r4 F; S" \) [
+ F$ K/ x) F& ~6 o
. w, K9 i5 i7 h
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函数必须返回一个值+ M! h! X% K0 |$ ^, Z( [; K
B.reduce_fraction函数必须接受一个整型值
3 C4 X, x% ?4 D$ R2 gC.gcd函数有问题; b) A1 c! L0 d- |: g4 v
D.必须通过引用的方式传递$eight_tenths对象
6 |3 m5 K- v! w/ I3 FE.对象的实例不能传递给方法以外的其他结构。
2 X# F  x* `. J! I( E) F. G7 y# }& p4 F# r9 }" u: d0 {
, I* r4 D& h* A/ Y' h
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法6 C$ R7 n0 h8 p! N
B.生成myclass的实例并调用mymethod方法
: _' T: g! @( h( K7 lC.产生一个语法错误. r; `7 q+ ?4 R
D.默认myclass类最后被创建出的实例并调用mymethod()/ Z7 e2 B' |; @' O6 m$ e0 O
E.调用名为myclass::mymethod()的函数
+ p' }9 G, ~+ t  @% L, @9 f1 d2 w7 t9 Y/ l; Q5 V6 B, O
+ T8 ]7 ?; Y+ k
16.PHP中有静态类变量吗?
; S, r! a$ k' G1 J5 @2 g( K1 ^$ M5 W, U8 w; P
A.有2 ~/ ?0 k$ J9 R; V+ [9 z
B.没有; {3 ?+ j% x7 T3 f  w
$ m. A2 X2 a9 N

3 d- F  |  V6 \! q! x4 s) p17.以下脚本输出什么?

  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
, f; S# Y- ?2 W) s. X7 VB.29 Q2 f8 u! P3 ^. ^5 j9 L* r7 W
C.一个错误,因为没有定义a::$myvar
# R, K: s. D9 qD.一个警告,因为没有定义a::$myvar
, q* U! F9 c+ V! |" DE.什么都没有" X9 J1 B$ ^5 A1 T
- X/ E& E/ ^0 M; ~, f6 k3 U

0 S% d! l( Z9 a5 }8 C  P3 Q18.如何即时加载一个类?
2 C  O$ |- x1 _$ R; M- i
. t  m" Y: e* o# _) H0 wA.使用__autoload魔术函数
4 ~6 p) c4 ^. `  h/ GB.把它们定义为forward类' A5 @4 O& U& ~" K( B
C.实现一个特殊的错误处理手段7 x- n: U1 r2 S' x7 b! D
D.不可能# J; X0 F! ^2 m: Z. J
E.用有条件限制的include来包含它们5 p: n  \" m8 U& Q9 z7 X2 A# t* V$ e

  A5 ]& P/ o0 ]# _
0 X3 G# c$ S% W. _* m3 s9 ]19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?) q2 D2 \4 Y' V7 @0 Y2 C
' L' |" `- r0 s1 t7 H+ l
    答案:__________
6 n7 ~( T- I$ o
0 E5 X2 `# E$ z6 s, C
* `0 b3 E3 p; Q$ L8 F: _. L9 K0 ~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
" M7 ?& o9 A- P; ?6 DB.一个错误# g9 t1 a' H& c; ~
C.一个警告
/ K7 w4 k5 d3 G' W7 L: [D.什么都没有
* J* z) _9 F$ q7 n6 P0 K; i* D. _4 z+ o4 N4 h! Q% W. d
& R" a$ V  \6 t1 v% g

  i- X8 u$ P. X5 g2 _; C. O答案速查
" X& {. s1 _& ^& O: O1.类. g% w, M; E9 g2 t, b7 r
2.BCD
9 |- V9 \* K- }7 P7 b! S3.C3 s& {1 O5 c4 x! I" z" V! A
4.C
. O' C' P% J8 [0 D0 `7 n5.A
# o& a. \/ O7 `7 Q" B6.C
+ e5 t1 M$ D. g& q) _7.C0 g, r% _/ v; R* \3 z5 `
8.C
0 R! f, `# p' o/ |$ S/ [- }9.D
# Q5 ]: M1 Q  ^: |6 i4 r( E) A& @10.B
& Z, D5 c* h( O( Q- ?11.D
4 o9 b. `; D' F& p. a9 k  N12.B
& _) g: {! \" G+ ^# ?' I13.A: ]! o# y( z& C: ?
14.D" x  @! D- x* w6 y8 r
15.A2 a) g7 \" ^5 m' o! O" L
16.B8 K& e% E4 i  H6 k% |# s- g
17.A
7 y# {7 L- r* N& u3 _* O+ w18.D. R' U& B5 m+ r. r' N
19.设计模式
# G1 g& d: ]+ @6 r: k: S20.D' L$ D1 B" Y* |, K5 @

. u9 B$ ]& A4 F  I) Q' M
0 |7 Y: I6 P; L6 W2 n1 A, W
9 _/ d0 c9 m2 `答案详解8 o& D" u& b! d# G, }; ?8 B  F; L

) R# A& y; o) K5 _, ?1.类是对象的蓝图(对象是类的实例)。
1 R5 z: m. P& [8 `1 [% E3 k9 d8 l! Z  B
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! ~& o5 _: Q$ I9 W, R9 m

" L& m' Y, ]: s% W3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
7 X/ ~4 b$ X# U8 d' R  ?; R5 Z& W  U/ J
4.单件模式可以限制一个类被实例化的次数。
; e4 x- y* K. z( O" v0 W3 Y2 V2 f1 Q: @( y' e
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
3 w9 Z3 h; X  W! h, I' i$ j. N% [) e" j
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
$ f, b- }4 K2 |0 ?3 z) z$ l; n& T. A
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
: m& V+ }+ v: A. K# R
" o5 u' n3 \$ s. g- {! w8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
6 p' p+ g' X- c! _& C# m2 T, J6 m* {( ?; m# @! B% h
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。# l' Q7 n3 L  V1 e

7 @1 l; [5 F' ]* Z10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。: {+ d# m" ~) H! f# K
3 O  j, Y* y5 z& L- `
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。' Y4 b) f) A- `) z4 l2 t
& ~( T% u, o- C
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。8 ^. K% Z; P% _
6 M/ g8 S  h6 V2 V4 v! g: d$ t  {) O
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
1 X* z/ k: {; w
. X4 ~/ |0 F) ~. a2 a$ o14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
+ q' A/ q) y0 K; r/ }" C4 K1 P回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:6 X, B- ~) s, M6 }
    function reduce_fraction(&$fraction)
& E5 }3 `! P8 n- e& s7 N9 Z答案是D。6 O' k2 x& R; t

' ]& Y) C# s2 e5 ?2 p1 `15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
0 M! d' u: c0 V$ `! b$ h( y
. C6 R2 W% y/ V. f+ W/ j# n16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
5 D+ m, [5 O) }1 y9 d7 g- U8 I# D+ ?& U$ R& F9 o8 d; P
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。. M/ H/ E' O7 a  w
( M0 E% u0 n8 l+ D: G( g7 I
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 ^0 z: X, \; R: }4 C/ r. G, ?; M  v8 r7 x* X& }9 j
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。# s& m7 H5 R$ C- }
$ i$ U3 [3 ^7 |3 S8 {
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




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