返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。* {, _. ~- R$ }6 D. m3 q3 C
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。; j& p) _  ?- Q
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
$ Y- F6 B) T/ I* ~1 }& d' y; x$ {( H* B  q  k+ H& [
问题
+ Y- u1 g/ s  e
7 k! R" h7 @* E6 [9 H4 z' z/ q1.对象的蓝图是什么?
2 r& U9 p; `. A: w! h. B! L3 v) h
4 Q+ L/ t6 w" B答案:____________( ~  `6 m5 l5 P3 ~; y1 R; [
0 O& Q4 I8 h+ p5 U- N& Y

$ x/ ^$ ~1 s1 ~# t  C% {5 b3 ]: u2.以下代码执行后,数组$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 N  V: h6 u# D. B# L; X& SB.b
7 F5 [' |; f# c, pC.a
0 O0 w7 J  M% HD.d  J) Q1 x0 R  Q
E.e
5 C4 R" G) r4 u5 D9 r7 D( _. c, ~7 `+ e8 I
. H" [! F1 F+ V7 ~; p8 _: \" P2 Q! n
3.如何让类中的某些方法无法在类的外部被访问?
4 o: y2 ~' Q) [; w" b+ R1 W
6 W( z* Z3 H$ A4 R) SA.把类声明为private: j. C$ w. h2 V$ A/ \# |1 G; w
B.把方法声明为private- o/ ^& [0 @0 D0 g1 U5 O
C.无法实现1 W) p: d' C) @" G* @! h% T/ |" C
D.编写合适的重载方法(overloading method)5 i3 }6 q# i- j* m* F1 d

& V8 Q) r! i, ~: k0 q
5 w4 |. f- @$ X4.哪种OOP设计模式能让类在整个脚本里只实例化一次?, T% g% b1 v" A# o, ?) W

% t* Y0 O- J5 A  Q3 o% F8 b9 x2 M+ DA.MVC模式+ C4 D* g% r/ F' u) ?4 Y( E8 T
B.抽象工厂模式(Abstract factory)
7 I7 }7 b' @0 g- C3 f& pC.单件模式(Singleton)
# M5 j1 d0 U! h0 i: c; I. iD.代理模式(Proxy)1 D$ X) i! c2 G+ M8 c% ~2 z0 P* \
E.状态模式(State): j$ y  L4 m, }0 p0 A! x' C

+ j0 h- h9 V8 _/ I2 _0 [# [0 ]) W& a- l" B) z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?9 A$ t+ Y& G: Q+ ?

. U: V3 T. x. Y5 p, T% t: X) CA.1个5 Y2 o  R: Q( V6 V
B.2个
1 ~( {) u3 l- o0 r3 K, yC.取决于系统资源- y1 w3 o  O( i- f* L  S
D.3个
! b' E# [/ |* d- g' TE.想要几个有几个- B: K7 b6 T; H) W% g. t5 P
0 N  @/ n3 l8 ?- P& N& X+ `

/ s; ]/ Y8 a+ A# m6.以下脚本近似的表示了一种在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.多重继承
6 t0 \; M4 e2 X* \B.接口
4 T: r- }$ d1 y4 M. ^  kC.抽象方法
' e9 s2 m# v8 rD.Private方法
  \2 B- Y" |4 I) k6 S3 D. s. V: dE.函数重载(function overloading)( ~1 i% H& d/ b/ C9 R7 ^
$ C, g1 `/ r2 o" g3 ^) G1 j; k
1 Y' \% i" X5 {2 n( g! ~
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
0 c" @/ g  @# w  D- P* s
; j8 z/ x, u4 V3 U( V: LA.__construct5 X/ }. P% R# f: Y. t7 u' U
B.initialize( M7 M. l$ X' S! b/ Y! d% E! O
C.testclass: @. l: n! f1 O$ O3 ]" B6 N
D.__testclass# S: b' ^0 L% K$ w$ @, t6 x2 I4 \
E.只有PHP5才支持构造函数
* ]% z, e1 o8 P! m" \$ i; H$ i2 ?
8 m; D! `& l2 ]; g$ n
& I& D' B/ ~! B; y; e" H8.一个类如何覆盖默认的序列化机制?
& g7 t5 ^. J4 k+ c1 J% U- _) a6 M8 H) K2 |3 D$ m
A.使用__shutdown和__startup方法8 [' s( n) U% u! F8 C
B.调用register_shutdown_function()函数
* j; h# O& F# n& ~C.使用__sleep()和__wakeup()方法3 w$ C' w: ^3 U% B: _* t
D.无法覆盖默认序列化机制8 T; S# O1 M) A+ q
E.使用ob_start()将类放入输出缓冲中# I. j6 ~/ n0 H! R) |
6 ^) k( k% z( c  E8 z: n. e  }
. V# a/ m. W6 @" D
9.以下哪些面向对象的概念无法在PHP4中实现?
, Q  j# @5 k# [! B! p. W1 B. l0 Q
5 A; u: m* x; w$ J0 e9 p; L@抽象类
! f8 n9 N' X9 R4 w' S: o# o@Final类
: b& h8 {+ @1 ^( U' Y@Public、private、protected(PPP)方法1 i+ C" p3 p4 @' o
@接口
; Q/ u6 _% F2 N2 Q0 ^4 }% `
8 ^5 u! z9 `/ R# e6 V& \" KA.抽象类
9 P$ S, q, a$ [B.PPP方法
) _7 z  i. o7 I9 TC.PPP方法和接口
9 R0 p3 {; T( U  ]: }4 z( JD.以上所有都不可用
. h3 }$ ~* A8 Z+ M5 K1 ~/ NE.以上所有都可用
* O- B3 q4 A2 Q, [9 W8 l1 U2 t( f9 T; |) M
' @5 t/ e1 v, x3 ^& ^2 N+ Y
10.如何在类的内部调用mymethod方法?
% a4 a) a) ~' Z/ ?" }2 ?3 y/ g  P5 [- G% B* m! U
A.$self=>mymethod();
- A  r5 P6 \, R9 fB.$this->mymethod();  V; P0 E5 X: ?1 `
C.$current->mymethod();
: Q/ w- |; A+ a, x) ^D.$this::mymethod(), Q% P; p5 J. o( C; J) p; s# y
E.以上都不对" V# o/ [  b5 L7 G* R2 P! V4 {) B
0 w: j( g; @$ F& v

/ X, Z2 x" d! W11.以下脚本输出什么?

  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" q' I" h$ Y. B1 k9 r; g! P7 T9 \
B.Null
) ~- J( `/ V& l4 H' e* ?9 jC.Empty  r2 }1 X; z3 n9 i
D.什么都没有
% {9 y$ w: H' z: _E.一个错误5 u7 {" d$ T0 _+ I0 H

/ t+ M  k5 E  x) j. }: ]+ v. F  N5 b1 j2 k: v
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
2 W. @- \5 B9 X8 `( @B.54 ]* x/ r3 [; I0 M4 E1 a
C.2% R' D* \1 _. k
D.Null
" b1 G" M' O7 G- g3 P. {5 Y% pE.什么都没有: b) l' _6 J# l2 o* q- B4 X, z
* L; S) l9 j, i% d) J# a1 o

