返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
# A' C" _4 I8 C4 bPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。( E' D4 \! i7 y6 _9 X' R) j
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ b+ M* i( @3 w$ F5 \( i) j% c7 ~$ n8 G$ X. K, e) B" |/ L
问题
9 N( U: F  |+ ~3 l- ~0 N$ S# p8 u6 ]7 S% j* w2 ^+ m# C$ v
1.对象的蓝图是什么?
) x( f. g: v; c/ a  f2 ^1 L
3 }. f) F2 F9 N* y答案:____________8 P% C5 \  ^3 d1 s* m( y6 G

5 u: f: I3 A) y2 A2 K& l9 y7 G; j. }2 D- {7 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
2 z  f: k6 C: _) P; q" ZB.b
: q0 x1 y/ G& m( gC.a
3 a8 V/ }3 z& E6 `0 z6 M9 eD.d
7 B# K& Q, J* J( u+ |; k$ v% H* ]E.e# \& b: M7 Y; Y" e0 W! f5 Y# c2 ^

) c# ]4 a, g5 I0 P. c% g( C, P7 L7 \1 \% B* Y1 }7 i6 w/ N
3.如何让类中的某些方法无法在类的外部被访问?5 h& \% J3 r; H0 u* ^) _7 W2 P

# K: A6 H- s! }* M& x& H4 TA.把类声明为private
* U( [( Q& k( O% l" {! p# [* OB.把方法声明为private
) L" v; d! M$ d9 y6 H$ RC.无法实现( ]# `; y" U6 U# m
D.编写合适的重载方法(overloading method)5 M: q8 m' F  r. z: |
$ C! ]8 l& w  P: ~  W2 o# k* o! }# l
* I  q; P: g' H' S2 D' F9 U
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?8 h6 r. F# \) Q9 q$ r2 T8 m
2 R0 e9 p' u  D( M
A.MVC模式
! }' O/ b. q! N& V9 E! K. v" ~) oB.抽象工厂模式(Abstract factory)
8 Z# @) A: n- ^9 eC.单件模式(Singleton)* A' ?( Z. b$ E- O
D.代理模式(Proxy)
' _8 t2 H2 o( h2 y3 s2 f- P8 tE.状态模式(State)
" y; r$ [7 d" ~5 x+ `0 C1 f& N* L# L7 C) J6 J6 m

2 n8 I2 ~# m& [5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
; |6 t! j8 x% i9 K4 {' o9 S
/ P* G* V: M8 v: x% r8 |A.1个- n  h  C' d" F: I+ F( V/ \' X
B.2个
) T! ~# F# O% {C.取决于系统资源
( V! g* j: d# B6 M" a2 pD.3个
/ p$ M$ K( D# r! c* ~9 wE.想要几个有几个
6 V( e) }& L9 H' G( b$ [9 a% t& q, y# F) B3 B
) X; Z9 w3 L# w! N
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.多重继承
2 p( w9 F* l+ x3 R# r9 pB.接口4 I4 ^4 D; r. }% m# v# G+ G
C.抽象方法
/ p2 ^  r  X- f3 m0 HD.Private方法/ K" `  B9 l7 y
E.函数重载(function overloading)
- c' D9 M: o4 b- O5 L% E1 a+ Z0 Y2 u+ G0 f* t

