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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。# `0 l, H+ t; z! j, {
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。1 ~, ?3 ]) M& {$ s5 a# k# k! R
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
0 g& x6 J. y8 B0 c; H5 z& ^+ v" B' e4 i& N( n8 n7 a' a
问题
3 i$ h% L( m2 F
1 V1 `, E" O4 ^1.对象的蓝图是什么?# s! z" Y4 @+ D1 D6 u3 K% k
9 c3 a5 K% r2 _1 ~2 H' e+ O
答案:____________1 {' c& I. q, ~. E" r- p! Y1 w" f" |
5 V5 l/ j- G* q+ Y8 J4 P7 ]

  \! t/ n4 o" m- I- X+ p& O- `( P2.以下代码执行后,数组$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
# \* e9 P* u1 [! g; M6 V: X; `B.b; m7 W6 f9 j" f- _; @% h( N
C.a; ]. _) n- W( ^3 R! O
D.d( C1 G, I" V( H2 r9 A
E.e; {, c; ~( o% X
" x/ L! @0 x# r" [  l( }

- ~$ e6 \8 B4 F- v+ H5 o% a3.如何让类中的某些方法无法在类的外部被访问?
6 _. H, E7 X0 D3 s! r$ B/ u
8 u: c( p; |5 y) R! r3 Z+ ^A.把类声明为private
, B& D4 `- u  `/ ]& x2 Z- XB.把方法声明为private8 b2 o. q. m& F0 l: O' l
C.无法实现, f4 o# j% _( e5 P/ q
D.编写合适的重载方法(overloading method)0 b& [$ e( k# D5 G1 O
, }; t9 Q* h0 Y1 k

9 w& @7 M& q1 z1 H& `4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
+ v/ O, E" ~4 i/ L4 w3 {% m
% A* Q$ m0 a$ k5 }A.MVC模式/ r4 {4 W; b( O' C1 _" y& S
B.抽象工厂模式(Abstract factory)
+ W8 ~) T* u1 r# d! uC.单件模式(Singleton)
$ P+ X0 R! N( E3 @( xD.代理模式(Proxy)
, m7 w# L" W: F$ iE.状态模式(State)
8 E( R: k3 Q. F: Y) W2 W7 a/ p- R
; }+ t6 w. w7 N( w) r, T! l, i- i# @. `9 b2 x9 \1 x3 A5 e' W
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?) O7 N; w( v) H0 i; }
$ `! d" }  E% e& L$ o8 D# H
A.1个/ e( m$ e* m/ E2 |3 I# W% g5 i
B.2个+ I4 [' t2 [+ y( m1 k6 |  j$ _
C.取决于系统资源- s4 o. t! W- b- l; Z: q
D.3个* E  J; t/ [5 w8 n9 }1 h5 v8 l
E.想要几个有几个
) S$ V: H; {# r9 F: x8 u
4 y4 R+ G7 }3 o! A7 e* \, `4 s0 c( ^, g0 d2 P
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.多重继承
. L/ j7 w* O  b7 [% x0 N+ ]B.接口
0 q7 \( O* ?( G' J( TC.抽象方法
) Y* a$ a9 `9 s6 e* l, o3 TD.Private方法
: S; q2 r' }& ]3 b7 r  R- e  bE.函数重载(function overloading)
) D- \1 w4 k: y& h- w
" w6 o5 E& L7 x2 z1 a; N9 [8 g. V
* `# a5 I$ c) h/ I7.假设定义了一个testclass类,它的构造函数的函数名是什么?2 W- g9 a3 j9 |! x1 A

- T  Y! A7 T# A. C+ h1 n- GA.__construct. p. `' O+ ?% B# H2 ^1 F/ P
B.initialize/ u! d- T2 Y# v
C.testclass. ~0 x( `0 d, h. d, X5 i
D.__testclass
6 y, y+ I; n& P6 u0 S8 mE.只有PHP5才支持构造函数4 P2 K' C+ x3 n$ j' F6 b

' G) O7 i1 Y4 E1 G7 Q8 N7 M  J& H% v2 a
8.一个类如何覆盖默认的序列化机制?) U5 k; P! b& Z' _1 ?
; |3 r/ [  k7 }
A.使用__shutdown和__startup方法
5 T5 B. b% O0 B0 [5 [4 lB.调用register_shutdown_function()函数3 ]6 X+ h( X: |4 _$ O
C.使用__sleep()和__wakeup()方法
' N" S# g2 H  Y  h4 gD.无法覆盖默认序列化机制
) {" V2 b0 C1 V4 Z* ]9 pE.使用ob_start()将类放入输出缓冲中
$ X" i, b, L6 }, K% `- }
( w9 ?) ]% P/ k5 ~- @1 E& ?  C4 F& w! A* k7 `/ }) s2 D
9.以下哪些面向对象的概念无法在PHP4中实现?
9 F; }+ R- a  g5 f4 t' w6 [3 O  a) E
@抽象类3 \% Z* r/ @% d6 e2 u/ F
@Final类
( |, a7 b. l  D/ @+ G4 F@Public、private、protected(PPP)方法
5 R4 A: w$ H8 @@接口
5 x1 I0 K' _2 j: _9 n& ^& ^6 I7 t6 i# N( Q: e4 g; K
A.抽象类
' D; v/ N- p6 N9 MB.PPP方法9 x7 f/ n' w- M- s' Z2 x
C.PPP方法和接口
: D) w# j% @1 s- z# ?6 }5 O$ hD.以上所有都不可用) ^5 V+ O) n) ^: w5 k. l
E.以上所有都可用7 j# o( e: P4 h* E/ u/ a7 s

$ s( [% a, w9 |, P1 v# x
& `- C: ?, h$ \9 w! e: u10.如何在类的内部调用mymethod方法?! M9 u( U$ F4 e% j# p5 M- R

$ _# x$ s( v% iA.$self=>mymethod();
  z4 d: z& G" j4 i/ Z- `B.$this->mymethod();5 M/ E! V7 G# G
C.$current->mymethod();; F3 P6 Y( v3 a3 `; Q6 _( D
D.$this::mymethod()* Z4 `2 }2 ]3 e' Q
E.以上都不对
. n+ T) h  j5 _1 o3 G1 a
# K; K9 h/ g! W3 v* d) V  S7 ~5 E
2 q2 }3 G( I9 r: p5 ^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' @0 F8 g% L( g' u3 n" H, Z
B.Null4 z: n/ \9 F* T9 T/ e: }
C.Empty, n# l5 r& a. ~5 ~4 u* S& F2 h
D.什么都没有6 {" u5 v( Y7 L' W! o, o: C0 @
E.一个错误6 S; P/ J/ X/ q2 C

0 D0 Z. d7 i6 F5 Q' }8 L' w5 O; b
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% D) q( x0 J  n2 {4 _, y
B.5
0 s) e/ @( a( T" _: \! X4 jC.2
+ S! J, B" i" XD.Null
4 n6 O4 h, J( ]9 W: QE.什么都没有
1 b+ h/ R) V0 x
+ ]9 d$ y% W% Q3 @  }5 l% h
' z, Q! u9 w3 k, P5 s6 x13.以下脚本输出什么?

  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& o5 ?  D  D0 c
B.10
: E* c' Q9 [# GC.什么都没有
0 h1 O1 F; e  G! w. [D.构造函数将报错
# t* |1 y" L: e( s. U9 [  \: iE.510  J6 a* A/ K) d2 S

5 M1 M' j  t* a  b( H
. V8 L/ y* J5 c3 @* o+ U14.考虑如下一段代码,执行时,$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函数必须返回一个值
5 |& p$ J! U# j$ D; ^9 H" l, k9 BB.reduce_fraction函数必须接受一个整型值" F. F9 O% }) v( U8 b6 R* |
C.gcd函数有问题
6 k, Y7 W3 l" X. S) oD.必须通过引用的方式传递$eight_tenths对象4 g1 R  ?; j8 n$ z# p& |
E.对象的实例不能传递给方法以外的其他结构。
9 S9 `+ S& {1 d7 o/ L! G8 D+ ]0 X
+ }/ L* f" @* A# k- \% Y
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法+ G# B! [* }5 S3 @6 q# d+ s7 P8 \; \
B.生成myclass的实例并调用mymethod方法+ q0 J$ m" [2 o9 ]
C.产生一个语法错误
$ n: _4 Q- I. z6 J/ rD.默认myclass类最后被创建出的实例并调用mymethod()- S7 }1 U, o3 Q# U# _: J9 D/ ?
E.调用名为myclass::mymethod()的函数
  |7 r- _6 b7 W& e
# }3 i6 ?2 o; L8 W4 Y3 {! w$ v& g" g
16.PHP中有静态类变量吗?* C$ c% X, @" ~7 }4 Z2 h
2 N) F9 U% M3 Q5 T$ |2 o8 Q
A.有
% R* i0 H" h/ T. B) j1 x+ w' F) CB.没有% |8 j  E! S8 T4 _0 d0 s8 e

8 B- T8 d- I% D9 z8 ^
2 x" V$ ~9 L9 x0 f17.以下脚本输出什么?

  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
8 l9 B2 x, L4 I6 pB.2( H9 O7 N, j+ B$ R& S$ Z
C.一个错误,因为没有定义a::$myvar
" m0 m& O' c( F5 c0 pD.一个警告,因为没有定义a::$myvar
( T0 _8 J% J1 X$ w) O2 kE.什么都没有
* F$ ]* f$ X; t0 U$ E& y3 R% z) F# E4 \: r. `& ]: [2 |) k& ?3 @1 S) h
" R- u" y: y$ V
18.如何即时加载一个类?+ }9 b  f* B1 }5 t

