返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
1 R- Q) \- P8 s* L# Q) N4 W6 l1 cPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
5 q8 f$ T8 D) [: p本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
2 J5 @- j; s, {' ]* \
& t; \7 X) S# M9 V; a问题3 R( w' Y0 h  J0 L* Z1 [" }
! I7 W  b) t' x% t7 S
1.对象的蓝图是什么?5 v7 P: B: N' m
' F- c  q; K6 l$ i
答案:____________  K" ~$ d9 v- H; R
! ^9 E6 s( M& I" C

; L! ~" @/ R* N2.以下代码执行后,数组$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
+ e! O/ c# h, ~' t9 NB.b
2 ~! P7 `0 g/ F1 f/ VC.a6 j( z, {# J, g! A
D.d% b/ @) k3 z# G' v
E.e
& ?$ @7 D  X; e  j5 E+ L& m9 p2 e2 G1 w7 F8 ]( r
4 t% S" c0 l; b: k0 f  `
3.如何让类中的某些方法无法在类的外部被访问?
$ Z# u' \8 F; q* y! n. Z
; L$ B6 N# K" fA.把类声明为private
3 G$ w0 I5 [) M# l  kB.把方法声明为private
7 ]% l) A) H* d6 [# C/ DC.无法实现! ?) d; Y% y2 ]6 f
D.编写合适的重载方法(overloading method): [$ E  \5 ?& l! r! G+ `

3 \1 K5 R& V9 A5 h- b: F
; `" x( b1 B# F& J6 g  @4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
' U1 m9 D+ K. r& `* w" O+ e# \" A- ~) B, Z2 ^
A.MVC模式
5 }5 W( |0 u9 h  yB.抽象工厂模式(Abstract factory)
0 j8 _- f2 K! [- h3 Q* j& Y' T5 kC.单件模式(Singleton)
6 g# N& j) Z9 u2 M; mD.代理模式(Proxy)
' B5 X! ~$ }* ?- r: LE.状态模式(State)
! j6 V" K5 W5 z4 N2 r" I, p9 y, }: L  W$ l
+ p; ]& h: v* ~
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?/ k6 ~; {, h# z0 j! d  ~

+ W0 D, a6 P, {5 y/ D6 p$ |7 x0 ~A.1个( D( V' ~/ R# B3 K/ y& Q
B.2个
& O* u8 k% L# fC.取决于系统资源5 V0 s6 Q" B, Q. j4 D* z5 M" L
D.3个4 {  Y- [  I7 v$ \
E.想要几个有几个
/ l0 f8 p0 T( @) d0 v" e( W( V' t/ L+ W0 _

2 A1 y+ ^- y3 f4 g6.以下脚本近似的表示了一种在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.多重继承8 v: M- w: P% _* h
B.接口
: B( {8 P9 k2 D! e, M% RC.抽象方法
2 |6 ~+ e) _3 B2 j7 a( _' d+ ND.Private方法8 f: Y2 ]! {! u0 ?: n. U, ^
E.函数重载(function overloading)
1 c) d  U7 g+ d6 [8 C
5 j3 D8 J7 h7 Y* W! T
3 s$ e3 H) d4 H) K! o7.假设定义了一个testclass类,它的构造函数的函数名是什么?6 y% A9 q5 T6 }

7 V! [. q: W! l9 R$ UA.__construct
2 R' F9 u4 q2 k& n- DB.initialize. w( A$ G1 ^, g0 ]' c' O) ?2 `
C.testclass
& ?3 v! Y2 X& _, d  Y+ {9 b7 X1 Z! iD.__testclass
) L. q  j& X' ^* c4 k. KE.只有PHP5才支持构造函数: \) f3 [% `  Q
6 a* k; R  @: Z3 v' q" j4 t

9 l4 y5 a1 w& m3 e: \8.一个类如何覆盖默认的序列化机制?# K4 w( h/ S2 [4 |8 T/ t$ B4 ^$ n
: m& i4 J, k4 a
A.使用__shutdown和__startup方法) v6 I; h; S& `2 F2 y: @. W
B.调用register_shutdown_function()函数
$ T3 q3 e5 p) G/ \+ A  S* B  U& kC.使用__sleep()和__wakeup()方法
% D! [$ s6 |1 `2 T8 oD.无法覆盖默认序列化机制
1 h1 J2 D. a8 D# Y- HE.使用ob_start()将类放入输出缓冲中
* R& t% U4 C# Q
" x. s" U  C+ h" G9 N/ Q
3 w2 e' I# Z2 A. ~9.以下哪些面向对象的概念无法在PHP4中实现?4 {. z  l+ |. r; R. T, C* m

, y$ l) V9 E) u@抽象类6 w! w1 o3 z  d
@Final类2 P) N( L9 {* t3 ]+ \2 G6 i: \
@Public、private、protected(PPP)方法* W! _0 k: I) T
@接口
) w- m% C5 X" H8 ^4 r; D! k" X! r: Y5 g  x: S
A.抽象类
" y+ M5 d2 J* I! n6 W" JB.PPP方法5 h  {- K' G: `. a& I
C.PPP方法和接口
. {' Q- M; j# l5 s4 c$ eD.以上所有都不可用7 Z) F  N7 t- S
E.以上所有都可用
3 g9 t: {7 W" g! i+ ~2 f) x! T) b* t# d9 I$ i7 ]

" b) Z) C8 P& p1 M" R10.如何在类的内部调用mymethod方法?# B" \; y7 Y" Y  f

" [0 H& a2 T1 ~  g  XA.$self=>mymethod();" [" I6 F& v( p2 x
B.$this->mymethod();1 u6 M0 Z7 p; F5 q% @+ |
C.$current->mymethod();
3 i, x3 I' S9 G) V5 i& I3 u7 hD.$this::mymethod()
; @4 o& q/ M+ V- f: L1 y# sE.以上都不对+ i* \5 R- h" r% O* ?9 S

) Z/ p. }/ h& `# r! W
1 U. M" m5 I9 k  B: a' T11.以下脚本输出什么?

  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
- |. n8 s6 b4 f/ l) G. ZB.Null
0 Q6 P" z/ M6 x8 O5 z7 SC.Empty
# J; }5 S) b7 X4 ID.什么都没有
; W6 g. h1 ?# [! i. C! i# O" nE.一个错误, m! E7 C! K* J$ w) Y3 [- D
1 i% b$ X! V+ |  v! `! R$ ]& p
6 W6 w+ [: p+ w  F. o
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.107 ]& y5 w6 I9 U1 Z
B.5  q" n( e8 F* v- v3 ]$ K8 b; v& N
C.2
0 Z* ]! C" b" T# \: D* eD.Null4 b3 ~) ?$ z+ F3 j) r
E.什么都没有
, ~8 B% s/ m  X
+ E6 w# _+ V6 I* p
, m1 h( {! v) ]. Q6 }3 W13.以下脚本输出什么?

  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
% O6 K9 b1 U0 y# eB.10
: t% W" K8 w" _( n3 p) JC.什么都没有6 T9 k4 s/ {& f; {, J& H: ]
D.构造函数将报错
7 l' m7 U) B- Q( C. r9 v0 m3 _E.510
4 W/ t$ s( m) _2 O6 }9 o& b  S* L# o5 j8 U7 G( R

9 B2 w# A( R$ T" L14.考虑如下一段代码,执行时,$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函数必须返回一个值* r( |* P" f3 P, n
B.reduce_fraction函数必须接受一个整型值
6 ?- Q. B9 L9 }9 k" o! g4 H  [C.gcd函数有问题& N& t" M. `+ a7 V0 o) V, {
D.必须通过引用的方式传递$eight_tenths对象) s% B# K' b& Y& S( o2 N4 L
E.对象的实例不能传递给方法以外的其他结构。
& i/ g2 k" x  S# o% m& s8 X: N( u

3 F9 `9 S$ U2 z$ z5 f" N& |- S15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
2 _% \1 S, {. a/ b& L+ {B.生成myclass的实例并调用mymethod方法1 D7 g0 D; y1 ]$ m5 g1 _! m5 K
C.产生一个语法错误0 C+ B* [  E6 ?% M
D.默认myclass类最后被创建出的实例并调用mymethod()
2 q* Q2 g) b; P  H# E# e' {E.调用名为myclass::mymethod()的函数2 X. r! \9 @& p7 Y# t9 S

$ F" c" F/ \2 `5 W
2 _' Y0 I: R8 l" }8 \% r7 P16.PHP中有静态类变量吗?+ u3 S- C' v6 o- s7 G5 D

$ {, r7 K/ v$ p3 pA.有  q( Y# t( v1 M4 N0 \
B.没有1 G4 Y( X7 U, K9 i+ j3 y

6 g3 b$ X1 a; F6 O) S1 V/ J' g
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
" P! N9 i% w& b0 `; |. @B.2
1 L  q0 ?- F& x) q! E1 CC.一个错误,因为没有定义a::$myvar
. L6 p2 W4 _0 b9 O& U" dD.一个警告,因为没有定义a::$myvar
- V$ u- F6 x9 B2 RE.什么都没有
5 \. q; }9 ?. E& S, f0 v
* Z+ m# R# [( Y* V! p/ t1 c7 V& G% q+ X' G" e0 r; ?
18.如何即时加载一个类?8 t6 s& m; ~7 E- e: e2 p. I; z/ N
: E8 n4 O* `& r$ B0 i1 J( N
A.使用__autoload魔术函数
( P8 P' N# U$ J$ f; P$ OB.把它们定义为forward类* F, Q' z- i. p9 w' Y7 I. d
C.实现一个特殊的错误处理手段
: o' [0 c7 e  }- w# U3 DD.不可能+ M1 e: A. D$ D3 U
E.用有条件限制的include来包含它们) M" P  |) _( G! i- N4 E, m

- M7 }7 W3 o2 s/ {( X: Z" ~6 B  u( L  J+ F0 b* U. ^4 P! h# q) J& r; I" F
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
6 ^, ?7 T6 S4 H9 Q* U' N: H
3 L' z, i# V2 f/ m( b    答案:__________/ s: q* C9 \# g0 d2 i
/ D6 P+ ~/ L) W

8 k0 D/ ^( z7 S( S. m2 J% I20.以下脚本输出什么?

  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
* Q* g1 e+ X* B; N  N/ X/ K" ?+ IB.一个错误  g( x3 _' y' c) x% t
C.一个警告
/ y9 K1 D9 q6 @. \D.什么都没有
2 |- I( ]0 s" M% M
, r1 \5 l( Z  }( Z5 Z) k0 U1 `) R9 q* n6 m6 r

