返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。5 X! z# I% ]3 I& u7 H# x  f7 g
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。: i  f, m! \9 P: Z' @& V: N! V
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
" t- n+ P/ G+ Q2 n$ M( q+ _& ~: y" z9 F3 S" l
问题
( `4 E9 P6 q: n
: I, [5 P' R% T, ]1.对象的蓝图是什么?
; B$ A) u4 H! A' F4 |( a- {- n5 C) ^0 D  }  C4 s& E
答案:____________
8 V% p: m, l( \2 G$ F
) r2 @$ G& A* c. C1 Z3 H( B1 B7 x, [& H* j0 G7 v4 {6 I
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# c4 g" n. d! I9 j& M$ V  z/ V
B.b
) [6 d: ?6 r) D( ~: A$ |2 DC.a
! v% {' o* h6 s6 n) d. }* j7 }D.d
( x8 W, N$ X8 v  P" T3 S' ^E.e! W: ?0 a& r; g! q9 ]! X
4 Y! _% _8 m% F2 g: q% D

5 {: A( T# \) ?+ _/ ^3 ^8 Z. t7 W3 w3.如何让类中的某些方法无法在类的外部被访问?2 Y5 q: Z5 z% {4 @8 X; e

2 J! Y0 g, a9 A' x5 r# ~A.把类声明为private
9 q0 P$ N. |  o+ Z& d- mB.把方法声明为private
# u2 Z% v9 T6 d) |% O' }7 iC.无法实现4 n1 U. \5 k, }& y, G. w4 ?
D.编写合适的重载方法(overloading method)
" I  h7 U. p6 |# b/ e# ?: h8 D2 [' V! {  z' S3 Y5 N3 \
+ s9 |4 S3 v9 q0 b% z7 x% y/ P
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
/ m7 j% ~& R( h; f+ K# y
( f' o# j+ ^4 g' k0 a" oA.MVC模式
* v' ]7 l. X  u3 w3 @$ L, u5 SB.抽象工厂模式(Abstract factory)
/ S2 q; ?; f( U& z7 O, |C.单件模式(Singleton)
+ P( z. e7 ~0 |9 w: p4 q5 lD.代理模式(Proxy)
3 P1 H7 I6 b7 S4 v* x/ lE.状态模式(State)
( l/ Z; i+ G0 u% B: e
; t( q( O! B1 V3 @* `: k+ q0 `% J! m, A2 \9 ]8 r$ ?; `9 M0 B, \
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
4 o9 q# h6 O) o( T. }; c; I
9 a6 z8 v1 b+ _6 ?) K2 T% FA.1个
1 K4 |* P1 r$ iB.2个3 |! U. G3 e6 S
C.取决于系统资源* m/ M/ X% W" s! l$ e' `4 O
D.3个
9 |3 h" |7 J7 h% [( @5 l. n: o0 ^E.想要几个有几个
1 }7 o, c: F4 J/ Z
! c5 T7 z0 \& ^* C1 ]
7 \5 F% d% M# k  z' T6.以下脚本近似的表示了一种在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.多重继承
, Y7 S& Z- j8 I3 Y, W) `; o. aB.接口+ h# R% F1 K: H* E; f
C.抽象方法% G7 }; i5 m% `) }
D.Private方法3 ]0 H" `3 W8 |+ t. e& ]8 X
E.函数重载(function overloading)3 g! n& e# G1 h9 o; N3 G
3 Y# y, Y4 K% H) H9 A; f
  }) }6 F# O2 s! d  g/ T& b
