返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
8 l0 g  b  g/ p8 dPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。1 L6 H& k! @/ d' I, Y
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
" ?3 f( X2 t* w" a; u- f7 ^
: P9 P2 ^1 p' @问题4 D9 {, l% E( ^5 {

: t  {1 e- `5 \, \1 e1.对象的蓝图是什么?
7 U1 w% D6 P7 i  s* a8 X* J: D1 i6 K; S8 K8 o; E; h
答案:____________
0 y6 b8 d; m5 H) ?$ A9 k# J
) K& e( u6 v' l% `8 `2 [/ A
1 l' c! u4 `; P* A# S2.以下代码执行后,数组$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.c2 p4 ~0 Q& r" _
B.b
/ v: J6 n2 G2 K0 uC.a. E9 w" I4 U& @3 y
D.d0 `  T$ [4 {) ^9 u
E.e
+ v7 l  \7 F& N; ~0 p/ W
" K# _' i) x7 T+ _
  ]1 F( a5 i2 f, i3.如何让类中的某些方法无法在类的外部被访问?; i0 f: o. g& i- M
- U  f5 }: l) n: l( X$ @+ g
A.把类声明为private, b, b1 v! p7 j9 M
B.把方法声明为private) L8 K5 `! u7 }9 y: X+ \
C.无法实现6 U- E8 {' l* A$ B' f
D.编写合适的重载方法(overloading method)
" B( t2 T' D7 r0 C0 y( |
: D9 Z( W0 ~/ M% }1 J6 o5 J4 Q4 y# f. C3 Q
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?$ `' o& R+ \5 ^( Y
  Y+ c3 E6 d) O1 P/ `
A.MVC模式
, V+ n* V) L; F! YB.抽象工厂模式(Abstract factory)
% {$ @! W) O" g9 b' HC.单件模式(Singleton)
" k; X, c" q- n( y. q! Q# qD.代理模式(Proxy)3 t- }& {7 x, d; T8 U6 t* t
E.状态模式(State)
) w3 \3 ~9 L/ O0 W. a  }- a: w* J8 o" Q( k9 B# X

4 ^3 J" O7 k0 q7 S8 w5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?. Q0 B4 P/ N- g4 l2 v

' l2 X5 I( p& u4 C% L* z) ZA.1个. F2 H  O. ~; l0 \8 q2 x
B.2个9 A7 m7 _# S, F5 T& f/ D1 P
C.取决于系统资源
7 R: e5 b0 v5 q& G. w/ ZD.3个9 j7 y( A8 [0 y
E.想要几个有几个' }# P8 _2 n& ^

; K9 s) q9 a: g8 J% }2 w7 _, Q. a+ j, c( r; K/ s
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.多重继承
+ D( P* i1 H+ ^* Q) kB.接口7 X* r8 a4 l: H/ C
C.抽象方法2 P4 X0 d3 E' [5 k
D.Private方法! i, j# H8 p8 _. r
E.函数重载(function overloading)+ T2 {9 c0 ]& \# Z+ v. k

% a& Q9 a  R  Q9 `
# I: f- l9 M- V3 ^& A  m7.假设定义了一个testclass类,它的构造函数的函数名是什么?" L7 ?; A/ H) Z: n5 I
# b( S4 {& `: R$ R' R' ]  ^& Y/ q/ Z
A.__construct
8 k& {1 ]# h; C. A2 XB.initialize
& A* S- E" J/ ]  f. IC.testclass7 F7 W. F/ c, ^! _3 p6 E
D.__testclass2 h9 ]8 B' u" K8 e
E.只有PHP5才支持构造函数7 T5 ]6 A7 I# I5 Z. q' l
$ |6 w0 U  N! U" V
! S& Q% B: e6 E3 s' X. N# N
8.一个类如何覆盖默认的序列化机制?6 q! ^$ U+ H4 v) r6 j/ S6 J3 g" y

- y; R, t9 B( }# B6 Y' `/ {A.使用__shutdown和__startup方法) V# B# ~. E6 X) C3 d( I7 O
B.调用register_shutdown_function()函数. y& ?+ H+ q1 D/ O  A: P6 P& x
C.使用__sleep()和__wakeup()方法
8 G! \) H  f' I( k6 F6 m) K9 iD.无法覆盖默认序列化机制
# N0 }* i# A; e( rE.使用ob_start()将类放入输出缓冲中- m0 {+ E% b% o2 ?' @( a4 M
! G7 S6 A! \' @" N5 q' ]% w# A5 b

