返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
5 I7 e" `0 R6 R  C, z& lPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
# _1 A/ [( I' D/ m& s0 B' u本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。8 x) x7 `7 e3 Z8 k

2 x0 T% M/ G6 a, l问题  m3 l7 P, P* n* W& R$ E; k

* Y  F: Z  {! f: o/ Q) P2 X3 U5 S5 w! J1.对象的蓝图是什么?: d% E! r1 u; G' q7 i; L7 F5 |

& a9 _" v8 I' o. ^, ~( x0 g, U1 f- s答案:____________
" c( ^5 a$ S" n0 N+ y6 @- D& E0 V* S; |( U" S
7 y# X& A5 H/ c' f! @& g4 n3 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.c
2 Y, x  h% a) zB.b9 t8 m- A3 ~. `7 J" f8 o
C.a; n3 k* D$ ~6 f0 w' c
D.d: p& ?! B: i* K" J
E.e
* |, N! C/ V: V& A5 b  ]; U: T
# m* |9 O1 ^7 }0 P, h! K0 b% N
0 K' @1 l+ j, w: `# L3.如何让类中的某些方法无法在类的外部被访问?' x' B. P, ~* _7 U  i3 F; `9 t5 Y

  [1 F/ o- F  t3 @9 AA.把类声明为private
  B, i4 H+ u* i8 K/ G: V+ m% n, kB.把方法声明为private
4 @# N3 z# `9 V3 ~2 yC.无法实现
# `# s# }7 b4 fD.编写合适的重载方法(overloading method)$ L% u9 Z" R! d8 Y* Q
- Y2 h) s6 D  M% E

- ^1 u2 z1 V) r; d$ p+ p' o4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
  }* ^/ w, N# j# [1 i
' G7 O9 t* U6 U8 e# t; w( }1 xA.MVC模式0 q+ f; Z, }0 a0 l! X
B.抽象工厂模式(Abstract factory)
7 i6 U  I6 h# H9 h3 L# Y, k0 _. |+ YC.单件模式(Singleton)
, l9 N. Q" N8 t' `- h! {- F4 y! nD.代理模式(Proxy)
  l& H) R+ \) Q8 oE.状态模式(State)
5 j4 m# I8 g) i( H, t( o* Z& ~) F$ U- G3 U! d
) Q  [/ d  G8 s$ v8 z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?2 h% z6 K7 C7 d1 U0 e' N; h
) E0 M5 M1 D3 t7 E$ r& f4 A
A.1个
1 m; R8 I3 b6 r9 x% s# }B.2个
% g' S' ]# K0 O; y1 p) ]C.取决于系统资源
7 h- e/ V' S7 [, x; v' [& \2 ND.3个" N; T" }3 c9 c9 D* s- ^; O8 H( y
E.想要几个有几个0 q# x2 G( P3 v6 ]
4 p) ]" Z4 f" u$ ^7 b
) _/ j1 [+ G8 _  a
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.多重继承/ u7 O4 Q, D9 k: p; z
B.接口
8 |% \% G( }. \/ y1 n( O/ yC.抽象方法4 K4 t6 G+ D% Q% A
D.Private方法
: ^/ }% G3 [% O: xE.函数重载(function overloading), ?. @* e, A$ N2 g* \

! |, W1 o+ }. c5 w
1 |3 C' Z9 M0 `7.假设定义了一个testclass类,它的构造函数的函数名是什么?1 |2 n" z5 s+ \$ s$ k# P; P
5 j1 ]& d% }: s& y
A.__construct
. e7 o: A2 `  |4 DB.initialize9 |9 h$ e: |7 u6 Z" z7 ~! r( o/ q
C.testclass
6 u0 h" P2 a( \, H# E+ g: ^D.__testclass7 H  o! Y  y. X8 c! [4 Y
E.只有PHP5才支持构造函数0 W8 P7 p2 I5 s& d

6 ?0 F4 R6 ]# D! W
1 t' k( W6 Q$ C7 L1 ^2 R8.一个类如何覆盖默认的序列化机制?
2 X  o( a7 u4 s2 S( J6 ]7 j! W% ~) y2 U
A.使用__shutdown和__startup方法0 M& b. E4 E9 B  I
B.调用register_shutdown_function()函数
: D% i3 K" ?. J% mC.使用__sleep()和__wakeup()方法
2 U: `4 K1 G: L) G' C3 kD.无法覆盖默认序列化机制% b2 H" v$ k. Y# K
E.使用ob_start()将类放入输出缓冲中
3 Y$ O0 p' w( M8 X9 Z4 o
6 r- q' {' c& E4 S6 q! s$ D' C- |2 A9 s: C/ n5 I( q7 c* G
9.以下哪些面向对象的概念无法在PHP4中实现?8 S9 D$ o4 F. X

