返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。* {" [/ q5 P0 _6 [$ z2 V
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。2 g8 E/ `+ x8 S' w
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
1 H% `) V# ~/ _$ ]. E* S( _$ S& P6 N; I% N5 `; c
问题
  A( M/ p  l, Z0 O3 _3 x3 d+ o
1 y8 n3 H8 ]1 W1 b& p; R8 k1.对象的蓝图是什么?$ q: D: {" X. c  a# V
8 L3 Z( d; @2 n. y, X
答案:____________' F0 \) i0 C1 q9 ^+ n+ m

- `# z* }: T1 B: ]: |, M* Y, U
& |& R; w8 m; O  ^, d6 z" E2.以下代码执行后,数组$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( K# Z% w3 p8 Y: S( K- z
B.b
+ k3 J' U4 s+ ]# u* LC.a" o5 R: N$ N  {7 Z: p) }
D.d- g8 u4 M# k& M  G  w
E.e
9 X  j3 G) Q- u0 x' T7 l8 b9 w: z9 e4 [% ]+ E

; i% z6 ?4 M/ k+ {: I" U1 Y% u3.如何让类中的某些方法无法在类的外部被访问?
0 D( z  O% x# o1 C
6 c- f, d7 h0 R0 _9 K* _# n. zA.把类声明为private. r( }3 x6 g# B" U
B.把方法声明为private8 h; p  N# `" u% [9 W3 @
C.无法实现
$ F3 T0 d( D" E3 q. X% sD.编写合适的重载方法(overloading method)
+ k2 T; Y8 b6 ^( \% \7 M3 S/ ^1 y- a
7 w# L' D3 x+ p: b! D% H
& g- G) w( d& X. X& l4.哪种OOP设计模式能让类在整个脚本里只实例化一次?% G! b$ v/ `3 `* U, l0 _! ?/ ]

: }: k+ o9 R; s" q$ iA.MVC模式. {4 }( t* E: r" S6 u% k5 K
B.抽象工厂模式(Abstract factory)
' [, G1 G, {0 D, Z! AC.单件模式(Singleton)* {* `  Q- g- K2 }# v
D.代理模式(Proxy)- o# z8 v" K5 Q
E.状态模式(State), ]9 h7 ], a2 A0 `1 p6 s9 A" e
2 [# `8 b% \7 S; s  C
, t; E, X3 w  s* W
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?) ?: z9 e2 U5 ~* F0 v

" h) V: r& d4 HA.1个; I6 _: c1 z% |9 U6 \" I7 i1 c
B.2个% k, ?: `+ `0 S( a! f  ^
C.取决于系统资源
! ^+ U, |$ X/ m# b0 k, AD.3个0 P5 Z( V7 @" m5 g+ s7 a
E.想要几个有几个( L) {8 K- }/ P
, n" M. X* v  n/ y, U, q$ b
5 I, t- i" u9 i! H
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.多重继承( @: Q! @& n* q
B.接口2 c  V" d1 v9 d2 e; O1 h: `3 o' \
C.抽象方法* p  P0 h  E, e; P' J. c: S
D.Private方法
3 `7 J$ j9 ~8 t: q4 ?E.函数重载(function overloading)5 [, K: K' n7 v+ ?, q
. [+ c3 G. Q8 g' W- i$ o# }
" ?9 [8 C8 w' t! v
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
9 }" G; [$ d. X' l$ f; W( y& Y! b* {$ E+ t: l6 V
A.__construct5 h4 `  j! p5 u3 Z2 k: o1 W. d
B.initialize
# i3 W' i% _- \C.testclass
0 q* L; `3 ^+ @9 u" \: y( wD.__testclass
3 g" L2 @- h# v1 }* G1 U3 AE.只有PHP5才支持构造函数
9 E- T$ ^  k0 d/ v# K
& u; P( _; `4 ^% }$ o( R% f5 [) J6 t
8.一个类如何覆盖默认的序列化机制?
* Q; m: \* W0 @+ I" F, `6 M/ u8 w; L& L6 X, r  `$ S( V
A.使用__shutdown和__startup方法
2 C! l8 z0 _5 n1 c5 XB.调用register_shutdown_function()函数, K7 D( q. o) }* H& @9 R! |8 P
C.使用__sleep()和__wakeup()方法; f. V3 a$ }6 }
D.无法覆盖默认序列化机制
6 X5 M4 g/ j& u1 sE.使用ob_start()将类放入输出缓冲中+ I* o8 p4 Q5 H" ^- H
8 \5 F! }5 ]$ {* E

" ?; X8 }% q4 r  Y; }. W( k' R% l9.以下哪些面向对象的概念无法在PHP4中实现?1 }0 y5 u  p# T4 m

& h# K6 _8 x$ b6 ?4 w1 v$ w3 o- v@抽象类
+ T1 l  E# `) J+ I. G@Final类
. G5 ]- |& T9 G. E@Public、private、protected(PPP)方法8 j- h% l% z  f3 U
@接口! k2 N- l  k' q" j9 ]# H; |% s
0 V+ C0 a, B! W% e2 {& _
A.抽象类  |8 R5 s; W9 S, _
B.PPP方法# x$ |  @3 ]% F- h2 _1 X
C.PPP方法和接口
# |( S# H1 r$ Y# `, CD.以上所有都不可用; N5 D  A5 d' H: Q( V; O- u
E.以上所有都可用& M2 M4 O  S" `7 {' P6 x
% [. \- K, K) v& J  D; ]6 j

  l  V- Z7 W7 M4 u) V6 k0 [6 ?10.如何在类的内部调用mymethod方法?! V1 |& g0 |% R+ M

2 e+ V- v% C5 {* TA.$self=>mymethod();* w$ x- ?# h0 k
B.$this->mymethod();
5 e# d0 c" h4 v* p% t  K; AC.$current->mymethod();
0 ]9 y% v6 }6 d6 z: oD.$this::mymethod()
9 |9 t8 G! i1 V" S) ~8 g4 {E.以上都不对; Q9 g# c' u5 i" p4 u% z/ q3 o: z8 H
& }- M. a9 ?: G& v  d5 A

