获得本站免费赞助空间请点这里
返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。6 Z. @  g& W! J9 u( ^, J6 u
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。3 Y0 L6 P5 @7 Z/ ^6 n
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
0 l) n3 G' }, M& j
9 N% ?% v" E3 F4 d+ a- N; O" q问题
5 @! y, F) N+ L9 Y" {: ]
% F6 D4 i; y3 u% M1.对象的蓝图是什么?
0 F; G' X8 o+ I
+ b; }" V. z4 B答案:____________
1 c# ^2 K) ^1 S* ?' Z% n
" B, P# j, x$ k5 e9 S, D4 i
  M, F. w) z: V0 @  X/ 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
! I9 q7 B' J* {' P" s" bB.b
! W1 B- T; _% \5 `C.a  n4 t, e( G$ n1 ^. q! H
D.d9 B" I* d5 |, ^# X* t% }7 f
E.e; {* ~' c: G" l8 C
6 I; u% t' b' }: x  d6 k& o1 i

, b2 F( @  j% M) O% |- s6 M6 w, e& p3.如何让类中的某些方法无法在类的外部被访问?
9 ]3 J7 J- n; e, k+ w5 k+ i) Z: S9 l5 ^
A.把类声明为private/ F% D6 G' E- c) d. H# Y8 A
B.把方法声明为private
$ o+ z6 F, j3 Z9 K, |! @7 W" EC.无法实现
: h# v9 O, D1 x/ Z3 b) ED.编写合适的重载方法(overloading method)
/ ?+ A5 g9 a0 c( z9 ^" B2 [" \/ }, {( `3 N3 m+ i! ]