1 M/ [# T4 [2 r5 e@抽象类
9 z. l% A# _* d8 o/ b@Final类
/ |; o8 C+ e0 f@Public、private、protected(PPP)方法+ o, R. f3 q3 w, N
@接口
* j. K# U& O  R5 Y  x3 c/ O3 p+ ]* I3 p/ V
A.抽象类/ [3 _5 l. ^5 y4 b- v. |% j5 O
B.PPP方法
7 K: @9 v- j" {8 i% S2 jC.PPP方法和接口0 N: `. a- c. q) ^
D.以上所有都不可用  l  W: f5 Q( S, M9 Y. t. o; i9 y
E.以上所有都可用# ~- b; u4 i3 @& Z. A& j. g5 N
! q- v8 Q/ u8 k( @, f

% \& @0 V$ s% d: {10.如何在类的内部调用mymethod方法?8 B6 k0 r$ R9 h8 B+ j) A  \& J

5 z6 @6 `9 T3 @5 SA.$self=>mymethod();: T: Z5 p5 @7 R- {' {
B.$this->mymethod();. ?- B/ \6 s- h3 b0 J) K
C.$current->mymethod();
5 C" _% J0 ?; Z7 j# A  `: ]9 q# {; jD.$this::mymethod()
  p& m: S% V9 E; L+ c  HE.以上都不对
0 m7 r& p  [8 Z  P' g; x
- [4 F) w3 V5 C* G
9 @5 ~9 y9 u5 K  \1 e/ M11.以下脚本输出什么?

  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
5 I, |4 k& l7 V/ ~2 n' FB.Null
' D. q! O$ d5 o0 c$ eC.Empty
$ x0 M$ [/ {/ K$ _D.什么都没有
8 ^; q) g) K1 \9 g! [; S1 S2 @3 UE.一个错误
# @+ @, s4 ^* G' S, Q- v3 s
8 e# T! {1 I2 a  o* c  L% Y, M$ @5 b& ]$ L* E8 O% [) f: _
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
8 Y9 h4 F2 D1 WB.5
- |; K  G- h$ S: r; _  l) YC.2; Q( r+ m7 {' X* [/ V* e9 @
D.Null0 G3 p. Y( w# |7 ^4 M
E.什么都没有; y* k0 d8 z/ i* x6 B" n4 N3 A

2 ^& l( ~5 i' U9 ]- h$ @
; I* l" Y* t0 N( X: c/ j  @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
3 W/ {! |# y& Q* @3 h. `! S# SB.10- j' Q# n4 y0 g' V2 C+ R4 _3 e
C.什么都没有
  b+ d2 M* D' a- G* UD.构造函数将报错' K0 q9 I- `: D: q; A4 Z
E.510
3 b1 e5 m5 E" s& B8 x" i' m% X, {2 Y* L; B) ]! O

" ^! U, ]  b0 r& q! A+ Y/ G$ w14.考虑如下一段代码,执行时,$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函数必须返回一个值
1 p+ a" H3 {& z( ]( NB.reduce_fraction函数必须接受一个整型值% ^8 Z& S& J6 J. d6 C
C.gcd函数有问题
3 J7 f: r$ b' a- ^2 ?% w7 pD.必须通过引用的方式传递$eight_tenths对象2 n; C+ {: E1 g  y5 _  M
E.对象的实例不能传递给方法以外的其他结构。
' R8 `9 H  w. p3 ~4 f6 j  t+ Q% f# H0 A* C! A
5 o$ f$ c, j! _/ K
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法# q4 J9 k( U* I8 T  g# P
B.生成myclass的实例并调用mymethod方法8 |. \: c0 l5 \) D
C.产生一个语法错误) g" k3 R- n2 Z' P
D.默认myclass类最后被创建出的实例并调用mymethod()
/ [+ A* ^& T8 R. yE.调用名为myclass::mymethod()的函数# Q2 F8 O% c7 g) q8 @8 J1 K; w( X
/ o, T+ x5 `7 x* l- s) S/ G
2 `, o2 u4 `& L: @" I6 u9 {7 H4 ?
16.PHP中有静态类变量吗?
% e! }" s, r, S5 K! K. w0 D+ Z$ i) g+ C0 ]/ m( n
A.有; _7 [/ s" ?6 C; u; L7 D1 h9 k
B.没有6 }: `# c% x% T  F: I% p- J' E& O

/ n( Y. |9 ]0 R! _* p8 p- Z
9 g# T, y: T8 V/ x8 h17.以下脚本输出什么?

  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
$ y( u$ k6 o- ~  XB.22 }9 k9 N0 x+ m6 e5 g  v" z
C.一个错误,因为没有定义a::$myvar
9 L- K( v# ]& Y1 u5 Q" CD.一个警告,因为没有定义a::$myvar6 Q- \! |, C: C' `
E.什么都没有
2 G! f! T  X" r- G0 J9 a2 |3 G- {- \2 J, Q" D# t

0 Y2 E5 W- x  o18.如何即时加载一个类?5 o. t" @- y3 [" b

2 e: }+ i; |6 v# ]9 hA.使用__autoload魔术函数$ @% W9 [. r  f0 c. E
B.把它们定义为forward类- Y- L' c9 H/ S2 s( W- U; h
C.实现一个特殊的错误处理手段$ N  u2 p& v- r! n
D.不可能& ~# b1 o8 k8 O0 F
E.用有条件限制的include来包含它们
6 g, O+ W# X: {, N
% B* U' p! q) o
+ ~3 Q6 `9 Z; ?" q6 N; D' G8 |19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?5 e7 \" `% f! b8 l

9 ]' J. Z7 J" D3 H0 \% [' \    答案:__________% `! b% M8 E; A4 K' M+ ]
" F; r2 y! p+ [2 i9 m2 [
% A' T' _' h' a7 X
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- h( L' K" l# x# `5 A: R
B.一个错误
+ v. D* Q: M% {1 `9 QC.一个警告  l' @* J& E( |+ ~; A
D.什么都没有
9 E  T% Z* H( G, x9 x
" x; o3 Z$ v) v. f
$ C  V! C) `/ x/ Z1 @  c6 k0 [1 p
' N" W& a8 Q# W' Q答案速查
9 x9 i: q' k; I7 m/ K8 O1.类, d3 e, J4 x& h5 _( w: z# p6 V/ p
2.BCD
; }) e0 M0 R7 C' A; K, _3.C; \7 |' m) Q% m* Z  I
4.C. \6 b0 v3 x: c
5.A
+ B6 j8 [9 Q$ q0 R2 E6.C  F0 e+ Y9 k" E/ K( b  k
7.C. z3 z3 r0 e  D. A* S
8.C
9 S( f1 p1 O0 `# p9 B9.D$ N' P1 _7 O$ g% X1 C
10.B' j, D- K/ I# v
11.D
' u5 K. W% D8 a5 y" t4 _12.B
* e6 G6 I/ Y3 y13.A; a& f; ^4 n, w
14.D" f- L" a: j$ s8 h
15.A
4 a- F9 N! u, ]! p) m& b6 \  P16.B
6 I2 S8 }" m* d. n; p17.A# C8 k0 M. y$ ~" L. ^
18.D
6 @  ~. y) S' z2 R  R5 V: U# W19.设计模式7 d2 g( n+ q8 _
20.D
7 o! Z% Z! V  c" F' B! U, {! V
+ G! a( ?+ o; a: a! V; C' I4 L; c, c
3 A5 b) X9 c- o$ H
答案详解
3 U3 @6 i& z, J, Q8 e! D$ X; v  \' @! j5 \6 q
1.类是对象的蓝图(对象是类的实例)。5 ^: \- e6 w4 P8 Q3 G

, [, z  @% o, @7 s* F2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
* n1 N8 W# N( Y; D" s" o' ?' s
+ R0 \" c$ k: d' @* m3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。) P/ \& V0 A& X) u6 |; `  ?! T9 k
" F& Y7 P% _" g9 N( f. ]; ^
4.单件模式可以限制一个类被实例化的次数。
/ i: T. ?; x4 o% I& b6 w) I' Q9 O- C, N0 D8 s8 r% A/ y1 V+ i
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
( f3 P$ h0 E% p3 o1 H
5 T( B8 g6 N& X, v6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
5 R, p  e  [, i6 ?4 ~8 ?! z5 K/ Y# g- p3 \4 C2 r' X
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。& P8 I% t8 G* @% W& f
: r7 X4 \9 O4 M  O6 K8 J& [! a9 S
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. b- p4 `* C/ k
2 y! v' f+ O: m4 d$ x
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。2 P7 T# F9 k4 o/ d" {) Y+ t

! X$ l& k" J2 X& Y" D10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。; S% }8 B5 H' [. y4 m

% j% e& I' q1 |7 {) K3 k11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。& {( q* l" o3 |# v9 h

1 f9 E8 T% e4 D% M5 j% u6 u+ }12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。' R& Y5 |+ _: g
0 G) ~/ m# E8 T
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。, C9 w# t5 y  q& K

" v0 a/ \1 G% e7 z! J: q  @14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。2 l: f, q; p9 X# _0 d
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:$ ~. c/ h! F4 q. `* M4 c
    function reduce_fraction(&$fraction); L) R' Q5 P- C
答案是D。
6 x. Q8 [1 a  u$ G( q
& o* K3 R: [  ?( _7 X! a15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
1 R& N. I0 W( w( C) ~7 R# q8 [6 g- f
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
7 C2 ^5 ~# W7 L" y; A: ]
1 g- ]* k2 k/ a6 Z17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。9 F2 z. H. t2 R' b" j& y" \. [
3 Z3 k0 m8 e5 j  ~/ H; S! X
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。' |9 h" v- ^$ n2 k; U, e

9 R7 [" D# a  K) Q' V4 T  |, L19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
: y/ Y  V/ x" A7 e% _1 U- G' G
6 P; n6 ~. N! s. E, E% L* t4 I! q20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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