0 g$ t+ f- N( q. v7 x: V11.以下脚本输出什么?

  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
% p( n" y3 l& i) f- NB.Null
0 J6 R& w% T6 `- P" {C.Empty
$ @) i" K3 B8 Y. {; bD.什么都没有; ^2 q% M: a) P  `, j3 }' U9 r
E.一个错误
9 ~& z' ^. i* c, r; G! G# X
) Y# W: U5 W* Z1 d: z& N) L# z/ j7 x, t5 d3 x  B( w
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* M# V3 R- C$ u% B& ]
B.5, ?) W0 V. }) s' u
C.2  y, X9 S5 C( p, P
D.Null
, ^2 t6 e+ D8 O1 m% gE.什么都没有
' e3 x. C9 A) r/ c( \9 H. P4 `( N6 C/ h( n
, a: a4 U3 Q0 N
13.以下脚本输出什么?

  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
+ }7 m9 _; Q+ P1 _( c" X. WB.102 w; A: @  \9 ~& a) Y, I
C.什么都没有* |' _- j$ |4 w  I
D.构造函数将报错- e% V8 E- o+ e0 U2 [* I
E.510
$ U: w8 l* k8 ^# @* \" ~: G' p+ i5 o6 C- t8 J

+ ~1 Z3 W5 m) Z. S" d+ Y1 k' @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函数必须返回一个值1 V' v- f" G# u* s* A% d( z' D' [+ U
B.reduce_fraction函数必须接受一个整型值
' ~7 t0 r8 Y2 M. l$ G" PC.gcd函数有问题8 o' c+ k3 i( _6 C
D.必须通过引用的方式传递$eight_tenths对象
1 G. ~) Z* m& T: ^( tE.对象的实例不能传递给方法以外的其他结构。7 g8 ]. Q" A, B

; o! J5 u; u2 M4 h* T; b
/ D$ {$ N7 C6 B* {, r1 [15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
" s6 R# s7 }3 m5 V& cB.生成myclass的实例并调用mymethod方法# u0 M% t. O# x* a; c9 d
C.产生一个语法错误& [' Y8 m8 y; h& v0 K. d; q/ H
D.默认myclass类最后被创建出的实例并调用mymethod()
& H4 _% A! q' G& }% |) P/ ~" sE.调用名为myclass::mymethod()的函数! Y& v8 B9 i/ X- n# c4 F
+ C, J1 r/ Q- r/ K. Z: W( u
' u, h' I7 K( @3 r0 b. f
16.PHP中有静态类变量吗?5 q# [8 Z+ n' x5 b# X2 h1 U

! Y" ?- v+ J& K  xA.有0 F5 x+ e$ h; P9 w7 v9 `5 p
B.没有: g1 v# i* O* v, e
/ Y) j0 h& N$ H$ u0 M
+ i  s6 N# f" P2 k
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/ D! w* }: r% _2 e7 G
B.2# L/ J, O3 U4 B( ?' \/ l( D
C.一个错误,因为没有定义a::$myvar$ B' `: e* B' x" n
D.一个警告,因为没有定义a::$myvar. e, o0 v. `6 W7 w# C
E.什么都没有
$ j. k+ d' s1 c3 _6 ], Y+ u- K7 T* W
& d9 H$ T! Z4 g$ C/ y( a
7 Z4 e- b2 l& m0 S18.如何即时加载一个类?
3 Z' y5 |$ r/ e6 \( y3 R. n( I; i
, E. ]" H3 b2 k, U4 E8 m+ z# e8 DA.使用__autoload魔术函数
  k# n' R4 k1 [: ^B.把它们定义为forward类8 H9 l% \/ e! F2 ~# M
C.实现一个特殊的错误处理手段
1 [7 G: D) s8 U8 y* U7 TD.不可能& v" V" x8 @% ^, Y& i
E.用有条件限制的include来包含它们; B' n; c6 {7 s
- ?+ \" O/ L  v" \( U

3 Q' \1 Q: Z" Q9 R# z0 w19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?* }2 B1 Y7 |  E8 Z. A
8 ?) y# Z7 {, n) J- y/ b* m9 e5 G
    答案:__________- f' w/ S  J: U* j: X
. d' S2 y7 i7 _3 y- _% |' D

! W+ B; p, }5 }! t  h0 l" c20.以下脚本输出什么?

  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
* [1 d* w9 `1 I* b8 yB.一个错误
3 d) r2 v5 G# J! o) K, OC.一个警告! v/ W9 _7 T% v- I* G) Z
D.什么都没有
1 D4 D# A& `( K7 L3 k/ a' ~8 l+ L+ X# T
' b, P" x, ?7 J. O' e) E
6 {8 v( C  V  D1 A* W
答案速查4 R0 z7 t, m/ m% T' E+ S
1.类
8 j2 y- g' y, w: ?$ |2.BCD+ }3 |6 N- {7 ~8 f2 z# I$ p4 H
3.C9 h9 D( p  s' w2 Y$ m* C( V
4.C
+ M) Q4 V8 F8 v, Q5.A
$ U, b8 e/ t  a, F/ B+ S& r6.C6 a) N& a) z  Z" {
7.C- V, l" ]/ P( X; f& H4 v) c& C) ]
8.C0 z% h2 S6 h( o% ?+ S4 T5 a
9.D; v2 P/ K9 |9 z9 a* R/ G- v
10.B
+ p) N3 s) Z, Q2 G) O+ C' t3 w11.D
5 @, p% D5 }" t" F( ?1 R4 @12.B1 A/ W; W* U; N3 F& g5 t4 G9 W
13.A. H* o5 ]( ~) f+ D1 H. a$ |3 c
14.D
' b7 e( Y' x# `3 o% s, U8 @15.A7 M& o8 ]5 O( H
16.B
- E1 W8 s* M" Q3 w17.A" g1 e. [2 m$ C4 J
18.D
8 u' U2 ]: S. A* K7 h( _6 r4 R19.设计模式' d# ]- U# a. R2 L
20.D
- U" o, u# Z+ s
% m( f& s. C  ?3 t5 c* G. u' |0 R  |7 j$ ], B& y+ l+ V

; \$ ^/ t, i) y答案详解3 z/ q0 @" J% l4 R7 `8 q
/ O9 I% K( v& s
1.类是对象的蓝图(对象是类的实例)。
, y# M1 c. U$ ?& E( U
. a5 e0 W: j# ^. E4 ?2 l( B/ C2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。) z( e# G/ }* v
, ], j( {/ }: f1 R
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
0 d. g2 B4 J5 W! ^. G& t, z
' I4 y& d; S/ ~! q! Q4.单件模式可以限制一个类被实例化的次数。( y" J! t+ D5 S1 N1 I# [
& V: B9 m) z5 H( ]" f6 Z/ i+ m3 e
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。1 _* A6 x# m& b

. [  M9 _. a4 G% P4 W6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。; C2 I) ]; r2 p

