返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
. O( h/ M0 s( O2 r7 j& p1 o% QPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。. ?% k6 A. M1 v% C0 ?
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
. G6 C9 a6 _- M# N: W) N3 e( F4 j0 N$ L* C
问题9 Q6 e" ]" H9 K! l  [4 M
2 m5 w. s5 {! e% o) v9 Q
1.对象的蓝图是什么?& z) X: Y" \% \3 P7 ?4 w& f
  y1 c. X/ g# H0 q7 q
答案:____________) f/ b: i6 G( d2 N
5 f2 S8 q- [5 ]" T

8 V4 s( l- q' A, X: c/ k. k2.以下代码执行后,数组$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 t6 V: t6 I/ e$ t8 I  Z% [+ f9 K& EB.b
2 V) w/ W" U4 W8 I3 L; D* ~$ oC.a% F! `8 d0 B5 l# J$ U, C$ _
D.d1 O' S! D/ w1 z
E.e
! \' B5 l( ]/ p# l; b; D5 d7 T$ l1 E9 u

# h* d; r% {! r6 k- y3.如何让类中的某些方法无法在类的外部被访问?
$ x% I, |  ]; c) o" c8 ]+ X8 `$ h6 p! A
A.把类声明为private6 d3 _2 s5 _& p" a0 {
B.把方法声明为private$ w8 i/ N& R; K# e
C.无法实现, [4 o5 f* J1 w: O7 U1 U
D.编写合适的重载方法(overloading method)5 \4 d0 A/ R7 h4 c! w( z

  k( Z% c  J9 b3 y4 T. r$ S' K' J
1 w' K/ B- {, r  l6 }  X4.哪种OOP设计模式能让类在整个脚本里只实例化一次?( W5 e; l" l! a4 P4 Y  b' |

* v2 ~0 ?8 n! G# j9 nA.MVC模式' h. \  K& q8 y4 q
B.抽象工厂模式(Abstract factory)3 D" S# g- Q) |" ?# ]9 W
C.单件模式(Singleton), s( `/ R) H7 [7 n, P1 d2 }
D.代理模式(Proxy)1 H8 H8 h. Y5 a2 @3 F+ e
E.状态模式(State)
" A* J+ A! K, {7 h* a( w# W" p
! @/ k! h  Q4 i
5 q8 Z; R6 K( i# E) y4 @# q& x! Q* o5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?4 O3 D5 @  C6 d, ^$ F

( W7 F$ N; h' U, P; vA.1个
: z3 W- R: ]! v" ~% \B.2个
% i0 S6 {; r# Y& y, p% {C.取决于系统资源; d4 _& }1 @1 M
D.3个
& o8 h% s. O. z. |0 e- ~E.想要几个有几个
8 }1 X) X! P. S0 H+ j6 l- K5 H4 b7 H) L5 }$ a8 }% g

* u) {6 ?# P. z& E2 ^7 @' ~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.多重继承
( A" M: F+ a! ?  A$ c; l* }4 KB.接口1 w! K/ H2 L, u, c* X/ n
C.抽象方法
8 E% z( G) n! fD.Private方法# S5 O1 I) d8 X- G2 J' U
E.函数重载(function overloading)
8 [; v8 V5 O9 r# |4 Z0 ~
4 ~: J) z# j: I; R4 r$ |: ^! m& E8 R$ `9 M
7.假设定义了一个testclass类,它的构造函数的函数名是什么?& W* \3 c8 `- x: B
6 |/ l$ y" `  K7 }. {- Q2 p
A.__construct
! j: m: |0 v" ^6 w! H0 j! D) n0 \* @B.initialize: a7 D. {- @4 Y0 r+ c0 z' m
C.testclass
: J, C+ `1 z! g9 ID.__testclass+ V( G: v( G  c( b- J0 v+ h  |9 U% K
E.只有PHP5才支持构造函数
- I1 o& g/ _* [$ W& }5 K! q: a3 ^6 R1 a

' h4 k+ Z: h3 W( B/ f" J8.一个类如何覆盖默认的序列化机制?
- b0 m) F% V) T4 l# p9 A- m+ A4 P! R* c7 s: c& f4 |* D% I
A.使用__shutdown和__startup方法
# ?! M& d4 p. D% bB.调用register_shutdown_function()函数
1 N, C; N; S) f3 GC.使用__sleep()和__wakeup()方法9 d0 d% v) _: @4 p5 f: b- i
D.无法覆盖默认序列化机制
+ M2 A4 M6 m" i' e/ m1 M$ }E.使用ob_start()将类放入输出缓冲中
, S3 ~8 E( i) f# S! y8 q8 h# h" Q/ L+ \* I0 l" w# v2 e8 z

' z7 S4 D* q- b9 N7 x! B1 O5 a$ {9.以下哪些面向对象的概念无法在PHP4中实现?
1 P5 w1 I+ @/ {$ H/ b; }  F9 C2 Q" o+ X" K/ @8 J# L, k4 H' a
@抽象类' E5 {1 x+ J7 E7 X- _+ f
@Final类
/ L: p9 [! z4 w6 f, d7 C@Public、private、protected(PPP)方法
. W. c& ^2 e. o" j) W! D- `@接口2 f- {. Z) x$ p$ E. q8 q9 _. X0 U
  d1 A" a5 O5 M: t$ X
A.抽象类
0 M% F* v( j0 ]B.PPP方法. \" U* `7 j7 h+ m7 `
C.PPP方法和接口
7 y4 B. \- c2 J  C- T" {D.以上所有都不可用7 |# a; e3 w- k! `/ H4 s, i: G% [! u
E.以上所有都可用
) w5 `1 Y, L7 }( W$ B) n2 `3 @8 _* r* H3 h8 m6 }4 ~: f

) v- C$ M# B/ m10.如何在类的内部调用mymethod方法?
$ j! v2 z& T6 d: O; _9 d
' h$ A2 x9 K7 D. B+ ~A.$self=>mymethod();
8 q7 t1 T. i, z1 W1 J  O2 _  z/ BB.$this->mymethod();; ^/ u( F9 F, T1 e5 a" f% g
C.$current->mymethod();1 u9 k2 S+ i; O- M+ l8 V% Q9 r
D.$this::mymethod()  c; n0 ?, D( X. h; f6 ]4 g
E.以上都不对1 y/ ]; f  D' i" K4 D. K
: {; s4 ^0 A  p2 Y/ l3 ^
+ T5 g( g2 K* {: t( L" p# [& S
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' I3 f8 }$ g) Q3 f1 l3 W& L
B.Null. S4 D" {! n4 Q. Z/ \5 X3 U. M
C.Empty
2 B% ^/ m" F; i3 N: V3 g' {* hD.什么都没有! S, m- [( o1 Q3 t3 ~" P
E.一个错误! U- K" B% E& ]

5 }2 x# Z/ a1 g1 T+ b
& p4 `- H" J0 l# Y) x12.以下脚本输出什么?

  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# v3 o2 v/ N) {$ P) x1 u/ a
B.5
3 o) [- U3 v: J& mC.2
5 |- g% B& i$ u, Z  }/ ^/ jD.Null
! F' _) k; x5 Z8 FE.什么都没有
# U4 h  O9 u8 L# s
, t) a/ G$ Z2 s/ G7 B  }) H
" k/ m! m8 }5 p3 O  o9 o% e/ r13.以下脚本输出什么?

  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.52 t0 }0 ]2 Z5 J
B.10* P' T9 W( a" V  |+ k
C.什么都没有6 i9 ]8 V/ r/ t$ V( }$ p4 _
D.构造函数将报错, L0 M4 H' w- f4 z, z) |
E.510
, j- b6 \& x% S! T4 G4 x
- U2 v" Q& q& Q0 q" H' I4 z7 I# l  t3 d9 n
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函数必须返回一个值3 V" o5 s/ |7 k( ^  A! T
B.reduce_fraction函数必须接受一个整型值
! i5 v+ R2 a/ G. ~C.gcd函数有问题0 y0 L0 a2 n6 B! F$ L
D.必须通过引用的方式传递$eight_tenths对象
! J9 |* b2 z8 _3 M" i# b# iE.对象的实例不能传递给方法以外的其他结构。
/ i; u5 o2 z# a$ v9 X' ?$ p) v
& N/ A+ w# G( L3 ?. q0 v" V3 L" o! V1 q2 @
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法, p6 J; f+ _% ^9 t
B.生成myclass的实例并调用mymethod方法3 [9 ?: C/ ]5 k. p, @4 ?+ }7 p
C.产生一个语法错误
. @! c0 B) |$ ^/ z( n- sD.默认myclass类最后被创建出的实例并调用mymethod()
: V# I- B" v) s, i' sE.调用名为myclass::mymethod()的函数
* \3 y: n, u5 X3 j. I& L2 ~+ ~/ |. J6 r

4 E( F; `; h; w7 l/ Y" H$ ]4 p8 b16.PHP中有静态类变量吗?+ G1 y) K0 a' P2 q: B# y" H5 N
3 v0 Z, x8 i% i5 @1 Z8 _
A.有
5 R% \0 c1 e% J2 e4 d8 uB.没有' u' H8 W$ G, Z; L5 q9 y0 M7 Z  x1 c

' ^# u- M' f0 w5 {5 {& I/ U7 f6 C, F3 C; O+ [# D7 G5 D
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* @6 O  U/ \% g
B.2
. v  N1 n) _/ ]8 GC.一个错误,因为没有定义a::$myvar4 B: }0 R7 r( P1 ~: s% \
D.一个警告,因为没有定义a::$myvar
) f) q- `6 h  f! bE.什么都没有
. a* u6 O# {+ b- e
- s* v$ K/ K' w7 g6 Q* W; ~9 ^6 p/ [, Q3 p  `7 L$ d
18.如何即时加载一个类?# `. j$ Z5 G9 W/ Q/ c) l9 c0 z
3 [- k  C* b' ^. a
A.使用__autoload魔术函数( T: y: ^* C0 G
B.把它们定义为forward类
; |$ J' ?3 x) P# |/ UC.实现一个特殊的错误处理手段
6 k- w$ i& G0 Z3 T4 Y; dD.不可能
' \6 P* F& p6 C7 T1 R% eE.用有条件限制的include来包含它们
! F% ]6 a+ r1 m, B# t3 H/ Z0 J7 X$ i' c; u1 V8 P( e
& @+ A. e9 K/ ^1 Y! F; ?$ }; k
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?+ L8 ~" y/ b1 Z5 v
/ @4 [/ v5 \2 F! r8 G" Y/ P
    答案:__________
4 @. ?' x0 k# X0 [# J
5 U7 m- w% h, X( k5 d2 p3 \8 ~7 T' }
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; x0 O5 w* z  {
B.一个错误- ^2 r; l" S/ B/ ]
C.一个警告
# e" j; [  M: e9 zD.什么都没有
, r2 X; t0 h3 @9 d! W  S- `
0 u" Y5 V5 q% w9 w
, a2 \- u- j) [; }" I
- v  }" ^7 c! {0 [1 M6 t) `答案速查
3 X0 B- c) C* h! {+ j) U1.类" w: E& M# }; _% r8 n' q
2.BCD
3 `8 b8 W" |) p9 z$ n3.C
! Q* c% l" Q9 M) @4.C+ k: x# d9 n/ F, T; H6 S  d
5.A
* \1 u4 j! K: _* A1 B$ W3 D4 j9 Z6.C9 a* ~7 |# B: n: d& a# k. Z
7.C
/ s( e* F" q( s2 a: r8.C$ @4 `* k1 U: q: u/ y/ S3 v
9.D* H; |2 J- b8 a; G
10.B" G& l1 z# p3 q* s  H: j: t  ?
11.D/ ]3 V$ e* ]( s) O7 `4 q
12.B0 v1 P4 O) |$ f1 d# x6 A3 Q1 u
13.A$ X  \( Q6 ], c0 p( s9 C! u
14.D# w) i) u$ \$ E
15.A! O0 h  s0 t0 B- i; B# ]
16.B
9 ~/ E* T, p- Y- j0 Y% w( W17.A* a$ ]' s3 V" b2 z+ a
18.D4 h) v* B$ E" o4 [4 R) W; G
19.设计模式
: K) m% Q7 Q& p) j, }) d& r20.D8 P" Q* m" P8 z( j7 l: I

% G0 k! O( V5 Q' j& m. q
! [. i. H! j9 Z$ l; i. Y* |5 \  t) t7 E9 ], b6 X2 K. b0 t) Q; g# L
答案详解, o  R: A5 B0 [
# [, X5 d' e- [
1.类是对象的蓝图(对象是类的实例)。$ U) a4 \- M% i3 ]( ^

3 A  p& Q2 p4 N. I$ G& _9 w2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
4 T. ?7 ]1 D) ~3 E4 }7 l
9 |9 L4 _+ k: w1 m- b/ m3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。- U8 c6 ?/ K- j# H

( ?/ _" J5 D% ^9 Y- C4.单件模式可以限制一个类被实例化的次数。' O# B6 @* u, e: P. }1 \2 Z
1 t0 m* r. B. B8 f  k( A7 F
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。4 j; o' R; p2 U% B# S) S1 z
* \4 f8 \" `9 q7 n6 h
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
8 A" Q0 C9 ^/ r- i9 {9 ^" p7 f1 y5 P$ V' Q* C& \5 r
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
$ B, j, e$ x* m, G
8 W9 e7 a% }6 L8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
5 [* q$ M7 ^1 w; z  _/ j  n/ s% ?6 v: |/ P( _4 I1 Q5 A' }: y
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
7 q+ F  w& O1 P; g# z/ W8 F: L4 W# a2 G! F, `
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
6 f1 _5 r2 i' t# E8 E/ f
6 J0 A! S6 u- H# }+ w, y11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。! @9 t' ~) g$ ]) L1 f" x1 z
! Y' b4 Y$ X+ h3 q& `
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
. T. |( C: g) B, g  U, N* }! Q* c: p+ H
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
$ A$ s" \" W6 M% T8 g2 Q! v& e! P0 i$ ?
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。' s7 [" U& T# s6 P+ @
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
# N$ C, I- [) d9 [1 w    function reduce_fraction(&$fraction): |1 a$ Z, E# O# j' e8 e; G
答案是D。
6 o; W% g0 E+ n7 `# V2 u9 Q  r2 \6 K# k! G# k3 r: U
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。* l  \7 g1 I% E! J4 [
6 x' _* N8 {/ }8 e
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
7 a* t! _: X: K: O; l
* q) q/ H/ |) d  u- r+ j* N2 d. ~17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
: p: h& e& P# |0 x" y+ V8 a; ^$ }' p+ F" d2 c: G5 Y, _" M+ X; }" N
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。* `* w* t: z1 `

% ~$ |8 k6 {) J% W19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
$ P6 R$ J4 @7 D
! l4 i" @3 q; s1 z% n7 M20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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