, J' {! x; W4 L0 ?* e* bA.使用__autoload魔术函数
; ]7 H9 G& G# T, E: U& `2 YB.把它们定义为forward类& b' }8 v$ k* d- C# ^
C.实现一个特殊的错误处理手段
0 v( U" r0 z) S' g, N; d7 ]D.不可能
: A, K! Q1 _4 \1 V% S! j. DE.用有条件限制的include来包含它们# L+ J  w. @9 m0 ~! s- |

* {* o; T9 z' P" u& k7 B' x
9 ~, @1 M5 J1 I19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
4 t6 Z4 v) R) a: j& k; ~' T! w3 E  f5 x0 x4 d7 [' c% d
    答案:__________
5 e3 C4 G) W6 A. A, s( v
5 y2 _( M% v% Z  F( a" t9 C) @. K  B; t1 a: r/ G1 e
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
( _- l$ f) [5 c- P4 @5 WB.一个错误! ^; \3 W+ K' L, l  D" o
C.一个警告% ^& w9 u4 Z7 Y5 ]0 d+ {, }
D.什么都没有8 n$ N4 f0 v7 p! e# v9 S! O
1 [+ }4 E" c% q7 m" j* w5 B
+ Z3 H. s5 g* H1 q7 [4 {( e
  D* K+ \" ]0 i( X
答案速查
" C5 E* e( z% O8 f4 @4 e1.类, Z2 k1 P8 O+ g  N6 c  Y
2.BCD
9 A1 A: d7 y3 x: J" K3 i9 T& u3.C
, o1 `3 B# w# i8 i  h9 O( Z4.C
: P, ~8 I- T/ Q3 n" y5.A
% I$ z- b0 Z( ~8 r( B' c1 w6.C
1 C: N8 M: v: F. L1 N( H( G7.C
& U! C9 o, B  P) @8.C
! I: Z  c- I  l6 h) [5 ]3 g9.D
. X3 k# y* H# h6 i3 R3 o/ F10.B
' t# G( x. G- b3 p' d+ N11.D
6 _, `  Y5 I% _$ P* }12.B
3 D4 r0 s0 S  V- @+ Z13.A3 @  e) _* F$ g  C+ N9 A0 Q
14.D
1 k+ Y" z0 g& o7 w7 |5 K$ E15.A$ N) e/ U& K0 I; v. C
16.B  P8 }" k/ W8 h4 p& _
17.A
$ O: {" E( r# z3 S; }) c: d5 `7 }18.D
- n2 n. G  q- t, n! R2 M19.设计模式+ r" ^1 [3 E( V3 c
20.D
3 K" l, h6 z4 J  z+ s  X* _; M" Y, h5 K7 C

& N, ?8 K: H' r) m8 r, Y4 e; v# `+ f2 {+ t* `9 c7 q
答案详解! r  z$ ~* q$ L8 t
7 N* d+ B& E0 _9 m/ B$ i
1.类是对象的蓝图(对象是类的实例)。% @' j8 n1 P( q& A( w5 I

2 g% L9 d9 V) [. E# Y3 v$ O  v& e( N2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。0 ~/ Z% i% h' Y2 \  Z0 p
  i) G# r( x! O( o1 a
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。$ D$ j1 P" @6 r

; q: n7 o' ]3 h7 d( a" b" |4.单件模式可以限制一个类被实例化的次数。
, C& l% L2 B" X, s; L& K) f) N1 }. H. ^1 i4 H3 t
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
* b2 z( {8 O: U. n! W- ?
, _  |+ m$ p! y4 P+ t" t6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。9 @7 x; S9 v1 L2 v- _
5 y; f9 d8 F6 [; U3 c
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。- \& E' i* n# K5 ]7 W! Q7 [- I
) }6 |! o* I% |9 x. ?/ v  \3 u
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
/ `) j2 G& S3 g5 H8 U" g  K7 m
( T, W; V' ]7 c, \; L  J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
8 o6 p, F/ p9 W1 ^" Z/ z% D  _5 N- x/ r4 g
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。" a3 J' b5 W  b$ i' I
- `* H  g+ H5 y! K
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。& H! M1 [; k# q3 q& r4 B( @: \

0 Y& T( T& C# V/ S: X3 X$ D# T- H, E12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
) I# q5 d! ^$ D" I6 l! d) {0 ?  N* X+ s! Q
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
2 O7 Z" w. n+ k( f: a- Z6 q6 ~/ X7 D8 d" \  j5 E
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。& @& f& W* B( ?5 U0 ^5 \4 I
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:4 H/ r0 Y+ B6 W: N
    function reduce_fraction(&$fraction)
% L7 j$ p9 b" s答案是D。
2 h1 _" o% F/ V3 b% M% v( J0 Z/ i
' {+ ]  m, e8 s/ ^. l* Y15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
( C- k3 Y! r; i$ s; m/ g8 d6 S
1 t: p" u9 h! f+ U; ^1 s2 h& h4 L16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 n! Z7 m+ D: }9 i( F

# ]$ c* d6 g( K% C/ C" b17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 F7 K6 S# f6 M" E8 k  s1 z; t; a  f. O# s
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。! |  c  Y3 |5 G) V# ]1 _

* I8 h9 f; W* q  B19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。0 T2 l% o9 }) N9 g+ {1 R

* N9 s/ H- j6 T20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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