返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。; m5 o6 o# L; g7 i) {9 i3 w+ `
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
' _! I. ?5 u- c( y) g. Z, Q本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。9 }( g0 K. [+ [+ ~4 V

$ I, I) R3 N( d+ F, d问题+ _2 S9 H) d3 u7 ?+ ^
7 K% ~# J7 U; y# h# U! \7 o# z
1.对象的蓝图是什么?' I  a, v! t% w) R* d- Q

; i5 c  I2 Z% U3 o- l答案:____________
* o: ~: e0 b1 l' B4 N3 e' i7 W- Q% c9 q! q$ R

2 L( Q9 I) \. Q& w# y4 j) Q) D! z6 L2.以下代码执行后,数组$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
  l# U, q% `7 J5 V: uB.b$ A7 R. C( B. R# g5 o+ \* Z8 r* {
C.a
# `) d2 M' }. P5 m( ]# OD.d
/ Q3 ~$ ~1 L/ vE.e
9 D1 u+ ?8 H+ d0 T2 l0 P$ _
7 P: l$ Z! r: e9 e$ q6 q3 {! F' p3 V3 I% K2 g* ?
3.如何让类中的某些方法无法在类的外部被访问?; r; Z! g$ r; c( h0 O3 ]. K
  U" d- U3 e( y$ H7 G( R! u' L7 W
A.把类声明为private
- p( N! G7 f3 {8 @4 W8 J1 N" i& jB.把方法声明为private
0 H: U0 Y! |7 K. y- qC.无法实现
8 X7 H/ _6 X/ ~- eD.编写合适的重载方法(overloading method)
: S0 D2 J& Q/ V% _2 Y' o
7 B* \7 y, \" B) N) ]% t( t/ B
" o! g: \3 w+ D7 z4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
1 c# P2 i' U+ V. t
3 |! X  @* N2 ?1 w1 J! W! O; w; qA.MVC模式; h3 O0 l; @" O  i' |
B.抽象工厂模式(Abstract factory)
3 j, |! R5 M4 z! e' v% qC.单件模式(Singleton)2 [' Y9 G7 w, y/ N
D.代理模式(Proxy)- E5 p# F) E( B/ U6 |
E.状态模式(State)+ D" G! Z; {+ T  K+ j% {' w; n
9 g1 G9 M, V. T; ]
4 x3 K8 X- f1 ]; R
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?8 u. f3 O% [, w

! Q, i; [% x( }" x6 w% }A.1个! x. g$ h  b, ]. v9 m( {# M) @
B.2个
1 c4 \+ W$ m. [! e$ IC.取决于系统资源8 U0 k& G9 F: ~4 h; m) d
D.3个
! q* k: w, t0 T4 a" XE.想要几个有几个# r: ]( T0 z/ u- ~( C5 c

, i5 v" M; [5 d; `- C5 M/ |5 k" Y( b/ ^  H/ F1 ^. e/ b! M
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.多重继承
4 o4 M1 x: C+ I: v- c9 l5 w$ n$ NB.接口
. @1 L, b# Y+ b9 p$ J7 oC.抽象方法
5 t5 W7 g& a. U2 rD.Private方法5 p, \$ a" A" b9 W. r) \" ?) F
E.函数重载(function overloading)5 T" @& [* F0 p0 v- e

) `- [' o; y% \
1 ?+ G  l) r7 u, P  T7.假设定义了一个testclass类,它的构造函数的函数名是什么?
9 _) Y9 l+ _" `' R
9 {/ v9 I6 W4 W% LA.__construct. k' \' v0 p0 J/ k! V2 F  O: \
B.initialize- s$ ]9 B. p3 k& b: k
C.testclass5 s! z/ L# K0 q! Y
D.__testclass
. Z% B% i! L3 N! @" PE.只有PHP5才支持构造函数
7 b" M) u5 j5 [' U# V5 A; P8 M+ R6 U/ s' X* w
% t( s+ F" W7 @" t; |; }
8.一个类如何覆盖默认的序列化机制?
- @) k+ J9 @& F- m# l& ~& E6 V" v. U; B1 K* a7 I
A.使用__shutdown和__startup方法5 I0 n7 L4 d0 G& L3 k7 v: r
B.调用register_shutdown_function()函数
6 l/ P! n  u* K* T$ v3 pC.使用__sleep()和__wakeup()方法
% B4 P; L  {" m3 d, F: k( I( lD.无法覆盖默认序列化机制
6 i& o7 D) q" i2 SE.使用ob_start()将类放入输出缓冲中& k) ]. {  w9 r% Q2 o- f

+ f( D7 A, p5 T5 q% R
) R% f- l$ [$ d% p9 t. M5 |9.以下哪些面向对象的概念无法在PHP4中实现?; w* K% c6 z* y0 _

. `3 ^' X0 C" [' h6 y/ ]' q@抽象类
2 w) u" i0 l5 e( b  c@Final类
, @3 t! a6 c" b" U  M1 y4 P@Public、private、protected(PPP)方法! R: {+ |6 q" x" w5 a; ?
@接口. ^  u2 H' J4 E0 t/ r

* B6 U) s0 x1 V/ `! g! I; ~/ ], XA.抽象类$ }1 k7 |9 A* g
B.PPP方法
9 Z4 |) t: }' p$ j; y1 VC.PPP方法和接口0 E5 u6 g  |& L
D.以上所有都不可用% o' o% q1 l6 R3 h
E.以上所有都可用
8 A9 {7 j7 n+ c
- K6 g3 o" h& m: y4 n% G' D
! H5 n) [+ @9 j* z! g. U10.如何在类的内部调用mymethod方法?
4 \- Z6 I0 S( K5 B2 w/ m' i9 F3 i- }/ B4 C+ A
A.$self=>mymethod();
8 Z7 y+ _* _" }* o* d: ^+ dB.$this->mymethod();
2 ^! q' k; S' N; m- p( Y0 WC.$current->mymethod();& ?3 J0 Q( ^/ F# w* f1 X' p
D.$this::mymethod()
9 h+ N+ ~. ?9 u) C8 v$ fE.以上都不对4 F& c: U2 \* T" i: ~3 m
  H9 P' G9 Y# Y7 W8 s2 f
9 M/ P- J& N% o" y' y0 C- o
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" r1 J3 |* i2 B; Y0 @+ @6 g
B.Null
6 {; F; ^0 y: P) h6 l4 m2 oC.Empty! [/ ^2 E$ D) s$ b$ ?# k& H
D.什么都没有
" h6 k% B% |2 [" ^9 `/ |" YE.一个错误$ W6 ~5 V0 i/ y: @: K5 L
5 H. L6 D  R8 o# Y
3 ~. A$ V) n' K5 r
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
0 k, C+ p$ s( F" jB.5
* h. i" A  @8 ~; }1 U; S5 B  n. sC.29 h- v& {) {5 }) N
D.Null7 K1 B2 d! m# v9 g
E.什么都没有7 ~' m; v; p6 u) n/ n0 i

+ x% L7 t5 u# O# c) Q4 h( z
4 Q) l7 ]# g/ [) y13.以下脚本输出什么?

  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
1 d( Z* {& L/ T" l6 HB.10
5 l, C; B0 j, \8 G" e7 E0 GC.什么都没有
! _) I" G6 A2 P+ R6 @0 A9 }% z' }! b+ m7 PD.构造函数将报错
! F1 {9 v- X; N" {! iE.510
8 L& {( i" v* N" j( ?4 G2 H
/ j2 S- P4 |3 L. i& l- P0 F- r
. R; t$ E" ~5 Z; C0 ?' D14.考虑如下一段代码,执行时,$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函数必须返回一个值
1 v. l" ^/ [  J1 Z; [B.reduce_fraction函数必须接受一个整型值
' @' e/ C" b. L$ b4 Q& O9 nC.gcd函数有问题
4 U5 N  n9 `" E: }0 o2 T0 rD.必须通过引用的方式传递$eight_tenths对象5 i7 M, X# \! v: `; d
E.对象的实例不能传递给方法以外的其他结构。5 L4 P) {# j# G9 G7 C
* [; ~, [8 f0 c4 @' X; u( i1 C
& z$ d5 l; [& \  }! E
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法; a  c  |' o1 F& ]! Q
B.生成myclass的实例并调用mymethod方法
* I7 {4 P* o5 Q5 jC.产生一个语法错误% [' _8 z9 ~, M9 V& ?
D.默认myclass类最后被创建出的实例并调用mymethod()3 \9 Q) A/ o. W! S
E.调用名为myclass::mymethod()的函数" z* `0 I% X# T3 Z, x

7 v0 ]3 k/ [5 Y. _5 P8 `  G
; c" t( [- [4 f; P2 e/ z, U- D16.PHP中有静态类变量吗?
. T& u; {, `2 o) Y9 Z+ T5 w0 g5 J3 @: O3 J& Z  y; j( |; }
A.有
1 _4 {7 Z& f3 f; |. J1 N, QB.没有
/ r* n2 O8 ^0 \' Q7 n3 G9 ?' S" e, b% m5 o7 |( g- Z2 d4 x
# Q2 t; }4 p) C5 }: C
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.14 n" {# v1 r# v" ~0 m
B.2
6 o6 `) s: e4 |1 n& r9 UC.一个错误,因为没有定义a::$myvar" A9 s3 f  U9 [8 i
D.一个警告,因为没有定义a::$myvar* c1 G& G) Z( j( @/ @+ C; ]& i
E.什么都没有
% d, H4 r! X" i/ o1 l/ u
+ z! o# ^0 y/ ?9 q. f& U9 C: L2 J" H* q0 G
18.如何即时加载一个类?8 _  N) D- e, r/ f3 F7 y
5 Q% M! v3 e& f. E
A.使用__autoload魔术函数
! Z+ _) k( h/ m  ]% [/ H1 f. dB.把它们定义为forward类: c9 C5 r' k4 j) f, F& K
C.实现一个特殊的错误处理手段
; A- f6 m! n. l! DD.不可能+ G# |2 m6 Y5 ~( ^! `5 d3 z
E.用有条件限制的include来包含它们
- @  u& m. y/ _
, c& ]6 {7 m$ h, x
1 d1 f% c$ K: l- D- D. U, T- {% l& A19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
% ~8 ~7 K7 {: L
( O0 S% z) `2 u6 o    答案:__________* X  N* I0 a* U3 j
9 O3 G+ n$ m5 f7 A
1 w" J( Z. m0 @1 \5 [3 r$ J! j
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
: t% B$ h, C! x4 L+ @5 yB.一个错误
7 G3 v  Y# d8 TC.一个警告
  V( b( V* f$ s1 f5 q6 Q3 tD.什么都没有4 P4 u8 ^$ f9 i& ], ?* j* e
5 ^& p8 N; w: f  M+ p

# p; n% h0 c4 D) {) I# M5 E, d0 \. ^% A, q8 L& _% I( S
答案速查8 J8 |; K5 y0 \% U8 f2 G* D
1.类
* v0 p$ S3 h! O4 o! O1 [2 [2.BCD
  i% a& y$ T9 D+ [1 t$ p9 H( o: W3.C
( B" ]4 r1 T$ P7 q; R. S8 q: S4.C
- M: {. O9 ^/ }- x( o5 Y: S5.A) S/ M; x) R9 c8 l! a
6.C
" K5 ?8 I. r2 G6 y7.C
2 n! g: h* y3 t0 E8.C
( c: K( X9 q2 c8 v9.D$ W- \8 o+ o; a5 j
10.B
. y$ m! ]% @+ A. Z2 Z5 N% S11.D
. A, o' K9 k/ d12.B$ P6 `) T" L: e; j, e& t
13.A5 I4 B- D0 r; R+ g5 t( m4 e* O
14.D
2 p' R, w: O0 E2 _' z0 q4 v. K15.A
  X/ L! f- n2 b8 _# d3 ^9 w16.B$ E4 o3 y2 H! g$ P: V
17.A; p4 m5 ~) s2 T, h( H* x
18.D- l( ^  b$ a! ?4 x" Y( C- K
19.设计模式
# w, U/ n" F6 S: B  o1 {. M20.D
! ^7 g5 n' A9 c2 \2 R# {0 v8 l# S: t6 C2 ?2 R+ h8 ^. a4 F) F1 O* P

, j1 r/ T9 }  T- s$ j: J! m  l% Q. L+ d$ l# G4 ?0 h
答案详解/ C( t0 O2 h; z1 V- w# `- M

5 G. \2 u1 S- ^# d2 q  H: m8 D1.类是对象的蓝图(对象是类的实例)。
) ^' D9 r1 z. Q6 m6 u' v% l! `6 k& ~1 @# ]
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。5 z- C9 h3 G: v1 [2 L7 z; l

9 H5 L6 k' D# Q  V3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
7 ]; j) t% U6 F
8 D1 H2 @) P2 y8 `% c4.单件模式可以限制一个类被实例化的次数。$ R: \; G( ~7 V) `, @- E. j! _* g2 {/ U
) G: Z5 H9 ^! F
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。% Q/ S$ S7 N, M, G0 B6 W

+ Z5 W" N  R, [8 Z" z+ O+ F0 f" A6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
4 |$ t$ p6 F* q9 u' n' r9 Z' K' t0 Q/ ^' ?5 @; k  k0 c$ ^1 k; z
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
% P1 {& E/ J# r! N. \, `6 m, Q  l0 _  w" [4 f
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。" V5 L" Q! n2 E0 y
9 T2 t5 \- M" @2 S, Z/ w
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
, n7 R1 P8 V' ~- r- _
+ v2 _- y: |! l, L5 ~( A8 m, c- E6 l10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
  @  e  S% v, @7 _5 z& w
( g8 {# u$ J# V1 G11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。4 x3 q  x; p& h1 |

$ k6 @" E. i/ z  [12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
: A8 T$ {! n& i" N% ?7 Y0 R: p3 ]3 C; n- n
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
' k, A: G* \/ H* K
; q/ ?3 Z* T1 ?/ Q# Z* n% O14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。( i% E: C& r* K5 X
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
) G8 j- G' D! W  Y& K' G% p, d    function reduce_fraction(&$fraction)
. k7 E  |# h' O% r& T# u答案是D。, G+ t, I' {6 d5 m4 z# X
% l% u4 B: t& F1 e$ W* O& E4 l) S/ N
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。; d3 w, N* n+ b( ~' a
1 c3 ^3 c. T& M; u8 \$ f4 z- N+ _
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。$ F1 D! {9 f, N7 c$ o2 c
% z! ~) Z: L- t6 z
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。. j2 u! t- e  q5 V4 ?5 t" Y
7 R/ ]- e' j  y7 C7 @" K2 n% N
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。  J1 y2 p/ {. {5 f$ |

& E, l5 {1 k( o1 X- T19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
, x( p& j( V4 p3 i3 ~) a* Q! r1 w8 G2 L& F2 p5 M9 M. p
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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