8 A7 Q. n0 H: n6 a$ R7 p6 u6 q! f13.以下脚本输出什么?

  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.55 U$ ^' J( D1 v  ]
B.10
$ O) X  p2 |5 Z3 u2 J' G6 W( p6 N3 TC.什么都没有2 T# j& z. X9 \% R% b
D.构造函数将报错
" ~- [5 D) [5 UE.510" e  C- J" S. U* q5 o& Q

# [0 r$ T. M0 C
$ z( J  ~$ ~) ~- f' H14.考虑如下一段代码,执行时,$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函数必须返回一个值
: N0 z. t1 u4 EB.reduce_fraction函数必须接受一个整型值
* I& ^2 |' S! ]. {8 F2 a! {C.gcd函数有问题1 t0 {: n4 p& q7 ^4 H& B
D.必须通过引用的方式传递$eight_tenths对象* u" w6 X9 J* e* s
E.对象的实例不能传递给方法以外的其他结构。
) j& w4 w; d% J6 @  t3 I' P8 `0 W* D
7 S" Q' Z, @4 q) w+ [7 T& ^! K- o2 ]) V: V. M8 x+ h, l8 b* a9 i
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法3 j, V+ V  a' n# C
B.生成myclass的实例并调用mymethod方法% ~1 K5 H5 T$ ]) {7 E. Z
C.产生一个语法错误/ S- c/ Y5 y1 ~6 B4 f, i
D.默认myclass类最后被创建出的实例并调用mymethod()1 ~/ }& O- r! P& ~) Z8 _6 D/ Q
E.调用名为myclass::mymethod()的函数4 U6 `3 |! Z1 g9 k9 c$ U( H

: z7 M4 |2 _9 V% ^
- u) }' z6 ^, |8 e; u* s16.PHP中有静态类变量吗?0 T3 q! L! }" @9 Q! ]/ s

0 Y& l$ s3 q+ \( u  k" bA.有+ k7 d7 D  @9 K& J, v
B.没有6 R0 d8 l" m" K3 L
  z3 R7 I- I. j2 K
& [+ c; W; T. I: u
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
8 x4 }( O! L. B" c! v( ]B.2( h: X6 ~( ^. k- K1 }" s
C.一个错误,因为没有定义a::$myvar
! @4 t1 U4 x# H" [# Z0 nD.一个警告,因为没有定义a::$myvar2 [2 J. x* g: z/ I* A' J  n/ F
E.什么都没有
2 D2 n+ A. c" s3 ]  T0 ]+ \% n" n' E7 r( u8 x
  r$ a$ M( E: u
18.如何即时加载一个类?
, z0 {9 P& a' u8 J
* |. X4 ?' J0 N$ M4 FA.使用__autoload魔术函数/ }+ I" [  e% ]) i
B.把它们定义为forward类
" ]9 }8 u! \8 P3 A& e8 pC.实现一个特殊的错误处理手段. q; Z  B+ r: b! X" o
D.不可能
! a; C, @& X  ?E.用有条件限制的include来包含它们
  V3 M! V& j$ i5 @4 K
; Q: l0 m; z  [2 `! X% t1 e& R" i; T3 ]- v! M: C
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?+ r# `6 C1 Y2 d& `5 N
) S) P$ C6 h# `& _; g! g- j
    答案:__________& U+ P; r. @3 w- \( D6 N6 c
7 s+ ]. D) e  q' O
, T# _8 N( j2 W: ]# w+ e2 B: x) m
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
+ G/ H' e2 x4 R3 oB.一个错误
- G. @& ?* R8 V- Q2 x8 @C.一个警告' v' ?% z( V' ~" g  P3 j/ u  W
D.什么都没有( ?  d4 P! _" ^/ c9 y6 e. k. N
1 Y% p; G) G6 b/ h* W  m- V! U

3 S' |9 X9 b5 J+ m# Y. t: ?1 F) p2 H! y3 Z
答案速查  a5 [5 I% y! F1 N! [+ W: [% E
1.类4 j) W0 l5 e: c+ |- X2 L! {
2.BCD/ i3 B" d8 s+ S8 E- \  P
3.C8 G% e% s" d  i' ^( H9 o# Q
4.C
5 P+ [9 R2 A- J: ^( _3 I& k5.A) n6 |- b0 M( v# W+ o9 e. m
6.C  `6 |9 F7 T5 {8 e9 U3 y0 f# {- z
7.C/ l( X" u+ r! z. |3 H
8.C
( `' K9 b# e( `1 t9.D
- G, W5 Y; e" x10.B
* H- P2 Q5 C% o, \4 b2 }( Y5 x11.D( |4 z9 t- ^! j7 [7 U( j
12.B7 d! t* [: ^0 V+ j. [' H( h6 w4 P0 X
13.A
4 c4 P" {7 ^3 s3 }: K. M14.D
1 N( E9 J+ a0 X+ ?- u+ Z1 M15.A
+ J$ k/ v$ j% }16.B/ @( [# w. V0 `  V6 Y
17.A
; `4 l) Q: w, T  r' q18.D! i) a. m" I+ \2 I3 }' Q
19.设计模式
: ]* [, N* q. Q2 I6 F8 J20.D
  o% h6 N- S6 A5 }
& A. c$ |2 m* Z1 I* ]% @$ `% G7 l: }/ R0 {/ E3 p
5 @! u6 |+ {1 R* A$ w: d& E
答案详解. z  A6 i. m# I9 z& }
  d% |# o  v/ x# w# Q( z
1.类是对象的蓝图(对象是类的实例)。
: u8 E8 Z1 @8 s7 Y
8 Y! g+ W9 x5 p* M9 \& n2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。* N: z" }. y( n+ D" }; |

9 I4 ^9 q" R8 x5 E3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。6 P# x* i, T7 k8 C0 l4 p7 r
; Z; m. @' q1 ]/ N, Q; u4 X
4.单件模式可以限制一个类被实例化的次数。
( ~" ]- r9 k$ @2 P
6 N3 j4 q  _4 j* U  N4 b' ?5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。; h& q3 \, ?* |2 J

9 f8 D$ C9 v* h  Y7 s8 F  }5 {' a6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。" K5 G9 {1 F# @7 c% Y: x

" e- d+ D1 e' N: y9 o) n7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
5 q  s, L; v1 }, p' N
, Y9 Q/ r3 a; K6 q3 V0 e4 Y6 b8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. h3 U5 D; i# e
/ @( z/ a5 L6 [2 n. o
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。& k8 y; V4 F4 P. o1 t/ f/ T
& k  S- k2 }5 {) V& I2 P6 j5 _  V
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
6 T! G. t+ X+ k+ Z& U% m0 w% C& w
5 y* t1 c7 v* m# E2 v11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
' B) x8 f. {6 J! D# P; D; \( {+ H3 V  O% |( C4 u
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。' J% P9 c8 s4 t& \( z; o

$ ^- h2 _. n+ e4 {. O: I4 |13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
' ~3 C$ c, \" Z% \
- t, F2 p5 w0 C& r14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。& ]! G' P- a( Y" ^' h3 P/ e
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
- y1 {) C$ }/ p6 V0 ^    function reduce_fraction(&$fraction)2 d* @& U5 ~9 l; D
答案是D。
0 ~) e# ~# A( k4 g2 F& u
- g7 H' K+ e/ a8 f, `% k4 K2 k) O0 r15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。* U1 t! I7 ~) O9 ?* A; W

1 u! P' }$ L$ D& {# a16.没有。PHP4只允许声明静态函数变量,没有静态类变量。* [) H: c) V( R. n! [$ A6 w- ^8 v9 p
0 D, A- O9 V& w2 n6 ?4 L! s
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
+ T$ L% x- s3 `5 Y" `8 B. L3 }
! _" ^6 y/ F- ~' F5 Q18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。" D: f3 S$ u9 l0 U7 i4 f: p
4 }2 e! @. R; N0 U9 _
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
& p! P& W, s+ x9 N2 j: `. N+ W4 j; J( A, J6 h
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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