9 b+ L9 m6 X: t0 ~! h' v答案速查
, `5 Y$ ]7 T0 D) j1.类2 `4 |7 z! U/ ~6 d. F! H
2.BCD' {  k5 C: \( M9 i4 D
3.C" H4 d9 v" g4 V- W
4.C
. t4 ^# _8 U7 o3 U$ [6 q- e3 S5.A; U9 k" R. h+ \  t! i/ V
6.C
5 m" X0 |8 c6 x3 k6 v7.C
$ b: t+ {; X+ j2 s2 j8.C
, U( b( A0 K" p! e: d& J/ J9.D3 J0 z3 d7 K  e5 z- x
10.B
9 U6 Z6 q: I* w11.D
( P9 k) N1 e8 @8 @12.B% l% B7 E6 K  I; x' \1 A1 `0 M
13.A" {. S% i( V! S: K* E- z0 z& N
14.D
! R  R+ H2 t& n1 y7 C6 D* N% G15.A% {3 @( v7 {% b" t. C$ C* Z( M: k
16.B
7 }# ^) F) g" G, j; E: y6 J( F17.A- ^( R: B  [, r6 w
18.D
! ~0 f7 R- f- U6 i& r19.设计模式6 A% Z" D8 |1 r
20.D
# o# b8 J* I' l: C3 {: S
9 Y" Y( E- ~; ?4 ^! U6 q: S8 x4 I' a2 m- p

0 z4 F0 y0 }: X4 }5 N0 x! b% r5 ^2 Y答案详解5 X' {; d6 d9 a% `9 w

6 s4 V& _' V- A5 a: x1.类是对象的蓝图(对象是类的实例)。
/ f" a: ?% [: j) P: d" d% N4 A0 {( _7 Y. M
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
4 {3 R; ]- T! ~4 i9 M5 ]8 v" Z; |6 b  X( r% i  n" ~1 k) {
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
- ]2 m7 T9 h/ c9 O  [$ S$ b' e7 b6 ^' k; A. u
4.单件模式可以限制一个类被实例化的次数。+ @0 B" j1 D+ R8 W' g6 |# I6 r

& r7 p2 A9 w- G9 z& M" F6 E5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。: B% t! [8 R6 |" l7 S! J1 Q8 W

% f: l5 b8 L- u; p3 J2 U% \' f$ M6 G: P6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。8 I* T( ~1 @9 j0 [$ @* U; q, S# i
  S4 f2 W$ F' E; G6 E
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
* j$ m) m- U0 u4 o* s( n1 y2 W$ ~6 m! Z1 f
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。/ H- f8 w* s9 o( W0 \5 n! x# @

) N! b; ^/ I3 R" j# S) H" n9.PHP4中没有题目选项里所列的任何一个概念。答案是D。' h) N; `5 |9 [0 Z" t
! ]* j& q4 A! n2 i
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
/ M* P& b9 s* H5 x7 l& W/ [. J4 G1 P
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
5 F; G$ V) R+ U: H) P8 y. ]& G3 i- n4 n. r
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
* @3 i1 b, _& |  Z( B# [
: d9 i/ }7 c' k$ q2 L13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。* ~  j! l  F& S; h5 E
+ _- x* y! k) A# D3 l" d
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。1 m9 p$ G0 }, d
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
, W: H; Y$ `; p3 a1 }( d  Z" q    function reduce_fraction(&$fraction)
5 a9 ~; A; P7 B' H$ |  c0 {答案是D。
/ B! B5 r5 Q, J! c1 X8 J5 M
9 a! f+ X9 K$ X  W15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。0 W, o) p$ ~1 [% w+ Y

& v& T& p0 e; D$ V8 P& Z( H, s( o16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
/ {, B' r& ]' Q1 i* Z3 ]6 p
3 W  U4 |1 |/ C, j' q" m17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
' L, F0 k4 u, e$ M' I+ `* {; e0 B3 ^& }" D. y
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
5 d: c* m7 T+ d% R/ {+ x8 q0 {9 C- k' |& {
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。. N. r2 E: W, |9 m' i7 J5 G

2 X& f1 k# N& a0 _20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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