7.假设定义了一个testclass类,它的构造函数的函数名是什么?& ?* i) m: [% X' ]8 X( t

. K- u* F- ]9 |# n, cA.__construct
" P- _. x+ }9 `: i8 lB.initialize7 p5 h' w! r8 P, h# c* I
C.testclass
+ V" i/ x) ~' j0 C0 T4 }+ B* G& V; xD.__testclass
) @& E2 u; L9 k+ cE.只有PHP5才支持构造函数. n, `& Q; O" q4 s: N$ \4 d! M
. {' l8 u/ R% ^2 v& U" d' s4 O
2 ~( P" D  P4 W* n( ?
8.一个类如何覆盖默认的序列化机制?
6 g9 r" D  L% l' t% ?; {: a- |
0 e5 V1 j( q7 ~( D# yA.使用__shutdown和__startup方法
8 M1 G; d% M2 S7 ^B.调用register_shutdown_function()函数
8 B/ Y! q4 \! ]3 B3 B7 i; nC.使用__sleep()和__wakeup()方法# R% P% _2 l9 T2 [( B
D.无法覆盖默认序列化机制
1 C) j  i1 `. A  g5 P" gE.使用ob_start()将类放入输出缓冲中& t" I6 Y* n4 H: d' I7 F
- q, h' B% Y& l3 m1 R* |
9 i- O2 t# w+ [# L3 ^
9.以下哪些面向对象的概念无法在PHP4中实现?  ^  ^2 [$ z! u" y6 G8 B0 o
8 [& J4 W7 E9 k2 `0 m" ]
@抽象类6 x" B( n" f7 h/ H7 i; n
@Final类0 K; h: C0 S) @+ Y
@Public、private、protected(PPP)方法
' o7 `" o9 x/ x/ ?7 ^9 C5 f@接口- @4 F2 O0 Y# L5 h

7 R$ Z4 R1 ^. l: S, h: c9 `A.抽象类
# o3 d6 P7 v- H. R3 I3 S4 F: h( wB.PPP方法. J( [6 u  t# z
C.PPP方法和接口
& l' C0 w! A/ t9 }; sD.以上所有都不可用
) A7 C4 r% a$ q; ?' O. rE.以上所有都可用) d, ~8 V8 p. g/ ~  _

7 @2 K/ E! h/ D% d+ h8 x4 Z2 a
- \. q3 a; _4 c, h7 c' e# _2 B10.如何在类的内部调用mymethod方法?! a' q$ U) F; w& M7 c; x, ~

, l. H5 y. z/ C! ]* D- }A.$self=>mymethod();
3 G5 y' N! e6 V4 DB.$this->mymethod();( E4 X4 h+ {- w
C.$current->mymethod();/ r4 @. d- A- s, \
D.$this::mymethod(). L2 ^* D" D0 n* ~  g
E.以上都不对
: _% @, E2 C& a  e8 p
3 b% U+ o" J3 G( t5 r, z: K+ i4 G
1 [# a: f/ w$ f8 b11.以下脚本输出什么?

  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.102 l! y& Q- P. _
B.Null$ l! o: b$ c, i' J
C.Empty
2 y; h8 V8 ?, M, {  j$ ?! A  HD.什么都没有& R. n2 P. N. v' t
E.一个错误0 R! r& f# @7 |4 ?2 v2 H

4 X4 i. f) U4 U2 T+ E9 P" v6 U7 l/ G: d6 ?# z
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 y, `7 _  ~- y; @B.54 a8 v  A. O' G. _2 W$ b
C.2
9 O1 U3 G7 S/ n4 x0 A7 J( ]$ GD.Null
! j0 h/ j4 D' wE.什么都没有
0 Q" e# \  |% u. `7 H& B8 h. d; |) W0 D# \3 @6 P
0 e  _7 F1 x1 k4 X: f
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
( ]; A9 u3 l" |) k) \B.10
+ t& c& h  y* z: x8 l7 k# RC.什么都没有
$ f$ d4 q; }- l! O* s9 G% G. wD.构造函数将报错/ ~' R2 Z+ S8 y# \; C* F
E.510
* B+ r3 d% r$ K
5 n6 O3 j) P4 q5 P" }% ]3 `" l5 |  K& l
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函数必须返回一个值  D6 O1 R9 t$ V6 ?; ?
B.reduce_fraction函数必须接受一个整型值
! v9 J5 N: S0 h3 SC.gcd函数有问题; {7 Q2 o& i" M7 @
D.必须通过引用的方式传递$eight_tenths对象
+ m) }4 \. l2 }E.对象的实例不能传递给方法以外的其他结构。1 w. t% S; _0 I% R

' U3 |  s7 }9 r5 Y
+ v8 }- {, x% s2 ^15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法1 P. M$ p* }8 Y& A* ^8 ^
B.生成myclass的实例并调用mymethod方法
7 G1 E8 s1 ?! T/ Z2 t2 ZC.产生一个语法错误
. |9 k+ J5 E: f5 C' z% g9 ?D.默认myclass类最后被创建出的实例并调用mymethod()
6 Y, k1 \  R+ z# j0 C  @) DE.调用名为myclass::mymethod()的函数
+ n7 S2 n0 G3 @/ }* W) u& n
. ^# C# N: M6 q) Q3 e: a
8 _5 D% |$ Z! r7 F" ~16.PHP中有静态类变量吗?( X. @3 p6 Y1 |9 H7 g3 ^

4 B' |2 _2 `2 p9 tA.有' k6 K/ I7 A* h# s
B.没有5 n: {2 S# O* C. U; T+ u# T
* d/ A$ F8 T) I9 ?

4 m- p3 _/ S3 {" k) p1 x- `: t17.以下脚本输出什么?

  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
0 w- n# P, u6 q! J2 zB.2: C$ O1 j7 B7 y5 M, N# [3 w
C.一个错误,因为没有定义a::$myvar
9 f) z1 P  t; R1 v6 ^# p3 @9 SD.一个警告,因为没有定义a::$myvar
  m6 Y9 [1 ?8 `/ ?E.什么都没有
) [- T# H2 r. Z+ l3 [  E( k$ p. B! i' ]+ E$ E" N0 J" U: L% e

$ l% ~; a0 c9 o; e2 o1 Y1 G18.如何即时加载一个类?1 i% @* V. c0 _9 X8 G4 p8 a

5 g" t2 f9 \5 B6 v, s% UA.使用__autoload魔术函数( l& R! s( w0 w* T  l
B.把它们定义为forward类
7 B9 J" l- S5 m" d& m4 f6 hC.实现一个特殊的错误处理手段
% Z- r8 @: `1 h! q' R6 sD.不可能
9 t" J. {+ Z3 i4 \E.用有条件限制的include来包含它们
! Q  c$ A: I& Q9 n- o2 }8 g" V6 i- g- A# P+ [( L

