返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
3 n5 c9 s! S; @: g( ]PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
; d* t1 @' m' K+ {本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。9 ~2 c& F% p& E

* ]* Q- \- M  O% w9 J' R" y问题9 F. |. ]) i- i2 I5 m

5 L9 D9 Z; q* h7 {1.对象的蓝图是什么?, j  _* x+ Z5 ?9 J
$ s/ V& @; j9 s  e% B
答案:____________
5 `! D/ r$ Z3 t
, r( Q& \1 D5 i) V  g6 e9 m+ j+ h2 C; p. N( o' O
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$ n* D5 R& q% c  ^1 \. X6 [
B.b! `9 _& B9 b  E9 U1 [4 o  ?- D2 H
C.a8 F! [9 h6 T8 W- {
D.d* d2 v9 c" l, N" p! L; I, p
E.e
$ }0 X+ N- L/ c1 o3 Z& n2 |+ \5 Y8 l# }# e* T0 m( k, O

. ~7 J' W; C( J" ?6 z8 D# R3.如何让类中的某些方法无法在类的外部被访问?
. t3 V2 }% m4 ~7 m9 h& p
. A2 x, t' i, X: ~/ tA.把类声明为private# R  U6 ~& ~# b! A! n' m
B.把方法声明为private
  ]2 i, N+ t* v9 a5 bC.无法实现. N8 t0 t1 [& G% J. B0 T" q6 k! x! A
D.编写合适的重载方法(overloading method)
/ v7 [- f1 k" u& ]" E# [3 A9 K9 s0 _

' p) D0 d8 B& p: \4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
( Z0 D' U. x* j0 ]6 }/ M
, I; m2 G; P5 [: bA.MVC模式0 p& q4 L) H0 {3 h* @
B.抽象工厂模式(Abstract factory). k  M( B3 `; X3 U: p. x
C.单件模式(Singleton)
; l- j. A0 s1 I, BD.代理模式(Proxy)
% f3 H. G7 v' _+ Z- d& C/ jE.状态模式(State)* @! ?# \. Q" O7 x' c

% A+ I6 E% V$ N9 F  O' _0 v+ V) L$ o0 Y% V3 V
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?3 i' {* b( `9 h+ ?) Y
/ K4 w0 A0 f$ v* E+ E( ^
A.1个
3 B: x. _: [# v/ Z% J# MB.2个9 a1 l/ f/ H. ~. g# C
C.取决于系统资源7 ~: P3 p' P5 \
D.3个
! I  g. R4 _- B: y: j1 E. qE.想要几个有几个7 J5 T- D8 L3 Q7 L8 S8 B3 ~3 r

8 \' S  _8 M6 |  K3 Z
+ o  ^: X" L8 q6 O8 P5 E# i* Y6.以下脚本近似的表示了一种在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.多重继承
( z: V6 p& N5 X: C- z/ l4 `B.接口1 w% [8 U0 G, ?* `
C.抽象方法- O' z  h. X; T- d" B" _
D.Private方法
7 s5 v4 s0 v1 I7 ~, eE.函数重载(function overloading)
+ P7 b6 _' d9 d0 m" H/ U" h! U7 T# F% P8 D/ B! t6 G

9 x( @5 S5 x$ g6 m, q5 o7.假设定义了一个testclass类,它的构造函数的函数名是什么?. _2 U' s3 k6 s8 s' q; z

) F$ Q" R3 A  Q; R$ ~A.__construct) e0 M& {+ ?4 z- ]
B.initialize3 p/ U5 W- A' f, t
C.testclass! @) ^6 Z. r- g0 {% w: H
D.__testclass
) e/ N6 X1 ]1 GE.只有PHP5才支持构造函数
; P0 P& L0 ?5 a! ^- G5 {, n0 n/ c: p8 m8 a3 u
) e; Y; B, o6 V7 s) |% R
8.一个类如何覆盖默认的序列化机制?
* V$ {2 F& f& B" V. z
# ^5 G5 f" B9 s  a% qA.使用__shutdown和__startup方法0 h) g6 G* l3 X# s7 ^6 {4 N
B.调用register_shutdown_function()函数
, _+ ~9 [0 d* B" K2 n! OC.使用__sleep()和__wakeup()方法
0 e$ S- q  S. \( B* j6 ]D.无法覆盖默认序列化机制
0 k9 s6 s: V- o) y, O  H0 BE.使用ob_start()将类放入输出缓冲中8 D; d6 U* }* D. U0 A4 D
0 m# X9 H' \0 T
4 D7 |$ N, b* o! R8 ]
9.以下哪些面向对象的概念无法在PHP4中实现?
- I% e! W5 m7 k- M
4 f( X9 e& O- w9 [, W3 L0 j, V- j@抽象类
$ e) I, f7 Q/ r6 D@Final类! b4 T% z8 `# I2 l7 N& P$ H. T! u
@Public、private、protected(PPP)方法
+ y- c- O+ \! A@接口
% B6 A' V! k# ^8 F3 N+ n  |/ R4 e+ |9 m0 o$ \% d, M
A.抽象类
0 h# e9 c) f# }, Q8 xB.PPP方法! R9 a7 X! x* r1 P
C.PPP方法和接口
% F, b% ~- Y' U' C: RD.以上所有都不可用' V6 y: l$ L; N2 P
E.以上所有都可用
8 {1 U! ]: j5 F  K; \0 m% w! q% v( n( [* t6 }0 {# k

- S% T  ?* V1 ?& O10.如何在类的内部调用mymethod方法?
' D/ W/ B, V3 |8 O+ N7 z/ I% L$ Q8 Z! F) \2 i' u) t/ T& d* Y
A.$self=>mymethod();# D& b4 N' ?3 w3 {; P/ N
B.$this->mymethod();6 x2 V. @. U5 W6 V! U2 n
C.$current->mymethod();5 V* M- F. i; z; j9 O$ P7 J
D.$this::mymethod()
' m2 g  x- Q' h' |5 U" [E.以上都不对
3 c# `2 {- x+ h' q6 j
3 i3 H& y  ]7 W& L" y0 I: V5 M3 ?) ?+ b, w
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
$ Y& R, l1 O( k# e; y" t6 `B.Null. _! s! ~' b, C7 a1 {# }
C.Empty
& S4 Z: A% F5 [$ ND.什么都没有2 c# Z8 g7 M$ G( k; W
E.一个错误
# D- J9 J" j6 d/ m
/ Q" D* Z' O! Y, b4 N9 V3 h
$ p) ]1 ~& `# G$ E12.以下脚本输出什么?

  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
9 i6 H8 y" w& [/ JB.5: E# h9 G9 J/ z# m' m
C.22 o" m1 d( L; Q$ H5 h5 z
D.Null0 D  H2 h, m  G6 T
E.什么都没有
5 F/ f2 i8 _/ B. _) ]& v, J6 n
( H7 W8 g( g2 j; P9 J! T1 n! l( I) c& A2 ~6 Q; ^
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* e; w/ D9 ~1 y; }* @3 l9 T4 [
B.102 e5 a. B) {, ~0 c$ q/ C. P# W* v9 Q
C.什么都没有
# i; G6 g% F6 @% ?8 h/ VD.构造函数将报错5 z: _2 I% \0 ]$ h9 i( N% C, e
E.510; Y, Z0 t4 K* h
4 g* d6 d3 m' T$ f
9 d* W6 }! R# c" m' N0 E2 Y0 A
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函数必须返回一个值- g( x; m% l& x0 e. ]: v
B.reduce_fraction函数必须接受一个整型值8 N  J( O& \1 V8 i6 a5 F
C.gcd函数有问题+ G. [; ?3 b5 j5 U4 l
D.必须通过引用的方式传递$eight_tenths对象
) c0 v% X# C- V4 |" w. yE.对象的实例不能传递给方法以外的其他结构。  T9 S0 h0 g3 w1 I
' ]1 N& o& a  @7 c, p& I5 P

+ d0 T' ]7 Z; t: O15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法% Q$ Q: a5 W, Z0 H6 T$ e
B.生成myclass的实例并调用mymethod方法; R0 D' g% x" G$ b9 n# W; Q: T
C.产生一个语法错误
  |5 V* ^  U: l$ \# Y2 OD.默认myclass类最后被创建出的实例并调用mymethod()
" x+ A  q  N. L1 d* x0 [& xE.调用名为myclass::mymethod()的函数
3 E; l$ U5 E- E$ s/ \
4 u" [2 U/ s. h; S' {9 A+ \
% _1 |: [# J9 Z' b) `/ M7 F16.PHP中有静态类变量吗?
$ \- w' A, \4 n* E) E- @# ?& ~7 b: m; }
A.有
' s: Z, Z4 N/ k' ~B.没有, ]( _3 ]$ ]6 T* r3 t
* q7 m5 L( i3 i7 F

; u) H$ k5 e8 h" t. W' F( G0 R17.以下脚本输出什么?

  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.19 q; o" R/ B% D) ], p- x" q
B.2
# n& ?/ e  f% uC.一个错误,因为没有定义a::$myvar
. X  n' u; `* r8 D- U' l2 {8 ?D.一个警告,因为没有定义a::$myvar
, \9 u7 I0 D  E/ EE.什么都没有8 o( I0 ]8 X) q7 X; a! A( o; B

) o9 G3 }, [% s# j1 V4 Z7 Z
+ B/ g. t8 z, V; M$ b18.如何即时加载一个类?" S3 [/ v7 |5 p- T1 m

1 r) g6 B3 \* O: g* P  c. ?& w( G6 LA.使用__autoload魔术函数$ `& Y+ n% g5 m% Q
B.把它们定义为forward类" K  O- {' O  }
C.实现一个特殊的错误处理手段, v5 u$ W6 s2 M% \* C, F: c
D.不可能! f& h# X0 K. M$ K# X
E.用有条件限制的include来包含它们
) S  |! V" D3 N1 q
+ ^$ r7 I- {( Y7 F
7 O* U! B( R8 W- ]: B19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
" p6 u( r# O% v& P/ H( s( C3 z, N9 j; l
    答案:__________$ A% d  m  e! q; U

7 G$ e9 A4 _6 d4 Y: [
/ G' ]/ p2 `6 a0 G. A20.以下脚本输出什么?

  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. W, c; C$ S6 P+ D2 V0 F
B.一个错误
" n0 `7 E8 ]; ]+ Z+ @& w; w& SC.一个警告
/ X  J( D+ Q* g5 \$ sD.什么都没有0 H! u9 @& l% c0 }- y' Y. l7 E5 G

( x2 d( K* ^" C: S
; a. w  u+ J& w9 y* H$ t3 k
; h& Y) l. P) A- d" u2 s答案速查
9 K, O( F" u! r. j+ l# \8 R  T1.类# J% s8 c) C: V/ A
2.BCD6 t- u2 a2 M1 s7 r* U/ k
3.C
& k% S6 ~; L' N2 x# Y4.C
- i/ d7 w  F. I. X5.A
8 C' P. \" b" D: L  A6.C
0 R3 P1 X/ ~/ v2 |1 U7.C* A  o) x3 ?5 s+ D
8.C9 o1 Z" k) U* `% e, c! g
9.D
' v% t8 Q5 ~& n1 p& r10.B5 T8 j" V, s+ C+ @9 Z
11.D
6 E; u& c& B& Z, R, _12.B' \* I& j# a% T; I: V, p
13.A
! Z9 ?) Y  f: \- a# l% H5 V# |14.D
$ e4 U3 V! m+ F. e15.A" K5 h8 u& F+ P8 `6 z  N
16.B- a$ \. ~7 U2 z
17.A# X' f6 D( ]# M& {% P3 f
18.D( r& @  x) @3 ]' X- ]* H
19.设计模式* S/ M3 U2 z7 t8 n' _# U
20.D
. a* I8 F- q) Q5 y% @  Z3 M
( }" m. J$ y5 j6 M- q( Y, [  ~* I7 v) D4 g7 [4 b

  p1 b" |( P7 Z答案详解5 W/ |* ?4 R0 ?* f4 a
