获得本站免费赞助空间请点这里
返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
+ a# v5 N2 Z  B. b9 s" x8 jPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
% _2 a) o" N; X* ]+ I本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。6 Y! X8 `+ M) `, U3 I
- u" x# N% d  [3 w
问题
  @, Q: ~, M% @% J4 @: ^5 y6 E" e+ T5 L* r  g7 ~; ?! z/ o
1.对象的蓝图是什么?- C5 a5 `3 Y/ G6 \0 y

& }$ t3 j$ L* M$ ]) m答案:____________4 r3 f9 V) ^$ W. L
' o! p, g* G! O* @
; m2 L7 U. P1 b. S* ?
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
: \; B. C; T. l% D! e) EB.b
' V' u7 v1 s- @, j/ [+ }# L& |C.a, X, T6 e* R- h# O- D% p7 I$ T
D.d) h$ E; A0 u1 S0 L
E.e
  O" X: I: v$ L1 }! p1 Z9 E  G8 J- c

, ^" w; {1 z2 e- t/ X2 b, g3.如何让类中的某些方法无法在类的外部被访问?
) C' u+ a% i; [! [# j6 {$ s  l( I! p4 E
A.把类声明为private( e/ V  u7 {6 x+ ]  C% F! ~
B.把方法声明为private
# q$ X* g( q! R& E7 @- A/ wC.无法实现
+ a6 s6 c* W1 e0 d: D8 R. m& nD.编写合适的重载方法(overloading method)
' l; h1 i' b% ^2 G
7 `7 N+ x( r5 `% }. S
* b+ H4 K/ o" h4.哪种OOP设计模式能让类在整个脚本里只实例化一次?+ s7 M# d+ M  h( ^  R1 m

& a7 B& @( t1 ^! j& ]A.MVC模式- t& W; A2 H7 s8 d! n2 G8 A7 R
B.抽象工厂模式(Abstract factory)
/ W1 h5 Y( O" l, o; AC.单件模式(Singleton)/ m- e; \9 r2 j6 ~( J0 L6 H
D.代理模式(Proxy)
& r3 I( B& }/ x/ j8 FE.状态模式(State)9 B, i, ^0 W( n5 X/ D

9 f' y, K% {8 F/ F8 F- L1 D7 n: g# |' _6 I
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?' q4 H% H# A- P- P. K( a- l

1 e0 g2 e6 _4 \* EA.1个
. a: k& ~- @; D; a* V9 \) \B.2个
2 K% S. G  v* m+ OC.取决于系统资源
& m6 W, H. t( C( e8 D+ n' o. iD.3个
) `* t; ]3 A+ c. Q* _' U+ ~; |; UE.想要几个有几个
4 i. \$ Z: Q! E
) Z* B9 [+ Q' |4 ]" x% O  h: }# W! V3 _# ?7 Q
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.多重继承
: u) N. I# m  k; g: \, CB.接口
2 F7 r3 J3 h6 J# O- @8 \+ mC.抽象方法) N. j; c: ^/ k% ~# T- Z
D.Private方法
9 p% U" P/ F, U5 W  @+ _E.函数重载(function overloading), l: F- s) e- n6 s: |) ^% c$ V# f

' C9 L) l# G  [5 Y6 D% H
. I7 c3 H2 d; h# B6 B8 ^2 s* K7.假设定义了一个testclass类,它的构造函数的函数名是什么?& v, h2 T: r8 k9 p2 p4 f