* v6 K: y* z* d7 Z+ h4 Q8 q' r19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
, Z- J9 E. Q7 v  W: R1 h6 [, _. G$ E$ ^8 h6 d: a6 k
    答案:__________
/ z) |  r- J5 E1 {
' ^0 O( Y0 l8 x! ~1 K$ R7 y/ k* W
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
1 w* O. H! T2 t" z' |B.一个错误! n5 `* y! {# I5 Y& V
C.一个警告- T; E! v2 n) f3 J- l, R2 b3 A
D.什么都没有
2 K( L! ~. T) |( P& c; C+ b4 o0 E. v+ I6 ?0 Y) B$ p; Q. x
! H* K2 c+ p' S& Q6 Q0 C

! T- J) u( D+ x; Q( r" ?答案速查
0 C* O' g$ ^* Y, m1 m2 i$ }) ^1.类% Q! @; V$ f8 E6 c3 }& k
2.BCD- t. G0 U9 i( t
3.C: a. n4 P$ r2 g5 F! w7 T) z  {
4.C& j4 Z- A2 X5 ]# n; o+ D4 \0 K  O
5.A
' l: Q/ j& v2 P) h8 l: a6.C6 S  v0 }/ d; ]  e
7.C
' j+ ~! C# u: J9 Z& {8.C8 U. K  z- ]* h0 u  ]' W
9.D7 t1 h( E7 Y3 Y: E- l9 k+ g  s) d
10.B
) g7 j/ A. K( S, a, b/ Z" ~5 a4 E11.D% }8 a% z) }7 V  Y
12.B+ ?3 V# d, X; h: q! R1 I
13.A8 H" D6 i2 J; s" [6 I3 K# m0 U
14.D: l* d. l4 ~- d3 Y6 V- Y
15.A8 ]1 h( t5 t* M( h3 ^
16.B5 z0 H9 w2 G# Q9 O# T/ j; h1 X4 T* V* t# ~
17.A
% O2 i; d2 f  k* O18.D
# ~- l  G: V; C19.设计模式# O/ Z9 a+ d1 H' Q5 F: i7 F
20.D
) p% D- V" I; f% j' n) q; [. p% I7 n0 f( x
" z$ W2 W( f$ ~, C) s
+ A& Y9 D3 H( ~, a9 |( C
答案详解
$ W7 x( W0 A6 ?" T$ I- U2 ^) V4 g, O% R
1.类是对象的蓝图(对象是类的实例)。
6 v- G0 K: G7 M' F1 M" J3 ]' u& d$ a' {+ {
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
9 p4 r! ~( u- ?' a* f  v" m3 M5 P( J* i: K1 e9 ]
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。4 ^/ Y  X8 s, W, X9 ~* }, R, }  @
& i. a$ a9 W/ K1 ]) U0 A3 U# u+ u
4.单件模式可以限制一个类被实例化的次数。5 }9 `" n9 L' b6 `6 A6 J4 A# ^* @* e

* f- ~, X8 M" M) t7 W5 \& P- H/ m3 `5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
, ^: R. Z1 j. B: a, ^
& R$ ~2 H1 N* z- O6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
+ z: Z- T9 i' |9 X, N
7 o  r' B0 d  G# ?& m; |- x3 \7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。( p, I/ u* b3 J, Q; V
. ~3 b# r: S: E9 }' O. \7 A
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
$ I1 l* f' r0 h' R8 z. a8 [% M+ Q3 ~1 B
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
$ Y) x& |6 J/ w# a9 L+ z8 V& k; o
9 i% Z$ E0 e# w10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
% p% B; }# m5 J6 K+ s3 f  x) x9 k& A& Y" @
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
2 x$ g6 \$ ?( F( _" h2 |2 ~/ Z8 J9 c$ S7 t: F# n  |9 E
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
9 H0 k0 Q# g$ M: H3 h; h+ ^2 m( ~. j  I$ `" O; ~2 X
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。' ?$ G% i5 ?9 u/ R0 @5 v& e
8 a2 N" g1 ?, b% ^: ?5 \/ u9 h4 P
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。0 X( o. B$ E# _: U9 c  l) p$ ]; R
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
; g8 l% Q- z9 i4 \% W    function reduce_fraction(&$fraction)
5 a( p* w2 Z0 w! I; U7 w答案是D。
* K4 M* Q2 ~8 X6 t: j- t/ k( G
, d1 i5 e( e! A' Q% A  A  Z% J/ O15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。* d, I7 @- n  u* V
- U6 X0 w. w: \( k: U1 E4 d
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
$ w  \. H" Q8 `( f: @) o/ t7 m9 M+ a! A8 F
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。$ a, _# J% E2 Y/ C& b

7 t9 n5 V& q) I* J3 X& ^: c- S18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。6 M7 k+ `* X' w' n8 E

! I* c) U8 T% B0 n/ H19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。  p9 B# n# ]/ [9 P- T
1 _2 Z5 U( w- [- }1 C
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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