* X4 ]# T3 c1 j/ c, D
1.类是对象的蓝图(对象是类的实例)。
, s, ?. C9 `/ i  t; ^$ Y- A# }% }$ M; a# N. D% [. g
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。; P9 P$ m& U$ I' v- X& f$ m
) }$ f" @" s! k# X+ T
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
+ M" Z9 \1 P6 V5 B* F! R# Y
& ?4 s3 G* u8 ^- o/ j4.单件模式可以限制一个类被实例化的次数。
1 q1 p/ |$ A  K/ R& k5 m
3 S" r6 K' l, Y+ `+ e+ ?# M5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。$ r0 D' I, n. u: P5 f9 r. S

6 c% \' m& i" ?$ @7 {1 W6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
* E/ t/ o' K3 A/ E2 H4 f( h
1 y: y: g$ G/ C7 l* |/ z' E" c7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% t- h+ M) b6 c8 ?: b3 T3 d& W

% e2 U( Z$ @( Y2 w- n; ?0 Q8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。& }" [% g* b/ L3 S8 p( m# F

) |# k3 g. A( f9 ~0 k- n9.PHP4中没有题目选项里所列的任何一个概念。答案是D。' w! i) `3 U' u

' x/ ^6 P3 b; Z7 X' B, z" s! \10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
% t5 ^+ d% C9 J
0 e7 m+ ^( @  V) F7 x4 {, H11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。" |8 O# ^1 y8 U& s, {
1 f- y1 z; k9 y; O
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。$ V) S9 f. X* q+ {
" ~3 W* Q/ W4 L% R" h% V, m
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
4 c: Z' A" ^6 L, F! C9 j0 N; o. b" z8 h0 w, v: p
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
% P$ M9 Y  P# w% z+ u回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
0 {& K- A5 r* ^9 d' E7 O    function reduce_fraction(&$fraction)+ z# Q6 y9 Z6 i/ `& |. j, R) ?- ?
答案是D。! r( Y& ~" H5 E
* W3 T1 H# ~5 x; c' }% _" J
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 k, X3 w4 Q) R+ t4 R% @3 @7 R0 _' p& r' O, P' g  _, u
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。- Z5 q5 S# W5 @) t# k
& C1 K; u' a. I- o4 s8 y4 X
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
  P, W- c7 A. z  V8 @
* k. T' C' w% Q2 P3 a18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。) {# x1 n9 U" V1 |

6 u, L$ U% B6 G- G& ~+ n& o19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
7 P; v' _! Z, _- ~. y9 u$ `# a
6 O( @% ]2 k7 w8 ^# L20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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