" e9 H0 D# j6 e/ S: b% EA.__construct2 d1 V6 u0 G& m6 \" v8 r2 p
B.initialize: x$ P3 g' h; q: {: ~3 y3 q
C.testclass
9 W5 c; [9 p9 G9 zD.__testclass
& c  G6 ?" p, IE.只有PHP5才支持构造函数9 J& x% r3 x# ]2 B1 p
( {1 ?3 A: X. h: T0 V

% r- \3 W( k7 w2 h0 h/ s# B4 ?8.一个类如何覆盖默认的序列化机制?
6 Y' h! h5 e8 \& F7 L3 F( o. R4 f  U7 O
A.使用__shutdown和__startup方法
  D0 b; j: d* \# w* cB.调用register_shutdown_function()函数4 H0 f/ z1 C% R. }' L
C.使用__sleep()和__wakeup()方法5 M" z- a' U% n, {0 I7 f: z. n. X+ Z
D.无法覆盖默认序列化机制0 l) A9 ?. _- m; G
E.使用ob_start()将类放入输出缓冲中
1 J& H* w; }, z" Q
3 \  ]! t$ K" b5 Z+ U' s
" ]$ [. c: ~& J4 F/ P5 X9.以下哪些面向对象的概念无法在PHP4中实现?0 s0 ^! ~5 ?0 u# T! U- r
# v. v; i$ G3 K
@抽象类
- X. ^1 ^7 z- f5 w( J" F@Final类
9 @1 \4 h; G2 k* Q& q: f@Public、private、protected(PPP)方法& n; [4 G% z1 u! d3 X, H" ?' W
@接口
* I- V: x# a5 Y$ V3 Y0 K- ?- X6 `" t/ _$ ^+ J+ T( R
A.抽象类6 m) T! ^& L( }( o% H" |4 ?
B.PPP方法
0 A1 z! N" M, D/ l; L6 dC.PPP方法和接口
6 X0 K1 b( N* f- ^4 ?7 eD.以上所有都不可用4 N$ c/ [4 \: J- q
E.以上所有都可用
1 V4 }5 K- K+ F: l" `3 H  B$ A% ~3 G( `( P+ c7 X( e/ O& |7 J0 Q8 W

& O& B  R+ s. T2 B$ W10.如何在类的内部调用mymethod方法?
5 ]' R6 x& |/ o0 O! q+ n0 Y0 I
' Y  j1 x6 {$ m# eA.$self=>mymethod();
- ]6 c$ |/ z0 Y7 v0 YB.$this->mymethod();' n6 X2 x: v" L! T% N. J  v
C.$current->mymethod();! ^( l, d5 K5 X$ {: L, J
D.$this::mymethod()0 N: E3 A# q; t3 \
E.以上都不对
% z+ i% P, O+ w, w
: |9 w% {5 Z  v, M4 j
# g* r9 }( F' P6 k  L11.以下脚本输出什么?

  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' D" a$ f' ~8 v3 dB.Null
3 I# J; [8 b2 h  y& Y+ p, _C.Empty
! i# Q5 H) y- `6 D% f0 GD.什么都没有
8 c. t2 L; k3 YE.一个错误
  K: z7 X" M# d
7 A2 O4 P2 X% G# q, I! O% I( O  g4 d+ Y2 Y2 ]
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: x2 U4 I5 t# W. [. t0 U. G; ~
B.5
5 m2 e+ o3 j% e4 `C.2! s) A. }1 N+ ?, y) [* h
D.Null  W) M7 [4 y9 o% }/ Q" K' `- l
E.什么都没有; {) r' f: n- [  v0 B! B# I

0 V' K. L. q9 k
' y3 d; ]1 B0 {& T6 a  G$ i; F6 V13.以下脚本输出什么?

  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
9 u7 `. S9 _# L' s. }/ IB.10* S2 W) F/ Q& P; x: c! `4 E! o5 y
C.什么都没有& c4 x& `$ g- a  D
D.构造函数将报错! y7 t4 M' k; r/ U- Y  R
E.510
- D4 F4 n  l! s! N5 e2 g' W! c7 O- s# m

* k( l) S7 Y# d8 p) T14.考虑如下一段代码,执行时,$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函数必须返回一个值- u, m$ N' V( |8 H$ Y
B.reduce_fraction函数必须接受一个整型值
" `- ~- A# |+ Q* e& {C.gcd函数有问题
, c. T+ ^' X/ T) |( OD.必须通过引用的方式传递$eight_tenths对象: i1 o1 [8 l$ Y/ v) ~/ ^# n4 K  A. L
E.对象的实例不能传递给方法以外的其他结构。
1 k. ^4 u4 s: B
+ }; O) l; k7 H/ Z3 j% O! _
2 N. Z! S6 R' ^# l3 h' N15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
; y9 b0 P; P9 f/ g+ `! f  n, bB.生成myclass的实例并调用mymethod方法
9 y0 W$ Y& a; jC.产生一个语法错误* t. N; l, g6 i! A% G6 z
D.默认myclass类最后被创建出的实例并调用mymethod()4 f- {" S( Z/ l+ N& W6 C* I
E.调用名为myclass::mymethod()的函数8 p7 R7 \. W- V% M9 ]

0 x- I" A- ~$ x3 H+ z) J" K5 t5 h( n( ^% l9 q( J. g( I) E6 g9 M) r
16.PHP中有静态类变量吗?, @$ D$ H2 m. z
3 X; `  A7 t. [9 m) O( J
A.有& }# T9 V; J- M) J; O8 e4 w
B.没有; b7 F$ {  ~4 x9 s6 t
9 {+ d& R& N6 j0 H" U; |
) A8 t0 K( i5 T1 {, S
17.以下脚本输出什么?

  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.11 ?" F! z( c; f) q; w8 x) i
B.29 N( ]- J9 b) }2 q
C.一个错误,因为没有定义a::$myvar
" g, g: `8 t4 H: `& }" GD.一个警告,因为没有定义a::$myvar
1 S/ c% F9 M1 Q8 p6 g$ GE.什么都没有& G* Y) k' P7 ~8 ?4 ?7 Y
  d* @( }4 D$ t; N5 H6 j$ ?
9 y, i9 |, ?2 G* w, a
18.如何即时加载一个类?
1 S( L, Y. T' ]: |# w+ X- }! r3 _, D; i2 ?
A.使用__autoload魔术函数
! a6 d9 |( u6 R9 E0 AB.把它们定义为forward类
9 O, J; e9 v- pC.实现一个特殊的错误处理手段
# L& ]  _4 _5 ?D.不可能
: n: ]. E% q: s2 hE.用有条件限制的include来包含它们
9 j* l* \: J/ `6 N1 ^7 u! l& O
/ d  ]+ w, m1 \5 v# T+ O; y9 b) x$ ?% D
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
  b, k# d6 Y3 o: W/ W- K: i! b: k. i- l" |# c5 V% M4 I
    答案:__________
: @% K$ T) ]; n7 F- p4 n3 A. J: }$ i! ^+ t& ]

2 j6 k1 B  e6 t: Z  F7 j. p1 R0 K  ~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
  V0 m. B) ?5 W, J/ I+ r* \B.一个错误& B; z/ u1 |* _4 d! N( e' f
C.一个警告7 E; h' f4 B, }9 C7 a& u
D.什么都没有
. m4 j) J/ c2 P" W8 f* A0 k0 B

* W% s5 p: G7 t2 X/ N8 o) U7 U* K- t8 N- q# y
答案速查
8 `% `' P& w' [: O1.类
0 Q4 A) v7 ?" U5 S2.BCD
  Y* \5 d( I9 J/ o3.C
5 G& D2 I! H  `: R; v4.C( e' m/ G6 A, i5 S, Z: m, Z
5.A7 h; V9 U4 G% P5 j0 S6 O8 z
6.C
& P9 K% E3 H1 ]6 `) T4 y. W# I- j/ w7.C
4 M1 J9 M2 ]. R$ A8.C" M) l7 S; d* I
9.D
6 E, ~: E; a3 H- P( F( E- k10.B) H1 ]5 Z1 l2 c
11.D& @" a7 G2 ~7 |  ~8 u4 \4 z) q
12.B, u5 Z8 {; ]' V! K0 H5 ^
13.A0 u' [: j8 g1 P0 r' {
14.D! \3 Y; f; F5 p' q) F
15.A* [" R. R7 m3 T0 w& R1 t
16.B! }4 u9 f: e* U) D
17.A
, G, ?8 S( f+ n5 U- M% E18.D7 i3 _8 {# V, f
19.设计模式. H: H7 A9 g- Q1 t. s  q
20.D
7 H( C+ s! S( g! U# A2 u) j, I
" g7 J. Y7 o6 s& r8 s, b% v
5 e  F9 K# b2 d6 k
9 v$ G  ]1 Q5 i" X7 ]8 Y. w答案详解
7 i$ F' Z, M% ~! Z0 e. t1 i- m* ]7 b' h- F4 q0 B& j& Q) X
1.类是对象的蓝图(对象是类的实例)。' v! p$ T! A4 @

" O$ B  t4 G7 x. H  n" x2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
. F2 b8 S& j5 e9 F+ W
0 K7 M3 p, M8 O5 \3 s! k6 \; x3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
3 s" D( d- z6 ^
  I/ L* ]0 l+ D) o6 m/ x4.单件模式可以限制一个类被实例化的次数。
5 v) x9 K0 R5 O) P0 T; d+ F4 G9 i' T, x% n, `* @2 `6 [4 t
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。7 n* H) {' t  T$ T% |

( Q. ^3 v+ F; f1 L* N6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。9 r" m0 d7 s( M$ U" Q: ~0 n4 E2 ~0 B

( N1 E* Y$ ~" X2 D$ ]+ ~7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
. N- \. e; C& |5 m$ ?7 `2 C  S( ~0 c% A1 V: j1 ]
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
1 Q- K- f2 _; W% p$ F0 H! {% K' |( b# Z: Y1 V7 D! O+ }3 m
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
" b8 g! v+ x. X, e
2 N! J; `% Y8 \10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。" S) k4 ^) h: w1 n: t1 z  i

1 r" d! G" t' s1 t  Y+ \& T11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。3 r5 S6 D# k, [; c0 c! d' k7 T, e

9 U% ^8 i  d$ i1 P5 J5 @12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。3 I$ W) k2 w3 J3 ~) {5 G( E) R/ R2 p
+ U$ o1 B. W' Q/ r) V
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。2 q  q' d) E& \5 d# d1 T( u$ d
) u. W' l6 l+ H- a5 H# B1 `
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。4 N7 F: g  U% G; [: H3 n
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
9 e" ]: f8 e+ k  q3 F0 d    function reduce_fraction(&$fraction)
- x: C2 F4 c  v/ x% d0 a) ?2 F答案是D。* K, T+ t4 f8 H" N

! J7 d9 k* ^0 ~  b7 I15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
. x% Y; o& N. G+ E3 A5 E4 M3 H. V& C4 t5 V& v1 t( s  G
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
2 ~: p: k9 h% Y, k+ `9 V
, O  V/ |. v+ ~5 N17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
. k7 H$ t2 P4 P+ R4 D  `
; E3 s# B$ q/ B6 P18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
0 W- k6 x; G: W# e+ |8 W1 E. `
1 X# ]5 `5 ~# `19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。6 e% i' e$ @% T& L* |) a" B
1 n5 A3 a* E' k# F# n/ ^) u3 Y
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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