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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
; f" |5 H' R0 e% dPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
3 m$ _7 H0 L! T4 o) |& V本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
* u+ a9 ]1 k0 K% r& {& R2 Q) d- U6 u& P7 F3 z7 W
问题
; ^2 O" S" U. h1 t
# Y8 g4 a# }4 |. g4 D8 W, d1.对象的蓝图是什么?6 G) P( A1 W2 g" W+ h
8 i/ T# z* _3 ?4 V$ s
答案:____________
0 v" |/ S# t4 R8 N! t2 }8 e5 m+ [( f/ K8 i3 }! C7 ]" f

: e& h4 r% F" S, ]3 m: ^2 H2.以下代码执行后,数组$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% B4 T: E; `* ^/ i) |
B.b3 I3 r* l9 A& z, ?, q* H. g2 H( U
C.a
, \* r( ]( }& d' ?5 MD.d( y8 j1 I5 D! }9 M
E.e- I0 Q2 f6 M; D( S0 g

" e8 X9 Z2 J- n0 k9 @* l$ X( |3 J# a( I; p5 c
3.如何让类中的某些方法无法在类的外部被访问?. V: i! \* f7 x2 N4 Q1 q
; q8 ~; @4 c' [2 w
A.把类声明为private
8 l( l/ W1 _! N0 SB.把方法声明为private
( R6 w2 @$ |! A& t$ N1 lC.无法实现1 P2 r1 [# B  {  p% @9 [; I" J
D.编写合适的重载方法(overloading method)
6 F- H; e+ {; ~5 l
( V4 g6 x% @6 W- h3 |( V( ^8 y
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?1 b+ @6 j: Z& s" ~4 E( `- y- n+ x; V

: z/ x! P; _  ^# Q0 z: \) }: NA.MVC模式. A6 M8 h% e+ _8 I0 ?0 r; Z
B.抽象工厂模式(Abstract factory)% z( Z/ i  b2 u  ?1 N
C.单件模式(Singleton)
+ H( N7 v$ j& J5 @* }6 l$ T: MD.代理模式(Proxy)+ D! |/ }* j( {  K
E.状态模式(State), s5 q6 i$ N* \# U: k8 k
2 W) u9 B% K( o( g4 Y) Z* S, g

& |& e* u7 l$ N+ _& m6 \4 u; C7 {5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?; Y, L/ s! [# Y/ ~! C

, T6 K0 y" h( Y% x, l( \5 I- y: z; pA.1个. C( f  h: ?6 X0 Q6 a- ?7 A
B.2个
# c% @& s# Y: W6 e6 L- V6 vC.取决于系统资源2 j# Y% L2 o  l3 y
D.3个
* O2 I  V5 W( G! `E.想要几个有几个  x! g& [/ @+ e5 C7 C- J

% A5 N5 r+ Y" i
) v! h( Y1 _5 N4 P. K( J! \$ H6.以下脚本近似的表示了一种在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.多重继承
1 ^# `6 d" k' @0 O6 S! M  _. M" yB.接口" L3 A, _0 g4 [5 i" x
C.抽象方法+ G2 W+ {4 t) h/ }- {' z
D.Private方法
( t, D% i$ d4 X. b- Z9 ME.函数重载(function overloading)
- _2 x/ _6 \2 V: a: Q) v& E! e# ~0 A$ x$ p% b8 l& N
( w# W0 d% B* D& |5 R' d/ i
7.假设定义了一个testclass类,它的构造函数的函数名是什么?9 [1 z/ y3 v  C0 H1 Y- x
- l$ }% y  v4 ]7 h5 j. }! _" E
A.__construct, ]1 g2 |7 t4 Z0 ]; l% ^& P
B.initialize+ {% e0 o% Q5 l) @
C.testclass
% G( P& l3 R  R, E# _! o% M3 MD.__testclass$ S4 n& u- m, t: S! b
E.只有PHP5才支持构造函数
# ^& |5 q7 e" z! e: f- [3 Q6 L9 z6 \/ y8 n+ c6 c

7 N- T/ {9 e# I; h, n: B8.一个类如何覆盖默认的序列化机制?4 V) v1 g( I3 P5 a
5 x+ t! r% W% p) O# _
A.使用__shutdown和__startup方法) S3 C8 N' U- @  |( q3 S5 J
B.调用register_shutdown_function()函数0 {5 E& p& S' J1 h) F* U
C.使用__sleep()和__wakeup()方法
6 f$ N7 A2 [& K* u4 q- [  a7 F# d& cD.无法覆盖默认序列化机制) b& ~, q/ M) h) ~' F' o# H# w
E.使用ob_start()将类放入输出缓冲中% Y  k) y" I2 E9 B+ o
6 B6 }7 k% c& Q9 Z- U; J

( ~, x) I9 j) e" K0 J) Q, u9.以下哪些面向对象的概念无法在PHP4中实现?
' t: a, u4 l: v. L
0 m; C# S  O2 Y' A, e& g@抽象类! {+ w  X# w0 |& L7 v
@Final类
2 `. z  Q/ s- Q: ~) ~* P$ s6 U@Public、private、protected(PPP)方法& x6 \- {1 S. M. T, M
@接口+ l9 d! d9 z7 d7 l

) y1 Z& v3 t& H5 E4 j) ^& \A.抽象类
5 k* p% ~0 d& P9 _$ kB.PPP方法
: Y9 ^" R3 P) V' B5 p- a& y: sC.PPP方法和接口
# O% Y0 r9 B% @: Q( ^7 n1 tD.以上所有都不可用
$ R( x+ c$ E3 _E.以上所有都可用
$ v8 U8 h( b. `: O# T9 x" |* a) K& f7 S5 E) X2 @5 d9 o& M

, q" d: y2 \- T4 l; m. O( w10.如何在类的内部调用mymethod方法?
; ?! r( z0 m0 c: n4 L4 A1 n2 e8 c3 c4 H+ }
A.$self=>mymethod();  i, i' X" z4 J2 ^* `$ e0 X9 j
B.$this->mymethod();
9 r  _$ l) i; s( cC.$current->mymethod();( T9 h1 p( T  W% i5 \
D.$this::mymethod()7 x2 }7 A; X! k1 w( W
E.以上都不对2 h% z/ A$ \" E9 T

- W( L0 p1 j$ z& l/ z# g7 }4 Q) f) L9 V  p
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
  m( e9 Z% r" n% a* qB.Null8 J2 U) M- E9 u  H4 Q) U
C.Empty
6 d2 \3 a/ [6 H! Y' ~& f1 e8 O; ^D.什么都没有8 Q( S$ D# \; _
E.一个错误' P' P- {' y% V- f# W* s" N

- V5 ]* k2 [4 x" Y5 _) [1 Y4 b7 E0 D2 ^+ X, R! l+ B
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
: U% K: L$ T! Q' B/ N* jB.5
/ B; [! j  t1 oC.2
, u3 n2 U4 M% m+ k( MD.Null& E; J9 h+ p4 M' b$ p
E.什么都没有
) ~. v# j  O. v' Y7 I7 m# @0 @& A+ v3 I" k" G

! l: g- H* C0 z3 G3 L13.以下脚本输出什么?

  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. [8 D3 L* `6 `4 W, C, g
B.10
# b8 d# z, a5 j! C. g3 @( RC.什么都没有
& U7 ]# u3 z- @6 ND.构造函数将报错0 r' V) I2 D& [, x) S
E.510" Z- O8 ]5 T: z2 f# d; p& Z

; L7 V4 [' z' D8 ]! W! o: V' p3 P# a3 {4 e# h9 c2 K( n5 S# X
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函数必须返回一个值- B# V! p, `, c; }6 d5 P6 d6 B; N% t' t
B.reduce_fraction函数必须接受一个整型值/ f. `' c% a! P6 L. P4 Z7 v6 E
C.gcd函数有问题: z; ]; V5 r4 Y% n+ A8 f
D.必须通过引用的方式传递$eight_tenths对象
6 p& j3 J* o' Y7 s. zE.对象的实例不能传递给方法以外的其他结构。; N* ^/ V$ h; ~# w- s4 s
6 U# ~6 y# e6 I% M8 c% h
% T' I: c: f; }" P  u6 I) ^
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
5 n9 {& W+ A! l( T8 jB.生成myclass的实例并调用mymethod方法' m, G: I0 ^/ _" m8 q- F( @" U/ |
C.产生一个语法错误
, c" F! [% B& z1 q6 aD.默认myclass类最后被创建出的实例并调用mymethod()
* x$ b+ O1 _+ ]  ?$ }: BE.调用名为myclass::mymethod()的函数4 I( g8 r7 E4 u3 [# L
, H( `8 _' N2 D# o; ^, x
$ O  \9 z# Y* U9 g9 ?4 P/ A! N  J6 R9 a$ S
16.PHP中有静态类变量吗?6 A. |* O8 f: L1 i5 `, _0 ^
( c' z3 |  ?" U
A.有) S" p5 }& j1 l. o& g6 H, w
B.没有) y4 x9 e7 Q! b: C! C

" B4 ]1 x# y0 W6 D  c! O# |' x5 j. `! k+ a* J- r0 W: `) ?
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.1+ Y* ^* b. I- U
B.2
! n; L4 F: V" ~1 @% `+ P) x9 gC.一个错误,因为没有定义a::$myvar5 c  p# h# P  U- ~( F+ `2 u
D.一个警告,因为没有定义a::$myvar! h" b' _4 [' O& f: {+ ]+ p9 R
E.什么都没有/ h" V# b+ R+ U& n- S4 p3 [# V

0 E' D8 }0 n4 v" B$ }5 |7 u/ M4 f# q! e8 _% o5 E# M! P( c
18.如何即时加载一个类?/ s; H: f; y" }$ |6 x7 h

- S! ~" B, I$ M$ S" \2 ZA.使用__autoload魔术函数
# n! i, B" H5 v% w4 @& KB.把它们定义为forward类) O+ p$ L. c; b! g) W* T4 W0 U
C.实现一个特殊的错误处理手段$ F' j  F4 j7 I) U* d
D.不可能
/ ]( C  m  X% m+ G) P# {1 DE.用有条件限制的include来包含它们
. Y; F% F% b" W' S6 c. Q% L3 O" S$ b4 R- O; P: I% |4 O

; ^# n. K. {4 Y$ \19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?2 h* v+ @4 O  E: l, t

( ]  n. A9 a; ]; }# h# d8 B    答案:__________
1 l4 K* C5 ~9 g
4 V" w) B1 x. e# W' ~- B3 I9 N# h) f6 V
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 called6 p3 `' j, b; G
B.一个错误
  G3 q4 S2 c6 ?; AC.一个警告
+ K# W. A6 o, z) ^. PD.什么都没有
* _9 S7 ?. H- i8 R7 O* g3 a) ~
" X; Q. F/ C1 ]& G" R" f0 ^8 q& f; i' P- I7 k% {0 W/ \+ q

+ a) V! u3 \( Y/ a, n答案速查' |7 |9 I+ Y" w( b
1.类
1 r8 s+ W8 I$ u. t2.BCD: S$ M: d0 O* `  p  x% s" i
3.C; M( f/ z4 [8 w
4.C3 P) h. N$ \2 y% _
5.A
* }1 q- d: h6 O$ C6.C/ h$ r; W" E& L( q
7.C/ T( {$ ?% O/ V1 v2 h9 {4 B
8.C7 }. c# \- ~# U' h
9.D
  A2 _4 V7 |9 ^5 ?10.B! B1 n7 H8 v  q. D% e/ y2 B, ^
11.D2 d, |# j/ h  O5 D9 I' F
12.B; y; }( _) w, P1 k+ q
13.A5 s! ?+ @" D% K: k1 Z5 p. X- V
14.D
" i, Q8 U9 |7 |! U, T6 \. C15.A
( Q1 f0 w, L6 {/ V& S! ]0 j: ]16.B& v2 m8 R+ ~8 L
17.A
$ C9 r; p* U7 Y$ z7 m+ N18.D
8 }) X- z/ o* Q1 }$ w, h. |19.设计模式6 f3 d) x& C+ B$ H
20.D- @3 d& }8 U6 E
# L2 M; F2 F6 e9 U8 ^

( t7 C# }# b5 ?/ W
" \; |2 c1 ?. y0 ?答案详解: r# X2 m" s% d- A+ F0 W! I
8 |5 g" Z4 H. f$ T2 B* C; c, G
1.类是对象的蓝图(对象是类的实例)。
6 y6 j4 p8 k) \8 e9 Y4 i2 t
7 N  s% M3 y# E& ^  D2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
; a$ q. s& n: d2 X) i. V2 C* Z3 H% Q! A3 ~- @. r" A. U
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
% ?( K  q$ O+ c: `: }# z" L8 m/ C4 S, Y2 W- ?/ {; w' C
4.单件模式可以限制一个类被实例化的次数。
1 N" v) a' f# d% t+ |  c+ [9 d" X% o
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
/ ?' n% a# Y; J( {7 F. G, l$ h7 z9 i
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
$ L; z# P' Z& G1 s0 J& t8 a; X) j9 ]- I
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
9 L" C% r. X  M6 y+ f- L+ Q0 _8 ]& t+ }% }
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。4 {: z2 d3 L, P1 \0 L! |6 F% O% W

3 ~- q. {( \0 `8 X' @7 d. ^9.PHP4中没有题目选项里所列的任何一个概念。答案是D。. u6 y" f, V* L% J" Y+ y  @; ]5 ]/ D

' ]6 i6 g' C: ~6 D3 ?. ~$ |7 ?9 |$ V10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。% N0 Q' C. t. L0 c

8 k$ I' }1 }1 w* j2 `8 {; l$ O0 s! d11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。' c" J& f7 f0 [2 S

% u# T3 `, L( Q9 @& Z$ ~' E4 |12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。4 l9 v4 R6 o4 v

+ ~0 N+ n) E% J% v+ y8 h1 p% U3 c; W13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
$ y6 A2 Z' S6 B/ N, ]- i2 H0 z- w- U; l  I0 q
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。+ B! N/ z) I. }) x& ^7 X
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:: I! N. z+ n+ [! K
    function reduce_fraction(&$fraction)
3 s5 I6 @1 g1 G4 D答案是D。
" Z. W1 z% v7 I5 s" [' ]
, ^9 ~, D0 ~/ c15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。& I- V3 N, i% S% V- f- d

8 t% H: U1 u! c+ L" B2 L1 R16.没有。PHP4只允许声明静态函数变量,没有静态类变量。+ ^" N  ~7 {5 M! q
6 V/ Z: ]# L7 [" C' B
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。6 K8 R9 s* A8 A. x! {
; l- O) U3 r; [
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。& h' i0 i2 W$ ]( S$ H
& s9 L8 ~  [7 g$ y8 n  {& u; O
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
7 T' q% D- f8 S5 Q# o+ M% Y0 F, k- S2 S" o# N( r
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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