1 x$ Y  ]& T( d9.以下哪些面向对象的概念无法在PHP4中实现?* ?3 d1 ]& C  @8 M
* |- Z$ G( k# f5 Q( v/ E# E
@抽象类
8 h, j1 x9 z. q- C1 t5 }( p2 I@Final类: S% [* g, ^2 X; P) _+ f% N9 q" F
@Public、private、protected(PPP)方法
+ c0 W0 S% J3 |2 \* M1 O/ p1 a( Y@接口9 K8 n3 t3 x6 E' a; H. X

' D$ ^4 ]% `* @, \A.抽象类, q# @7 ]7 K  }% o. \  c
B.PPP方法
4 {8 s* I& Z' D% {8 e0 [; NC.PPP方法和接口1 b# S' C8 t6 i2 y/ M( c! C
D.以上所有都不可用
& ?2 Z9 b, N% `0 \; o4 w" OE.以上所有都可用0 g! |5 w4 T. ?/ _6 ~8 C6 u3 I
8 _; f6 g6 i0 ]9 |# k  N
) F! B3 p& V9 c  L9 T
10.如何在类的内部调用mymethod方法?" e. j$ r! p1 a6 w) _( {' A- [
6 ^) @# S* c4 q2 s8 B
A.$self=>mymethod();; S5 F  P3 E4 s1 E! ~% Y/ B: d; E
B.$this->mymethod();% H4 _" _* o, X% ^6 a. R: l
C.$current->mymethod();
/ ^; \% u: D* lD.$this::mymethod()
/ u. o# u8 K# W0 B5 r2 B- [E.以上都不对
4 T% k- b; w# F, j* R' v' \
; Y: C; j; e/ N% j3 O1 `  V0 k" n8 Y' i; S, `+ |! U' B! l
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
+ {$ g$ u: F7 t8 V* e. JB.Null/ L8 d+ n- w, r5 a* h
C.Empty
% Q+ N! R$ q+ o' q" }D.什么都没有
$ G9 W: @0 h9 I5 C: L9 _E.一个错误5 ~( a$ Q1 h" [  i

) R% P, h  F8 t, c8 G. R. D9 n5 T/ R: R9 G& i! s
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% ^/ J3 G2 Y, q
B.5. `1 \4 r5 ^6 l' |- \
C.2
. _. K3 R3 E3 e, BD.Null  _8 i; y' C( Z1 p" a' a4 X+ u, E
E.什么都没有0 B0 v: U* }6 y) f+ Z

& f3 Z; l; P& p+ _# l# C
  H$ r* H; u6 f2 M( l6 ~! U; C13.以下脚本输出什么?

  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
! n; X( \# ?* D6 l$ o1 [B.10
& U! U1 q0 s2 b/ u# r% D6 _/ qC.什么都没有0 x# R; w$ A7 F! y+ M
D.构造函数将报错
$ t/ C# n0 C0 l3 t/ G3 fE.510
, l! Z- b3 `2 _, x! l7 ]& d7 H$ c4 A, O1 h
' ?0 M; u8 C: W2 X- _8 Y
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函数必须返回一个值
# C" z" M# e0 S) W2 }B.reduce_fraction函数必须接受一个整型值' `$ M! _( @  Y
C.gcd函数有问题1 Q  I% o( l# L1 V3 f* G3 w  A
D.必须通过引用的方式传递$eight_tenths对象
: N2 O4 m) B$ T$ [+ dE.对象的实例不能传递给方法以外的其他结构。
; `: B4 N9 Y" n4 z7 m$ [
' h8 @* l# M7 ?* ~4 m1 ~; ~# S4 Y' y8 t/ v
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
: j+ V4 J& n+ ^, zB.生成myclass的实例并调用mymethod方法% @! [0 t% f0 T. }, {
C.产生一个语法错误
9 U5 Y( X2 n4 YD.默认myclass类最后被创建出的实例并调用mymethod()$ e/ }7 N& n5 ~9 `+ r$ p# x
E.调用名为myclass::mymethod()的函数
* q( H4 n) ^6 X  t! ]
% L; T/ f$ p: g1 X' y6 k3 t% x# [1 s' ~' P& s
16.PHP中有静态类变量吗?
3 ^9 {  q; t' s8 \: T6 K+ V! [
$ n& ~, x% t2 e4 u7 xA.有
  t6 }2 j0 n5 b4 z0 ^+ _6 p" z! iB.没有/ x1 D9 i) B1 q2 \6 _; _6 b  S
) D7 H4 Q1 t2 O
* Z4 _# y$ F# ]- s8 p0 P
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- T- F8 j5 k8 x8 O0 s. q$ V1 T
B.2
3 \: W: J7 u9 S! V( [& b- @2 n% j& eC.一个错误,因为没有定义a::$myvar# \) F! J1 X" Q6 }
D.一个警告,因为没有定义a::$myvar1 q; C) w) D. Z; b# v" d
E.什么都没有' x" Z  K( t8 x2 a( d" ~
1 m, }- s' K5 Z( d4 |5 \; u

- D+ }: k- ~6 A: O9 z; u, G18.如何即时加载一个类?1 L3 j& E& C# Y5 S

- |& ~9 g# g# I7 OA.使用__autoload魔术函数* ]4 r+ A0 A  z0 L
B.把它们定义为forward类
2 i. L0 Q" i3 ^5 x1 }$ a6 KC.实现一个特殊的错误处理手段
, ~6 `- u& H- [D.不可能
) E# F* @5 J3 n6 P  v$ K% y0 qE.用有条件限制的include来包含它们! M0 ]# `% V* k( m4 Q% d2 F/ r

) p" b5 D. S) C) O7 I9 E9 H& z  G# e; E! A9 E
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?# F) G2 h8 L- @3 N- t
  L" j4 ]; _& [' y* N3 L. R
    答案:__________
2 D8 Z3 E; N5 x+ O* z3 r5 S% I/ Y7 P: w/ @, R# `- X

) j( G. k( k0 e0 h# k. ~6 u20.以下脚本输出什么?

  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- e$ _2 g( Z2 p' ~$ s4 v' Z
B.一个错误
! N/ o1 D! S# D" R) Q, Y0 I8 aC.一个警告
, m0 ?$ D5 k4 J3 x. E. ]D.什么都没有
# ^! \  R: A9 D" i* v% a
7 B9 A: A6 ]5 C  p
$ |/ T: x1 q, \" o1 O2 y! L* W3 ?& u- c& g) }
答案速查9 g6 t% s3 T& c0 H* @
1.类
9 K% Z8 n' O8 a2 b. g/ K% @$ `2.BCD
/ |7 |2 e' h# i. Y" R3.C7 E. h8 I$ Q1 Z# R9 O; a
4.C2 N- |' H2 P- y: x) T
5.A; [  u. i# x+ i' I; i9 A! Z
6.C
* h' K( I0 w+ ~7 Q" C, j7.C- K8 r8 Z4 X7 l! A" L
8.C
: P3 E9 r: j$ Y& C8 c0 _8 f4 s1 f9 a9.D
1 k3 J: C. V& i10.B) V; P% x7 W2 n( G
11.D
3 @5 Q( v$ d0 s' S/ d' g12.B4 D+ I+ c& ?9 B& G0 ^6 V8 o3 `# X
13.A
$ f$ g6 p% \4 f( }# R  e14.D+ I* i# r' v7 h0 Q. r" W' h
15.A
8 _) F# r& W. p) g& q8 w1 W% R( j16.B& V1 G9 z, A# K5 |, l! P
17.A2 ~' G/ \7 e' s) q! Q
18.D- n( Z4 M3 @; @( z- b$ z4 m9 E; F2 d
19.设计模式
- }# I- X, S4 Y9 X20.D
4 B0 A  Q  a6 r  W: y( D$ z( m- X, I; \/ `: w8 {
* @* O0 C. \0 X# C+ O( ~$ `

) J; ?9 W' j$ C9 @  t) d! X答案详解
3 ~" K  {5 H& ]& e- s: G% e+ G
1.类是对象的蓝图(对象是类的实例)。& E3 R) m% m& ]; {" H$ W9 h
$ i/ n  {% z6 J; t* `7 T9 @
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。9 t" V( c8 r# H3 \- }& ~5 ]0 S
' Y" T2 K0 {) O
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
* w8 X5 G1 X" m2 G" J. K% Q$ X5 }& v! A4 J; E$ c9 j
4.单件模式可以限制一个类被实例化的次数。& ^6 c! M6 F8 n9 v
+ A4 c/ Z" U' @! n; S4 M, H5 Z) x
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
0 Z/ w9 J' ~! ~% R
& n1 g: n# G) j6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。6 v9 Y0 O& k% r4 S+ r6 K0 i- z
6 U; c% n/ ~/ J: Y
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。! s& |) o# p+ H0 x. @" `

+ d/ X# x! H! ^( B8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。2 E( a; n" P( o' A/ ]" H8 @
( a/ _2 X0 c% c( d, l# j, O
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
, s# C" M& o6 R4 W( a, e" h# o2 j; q* t
, W/ W0 b! k* E/ Y10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。9 X# _6 u, v8 l* ]

0 N' m3 E$ f" |" [2 x11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
6 K2 @7 ~; O" g( f
' m! B9 i5 ]& d4 |( c# q12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。6 A! a7 N, f2 Z7 a
2 a1 z( t' \$ n
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
, n* k' B+ O0 A6 C3 Z7 J
5 e; k' `: R4 ^14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
5 y6 n; _/ z" u- ]7 `回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:4 [! t9 A  y% B
    function reduce_fraction(&$fraction)# ]( u4 t0 m- W9 x# u* ?
答案是D。
4 N$ i9 {5 n& f: d/ O  K& `* |7 |
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。8 w3 a/ P, h4 h' y1 T" M
' E6 v: l* N! w  Y% n! S- s
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
( w3 Z# C( r" l8 h/ L3 F
  W3 X+ W! ~/ ~% @5 H2 i17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 @: v% Y/ [: z/ U  |7 n; s
2 H# m1 O9 H* m" f1 R" W18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
, |3 e1 B+ I; ]' R  i, |0 ~$ C/ w0 x$ C
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
; Q  F! O6 ?5 s" x  c, F4 t4 z8 R
. y+ F6 Z$ J. ]' d) x$ p% Q" ?20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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