9 e) c6 y9 F. P7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。- I! }5 X  Y9 H: z& l
* ~3 v; N$ L( @
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。; }. [. [* T5 ?/ P% T9 A

6 n* x- z, ~; J% S$ @9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
. W/ t6 r+ Y$ X5 O* ?
& u2 @6 D( C4 a1 t10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。* s; ?  }3 |" g8 Z( |6 X7 t9 ?
/ |- W9 T+ [& ?8 S  N. [3 o: J
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。- w4 W! H1 n" L$ j* n& G, c
" v: K7 U; B( I1 k! [, B) U
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。1 K/ H- k. G& m+ d
3 n' @" F- |) H" F$ A8 |: S
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。' y$ v5 C% {  }
5 q- Z' ^8 h  o; _4 I
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。( Y3 m; x( u& d4 O
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
) c' I; `- s1 r/ i% @    function reduce_fraction(&$fraction)
! P+ p9 l0 t, O; h0 Z/ m0 X1 y答案是D。
2 Z  m0 Z4 d7 B- @/ ?7 B% Q3 L4 O4 f" w: v1 u! U& J1 i
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。! e7 T  m0 w! t

( [# f; R. g: J) M/ a& T16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
( V0 p$ J7 O0 f5 N) V% E1 P- o
3 s  d% V, _9 i2 O0 q17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。5 i6 i( |1 R) X/ F

. d' u. Z$ e$ Q' Z- E$ K; G' l18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。$ [4 M4 F5 t9 M4 T" U/ T

- H: e+ \# f) A: M% M& y19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
% h  S- m* A0 t7 g' ~  A% G6 _" Y2 R; X$ k
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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