7 h. y5 ^  T6 R9 v1 K! k7 y4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 g/ E0 `. Y9 n, O0 V; {: b0 M# d
* g$ j6 d- ^" W' ?
A.MVC模式; u' b1 A# G; G2 |+ Q4 ?
B.抽象工厂模式(Abstract factory)
  ^# r" U5 d( ~; v& cC.单件模式(Singleton); f2 {& @* {$ b. v
D.代理模式(Proxy)
- J5 r: A# D, J2 |E.状态模式(State)
) H8 |1 s! |/ O3 ]: s0 |7 M) X/ u. Z7 }9 \
! C( [0 w6 q& k6 s! D" R2 u, r
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
/ N" V; U& [' J5 A
, K! ~4 M. z* P1 |: _A.1个, l7 e4 D- l6 V/ v
B.2个
4 ~9 G' F" H$ Z* k9 @# dC.取决于系统资源
. K, S, ~* E, x$ L8 @) VD.3个
2 Y9 u; W" f2 G! v) E( u2 AE.想要几个有几个
) n* [8 j* J9 F0 c; R; M& l
% o) V/ j' @6 i; K, e1 [
) z$ W$ b! ]+ t: e  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.多重继承* p" q6 `$ i) ^, f  z8 {0 d: ^6 J+ ]# ?
B.接口) A4 L' B2 _! z1 H
C.抽象方法
- }& w1 p; F" f3 w* J8 R7 t/ eD.Private方法
# V% s- E, p  x8 U: M  X: VE.函数重载(function overloading)
+ q3 a  P7 d1 Z/ g! y/ I* }& N
. g0 b; n* r: o% q" m2 n) R. N4 h
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
0 H5 Q! I4 c, `, q5 J' m" P) B; w4 C  N9 {2 d% P( e* K
A.__construct
- z: j) t5 H( SB.initialize- s" k& C0 ]! Z1 B+ n: G: a
C.testclass/ {" L; l$ S/ l; G% N7 b
D.__testclass
7 Z* j8 b" T' _6 [E.只有PHP5才支持构造函数
4 k" @" |) F' b6 _# \
7 R( X3 Y( t. W5 n9 a
7 l0 v% u* G  \2 v' S2 E: M/ @8.一个类如何覆盖默认的序列化机制?
1 p# j7 x( C/ @& k4 p" k; B* E  }; a1 x! ~% W1 h
A.使用__shutdown和__startup方法
. g3 d% l2 |* A+ u" S) JB.调用register_shutdown_function()函数$ Q- Y2 N- q& d3 u7 d; s) z
C.使用__sleep()和__wakeup()方法, K' _7 ]5 J& T) Z
D.无法覆盖默认序列化机制
3 T+ k5 C- A: b$ WE.使用ob_start()将类放入输出缓冲中9 a6 Q. O) q% ~! Z% G
6 b' b& h* p! J7 [3 e! K
8 j; v3 m5 v) V/ [1 U4 w/ L
9.以下哪些面向对象的概念无法在PHP4中实现?$ [& i' z4 w" E0 a! j

( b1 h" G. t5 q@抽象类
1 Y- n2 \1 A: Y@Final类
! _$ q5 C' d2 T! O( i; p4 c@Public、private、protected(PPP)方法' A+ n0 w1 B3 y9 n! u! L3 J& a8 t
@接口
4 T2 E. u' T- {" _6 z: Z/ b- N
7 G4 W9 Y# P+ N' Y; xA.抽象类
: Z+ k% l5 u  E) C  p1 L8 kB.PPP方法; n. }3 i, {* x4 h$ l
C.PPP方法和接口
/ p% n, f) k. c) x3 F2 G" @6 ?D.以上所有都不可用
0 o/ ^' [+ R0 \! vE.以上所有都可用$ R7 \: O6 F% ?

& G) {6 ?* @  ^: {% L. C3 t8 o1 B2 y; X6 r, v  N6 i
10.如何在类的内部调用mymethod方法?
" {( `' d. c; Y2 `& A) l. |/ D2 r) O5 m9 q1 [' t- l
A.$self=>mymethod();7 C2 S" p. d+ k( j5 F
B.$this->mymethod();" ?7 @7 F3 P# t  i  @: H9 N  x
C.$current->mymethod();
5 e3 W5 d0 [: c$ l# `; qD.$this::mymethod()8 K3 O( M0 R" R5 v
E.以上都不对% z& M5 n3 l" Q+ ?

) W. [& J3 N* K/ c! F) W( t9 J: ]' N  O% I3 C( F2 ]8 c
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
: c: i! @9 |2 |2 n* ?+ ^+ w0 ~B.Null
/ A  X+ b2 g& V, cC.Empty
8 W) M- r3 e  ?4 L" [D.什么都没有
# c1 `: T% j# f9 u) wE.一个错误- P+ ]! c* x3 c- z8 y. s" B
2 x! Z- a. \3 B3 P- O9 W
( u4 }6 n# D( w' q2 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
% Q) S! K: S8 j( V: G- WB.5
0 l- L$ p2 x8 HC.2& c. c0 ?* G8 p- z2 d
D.Null
' }7 W4 ]" H8 ^* Z5 b& mE.什么都没有2 q7 j% b. c# {1 H6 k- ~: v
$ X% k5 g) U9 k
) U* }' B! N+ h, I8 a
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
3 W! V3 p. q/ JB.10; T8 B: D) P+ e' f
C.什么都没有6 T) |- h7 Y' o/ I  T
D.构造函数将报错
. M3 B4 T! u* `. uE.5105 O4 b! g, H' K; a% _
2 b6 e0 D9 z* r0 K! c6 D# y

; h; p* [$ E$ ^! v14.考虑如下一段代码,执行时,$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函数必须返回一个值
. b; u. V; F* b- m1 y2 eB.reduce_fraction函数必须接受一个整型值
6 G' Y) z( M2 Z9 z* w$ L8 rC.gcd函数有问题1 I+ K7 D+ @/ s3 {* ?
D.必须通过引用的方式传递$eight_tenths对象5 I+ x* T8 V4 I5 ?5 c0 u' q9 d
E.对象的实例不能传递给方法以外的其他结构。
! ~/ J* Z% i4 u4 w/ r2 z; Z; ?1 N, |: E2 y# N5 e& ~  \

% |3 h: u% G8 c& W- Q- v15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法1 G) w% O( S% u
B.生成myclass的实例并调用mymethod方法2 E% H4 }) I0 H  s4 e3 ?% Z" j" {
C.产生一个语法错误
7 E, i( Z" y! L: CD.默认myclass类最后被创建出的实例并调用mymethod()
5 l3 D+ a. B$ i' ?) X) a$ `E.调用名为myclass::mymethod()的函数
3 ~) n: f2 B% O2 N" ?; _
6 a1 x1 ?1 n+ Z" _9 Y
" Y/ p/ v5 w7 i: l0 a16.PHP中有静态类变量吗?
* a; p0 w9 {2 C: [. {5 i3 ^( M) o2 y' Z% K& n4 }
A.有& y. Q. m8 N- U4 a; ]
B.没有
$ r$ U/ N. y  Z0 G3 w( z7 s% M8 j; J" _7 e* p1 Y- l( W

/ j7 y- O) @8 R' r* q% d+ v6 h- ^! s17.以下脚本输出什么?

  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.17 b; ?: X$ D' l# i9 z0 i
B.2
+ A  s: p, Z' K" U) H6 p3 E; oC.一个错误,因为没有定义a::$myvar7 v- g/ V4 j0 ]6 z* Z8 ]4 d/ L2 R7 N
D.一个警告,因为没有定义a::$myvar) q8 |. O  r; w: s# _4 J  E, A
E.什么都没有
, s, U9 B1 {( v2 V) C
2 c7 h* w. _4 H1 z% D
0 J) v$ x9 B8 Q18.如何即时加载一个类?5 q9 ?, _' I" {1 y- q. _
; e; k% q/ C$ u: `( u; E
A.使用__autoload魔术函数- E8 W) K9 b/ v2 U$ S
B.把它们定义为forward类
9 C. r  H3 f* w) t0 [C.实现一个特殊的错误处理手段
" L$ y  i$ j. L4 ]D.不可能5 R" v8 I: w' m& z3 O9 J; O8 b
E.用有条件限制的include来包含它们
  K" K6 h' p7 W' f- E4 y* s$ r: U- B$ C4 g( Y+ M! F: R

5 g" Q. l- y7 v' l! S% J19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
4 a! W% P" P  O% a; ~& A, t% H
3 A; Q3 E" d6 B/ B3 c4 z, y    答案:__________
7 F0 A5 j" {4 T8 X) ~5 w
# \, y* s4 {0 j& x' f+ P# \# j7 \  g) V8 v  b+ I. }1 ?
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
% {: r4 n; F  O& W  y" b" NB.一个错误9 v1 H2 y& U' Z: U% H2 v
C.一个警告8 S: n' I" ?3 P2 ~4 N- ~# \
D.什么都没有/ D7 v" `, F2 T& J9 t5 N

" P, E7 l, |0 r- r; h6 x8 q# |
8 D1 h9 O7 ?' k! d( s* l6 t! b& K' D2 A( V/ C0 f
答案速查: |) N3 ]( @: p
1.类
+ l( `- ~# s6 f' U' Y2 t6 N7 R2.BCD+ G! @, U  ~( h+ c) B% ?# v; l/ v. Q
3.C
9 g$ D/ S5 F0 Y9 x* [- }4.C
2 Q! D* A9 C; J* {! Q# o5.A  l2 P9 c7 D6 F. {$ K- |2 P. h
6.C3 R' O: A; ~% \* I
7.C
; ?" G1 W# p9 {5 s8.C) e) R6 G5 ~. T3 E
9.D
+ P/ O7 P  N8 T+ U: x, @10.B
$ E% [' u9 D, y' B2 m2 v11.D
& L+ _# N6 c1 k3 C+ s* R3 k% c4 ^12.B- @; F& ?( f: u( r/ p
13.A1 ^( b, W& D4 m- z
14.D
8 e7 g  W' g  a% Y8 G15.A( D, t4 i4 F/ A( w/ O
16.B/ K0 B  _( B! z+ v4 P8 x) m" c& f
17.A$ I: _: u* G+ p2 N/ @( _. M9 V
18.D
# u8 }0 |4 a0 @) S: [- B19.设计模式
& Y& P, ?) T" R+ Y  C20.D
; ~+ D6 z; ]; U. E6 E4 w6 `- R' I0 x5 [% K

: s. o; ^, g8 l$ X% [/ C5 ?5 P' ?- R6 N& f6 N2 i; j4 o) h
答案详解
% }) B8 ~2 c% X. C$ J
; f, y# a1 b; P" b6 U1.类是对象的蓝图(对象是类的实例)。8 X8 J$ I7 i7 f& z

# K: L" y$ a4 z9 l8 L4 S/ u2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。+ }1 d0 b: A; b7 ]/ w& f! i: o$ `
; d9 P( e9 z& O5 |. Z1 N/ T+ ~
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。. k6 [7 S6 }' f, r
% L0 l# n+ w/ a1 @2 {) B7 V8 b
4.单件模式可以限制一个类被实例化的次数。
" s& X1 M) O* ]$ c, {; S
" e) w4 V0 z5 i7 f5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
4 c7 ], b* q  {, C" L7 h! J
1 F- q# }& v- Q2 P5 p! ~$ {6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。1 ^- K- M, f9 i+ i2 p+ e
% Q% H+ _6 B, b4 F2 u$ ?
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
  x8 l4 i$ @' f* @  Q7 r8 p: P, h( N$ C7 W) L$ C& ^% f; ^
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
$ }, x: F2 W; V) j( g; J- T3 w4 t
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。$ [7 X+ B, v3 |% C! a" w

' X* M2 Y% j8 [7 P/ D" k10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。9 f$ a7 U! b# X& r

( E# w, F: }* ]) E. V7 z0 Z11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。) a+ @: ?! H2 X0 [- J9 [; a* H, U' Q

% ~) E- q4 l, @/ ^12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。6 \/ l$ V0 n2 e
" w/ z, Q& p/ g$ g- @
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
/ j3 }' h' T- h5 q, b$ X
+ _" G0 h7 ?2 ~* m9 Y; K, f. K14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
' A( [3 k4 }6 _! r回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
5 l% j+ l( {( k) d" U$ [    function reduce_fraction(&$fraction)- E. p. x- s: n
答案是D。$ {( h$ d' S% l2 D" e% k" Q( M$ \
* |# z# d2 G5 O; ~  z
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。# J& ^6 z% G1 R& v) ^* V/ e

( n5 _8 H9 ]3 @. ~) v. v16.没有。PHP4只允许声明静态函数变量,没有静态类变量。+ z9 ~3 s4 Q: X; b* E9 X4 k

) Y$ m* h- N5 i9 L) b$ l0 A$ h6 R17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。0 f$ ?4 S! z$ v) A& c# m2 z
# d( C* z6 B, V
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。1 c2 q" ~' p4 w, Y4 C9 V& }

) [$ g* X, _( i8 T$ {5 D! O19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
6 n6 C2 P0 N: x5 y& A" T; w# o
* o% h9 z5 G7 C: j- H! J% {20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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