* B! W7 `4 W* H- v7.假设定义了一个testclass类,它的构造函数的函数名是什么?
) R7 G2 W9 {$ r7 Z6 e6 t/ t7 E" z0 i6 r: L0 e
A.__construct9 w7 r6 B: g. H  r7 G
B.initialize. X4 a; V1 T  U3 D' t
C.testclass
( `! m& K5 c% h# oD.__testclass
+ q$ I; r+ I/ E3 Q" z. n3 {E.只有PHP5才支持构造函数
" D; }4 r0 E; M# y2 k; i0 A) ~; p4 N1 K4 Z. T
0 k& X' X) ]( j5 D  j8 l; ]
8.一个类如何覆盖默认的序列化机制?# t  S4 v. _5 }
$ c+ h. C" ]" v6 n
A.使用__shutdown和__startup方法* {2 u. _/ ?5 v# H
B.调用register_shutdown_function()函数0 @& G0 F  b$ I1 D' P, k, I
C.使用__sleep()和__wakeup()方法3 L5 X  j& g# J7 n* A% B
D.无法覆盖默认序列化机制
3 i" W) [1 E% C' c/ ^. [+ lE.使用ob_start()将类放入输出缓冲中
8 U4 r9 r, X3 F+ J
3 b2 T; r0 T1 \; a7 F- e: }$ _) \1 H, y, |. Z
9.以下哪些面向对象的概念无法在PHP4中实现?
7 m4 z+ _* N! [" @- z" k2 P" p/ r5 _8 S6 ^; f' E7 ^2 j1 e- S
@抽象类, `; ^8 Q& D2 P9 o
@Final类
$ h* ^% ^6 B; k) e$ p@Public、private、protected(PPP)方法+ M% E- V4 t: @
@接口6 P7 _% E' d: A1 C7 j

' `4 ]8 G: o$ fA.抽象类
$ ~% i7 A9 U) h2 Q0 o$ I0 ^' H% wB.PPP方法
& X  q, w0 r1 l* ^0 P' l% v5 TC.PPP方法和接口
) ?8 b1 P% ]' y+ g) b( CD.以上所有都不可用& i( `$ T" A  @& |8 B+ O
E.以上所有都可用; U) C4 N  [* a3 K. a

# R1 b" E' ^0 w' K5 B# \. m7 x/ v3 V8 N3 d
10.如何在类的内部调用mymethod方法?
4 w" t; V% }  A  v5 z* A" ]6 W" C  e1 i  N
A.$self=>mymethod();
6 t& T% M0 q( P- KB.$this->mymethod();: I4 u6 a( |6 G7 g' N" |) A
C.$current->mymethod();
3 V4 r* x6 p; v8 DD.$this::mymethod(). W* K% v2 k% |" s* l2 Z
E.以上都不对
  R( R5 @5 i0 q9 w4 c$ V1 O
( M1 m2 R$ H* S! |% ?/ f' s' b( P& F; D8 t
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
6 M: ]1 U( s! p7 c$ s6 g( {B.Null! Z/ y; P, E& t) e
C.Empty3 n% ?4 \: o; A. d. u
D.什么都没有
/ w/ y# Y/ I7 t4 e  F( hE.一个错误- u1 }: S2 l% u; H% ]- E
3 a8 v3 o- m+ r! F

; y. `" E/ b4 d, V4 V7 t/ ?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/ v  C1 ]: F/ Y' J; [/ q! d5 a  C
B.5
, S- K( q8 k. m% s9 q( EC.20 A! X) O( s, S+ k/ A& M7 @
D.Null
0 b- X& G/ e  c- ]E.什么都没有5 `# u' a: W' s9 l; p
% @( y4 k! b* m

- a0 N/ \8 K+ A0 ^6 C) T13.以下脚本输出什么?

  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" l! f9 m7 x8 V2 F
B.10
  x2 l* ^) R7 @% |0 V+ _C.什么都没有
$ a5 F  w, Q- r  }- pD.构造函数将报错
( ]9 z; r" p2 x: K* g/ WE.510
! d0 Z, B. t. C4 g: N/ i3 p' |9 G' n" a; b

( F! m8 z+ t  `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函数必须返回一个值
) _( k# b- J8 [9 K  _B.reduce_fraction函数必须接受一个整型值3 g2 \! q5 d5 c  t3 S
C.gcd函数有问题2 p+ Y5 p, R$ g
D.必须通过引用的方式传递$eight_tenths对象+ F% U6 M) g8 b) |6 {% X
E.对象的实例不能传递给方法以外的其他结构。9 d) W1 R, v+ ~: y( y0 a+ t/ A

0 i0 g, O6 e, w$ p
8 m3 L- e/ O8 s4 @/ i& K) o15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法% ^  U7 D2 s3 B2 n) Q$ L4 n
B.生成myclass的实例并调用mymethod方法/ }* _' e7 D6 {5 e
C.产生一个语法错误
% l9 s/ K. `1 i# I& }/ |D.默认myclass类最后被创建出的实例并调用mymethod()# x2 U9 a: k  h$ t' S, U( I0 m5 h# S/ @
E.调用名为myclass::mymethod()的函数# G# h* @0 Y: S

' q. C$ N' b' Q9 K$ v$ o* R# ?+ c# ^; E4 a0 C1 q$ g# O
16.PHP中有静态类变量吗?
2 c  q3 {$ u* V. o
0 `: J2 k8 y7 o" b9 sA.有
8 w( H1 G+ s3 H5 Y2 T/ C" E; N- bB.没有% S- D3 u  r5 ?1 v
( Z$ b; B7 E0 U

, |& b" M' B; e/ S1 ^3 }6 `# V17.以下脚本输出什么?

  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" E* j$ I" g* \( P2 d
B.2
/ Y2 y4 D/ i' f. vC.一个错误,因为没有定义a::$myvar
2 V0 z5 e1 t+ U: VD.一个警告,因为没有定义a::$myvar" D- K% l% i8 J7 M
E.什么都没有! `3 o; f0 E4 ?! z

- z) ~* l, {5 L7 A8 w5 E; x5 w# a! h4 p/ s* H) e
18.如何即时加载一个类?8 K+ i5 V) m% I; r7 y- ]- h

) e- C$ S# r9 A- }$ jA.使用__autoload魔术函数
. d" J7 d1 {; X& K0 s/ q9 \B.把它们定义为forward类* }: U" r, _; W7 z
C.实现一个特殊的错误处理手段' \& j/ M9 i% y5 z7 E5 |2 b0 u
D.不可能! l6 Q. v" z. q, g* |( F& k
E.用有条件限制的include来包含它们
, f% D- V- e0 L' w! D3 G3 v
+ X  m. a2 Z3 p' O: G! L0 R& G
9 I) v" O+ b4 n$ H* |1 e' c19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
+ |3 `7 O, b- \( o% }1 ?
% @% {1 m4 S1 ?& w6 W" S. w    答案:__________
. m& J3 v6 k& ^- b
) b- u4 Y1 [7 P: N! T8 y3 l1 m/ ?' @$ v+ l& _' P, Q
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! F* Y5 D6 ]$ j
B.一个错误
. J  a" @+ P! {8 t1 E  w4 ^% xC.一个警告
. I' f7 ^+ D3 D$ ], n: y: U, FD.什么都没有: m; p  v# p; W/ d8 z& N4 _
' G% O0 j3 S0 ?" D9 m

+ h. g2 O& p* R& U; J3 e8 R
8 F( o1 d) ]+ x% V- R5 C0 |答案速查! V. G9 e% [; N$ R6 ]. n) o! n
1.类+ e" Y1 d8 {' j% A; |4 o* _: `) W
2.BCD
+ Q3 U3 Y; H% M# u8 @: A3.C
; V( [) F1 s5 X( J4.C
7 j% @( r7 H/ a( Q5.A# |  l6 Y. q7 L+ z7 b: r7 H) D
6.C
# Y+ p; q6 ]( E6 z' L7.C
  h7 Y6 G+ S2 c1 D' ^8.C( v" ~2 ^  [8 B. L; ]. a
9.D
  \; y, c$ ]" E& n$ i10.B
4 H5 j( l2 q7 G( J; h0 ~11.D
5 t, j* n) x# ~. C12.B7 k8 ?, n6 y2 D$ Q' M" ]
13.A
- @, [/ C9 s' u3 z6 F; b14.D* z# G# U0 H5 r; B- h( W3 M
15.A4 W# b5 b5 {5 [, {' ^1 f0 H: |# {
16.B) C" y" ]0 r/ U+ ^
17.A- d: ^  a/ ]5 Y7 E
18.D" }, r1 I1 H- X* H, E& E+ l
19.设计模式( ^3 w+ T# U3 `3 v" |4 n
20.D/ _9 ]& Z" V% r3 P) \
& ^5 g! T6 y0 B! ~$ l1 l% z# Y9 t
" F+ C% @+ Z2 X+ \. U0 M
; M: O" S8 d. ?+ }
答案详解  r" I$ d) J; @9 t) \5 K! R8 l
1 {+ E: U5 w5 K. h. P
1.类是对象的蓝图(对象是类的实例)。6 i! I0 z7 s  R
  Q8 X+ [" a( b6 K( H# d+ u) l
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
* r1 U" S9 c3 W1 K) o
, o2 D$ ]' P! `; }$ W/ y: ]! h3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。" x+ o, z  ?6 S% N9 C

/ m! A' @9 {  r; B4.单件模式可以限制一个类被实例化的次数。- K7 R- o  i8 t7 k/ J1 D
- M! i( ~- X8 V7 ^
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。* ^* ^& ]: ~% A  V0 _% o2 w

4 v5 C2 h4 x/ y! A6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。5 C' i6 a& _. \  e( T/ P% W% f3 s
' \! }  ~, x  N8 z- Y! D# u+ p
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。1 C3 _. [" s+ s8 ]
1 L2 z" N* C: j7 B0 h3 I
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。1 d2 A' x7 f6 p0 h
+ R7 n5 q+ C1 ^: ^9 Q( B* g: }
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
9 ?- l3 u) w( y  k! \- i* o( R2 w5 `/ @1 Z: a
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。7 G/ i. K! R/ ]$ t0 X

  O; y: M' }$ j& k11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。. r3 p; v4 \& [1 \% u) S
- E" q- L: g. v, _+ ^
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- w% L+ _" W+ m6 l! |
7 ]  i& L7 U# R% h
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。& F# M* D1 T" ]3 U
3 c- {) p5 U5 z2 {
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
$ u* U+ [/ D0 F4 S* @) m回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:: V/ D9 d1 n# B9 J! u
    function reduce_fraction(&$fraction)* C1 C9 _2 V1 t) c( ?" `3 S  N' j
答案是D。
8 s$ s5 h: u; U& i$ Q) k9 ]: X( d
& Q8 _, ?/ a. h3 W; R15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ m6 R3 t5 f2 Y2 O0 U
' S( W6 n3 H' p* ]" B
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。; {- C2 C* M! ?9 J/ j' O

3 P9 s1 v$ ~9 z: E+ |  d5 t17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。4 g# q; |2 E6 i6 P' X; q' g
6 q6 q1 G% O7 }$ T* e
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。. d( Z/ f; @' p
; F* g9 T: m; a0 m
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。8 l+ [8 c# l/ n+ F- O
3 _1 B; O$ A0 j: |  o
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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