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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
  e9 P# g$ W- V! M  _* gPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。3 Z1 X. o. I$ Z" w, g/ F
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
& h! g+ Q. k/ h- D3 N
+ U0 y( v! U7 V6 `问题; E+ A* W2 }- B9 ~
' q4 r1 z/ d1 Q7 ^' S( N( D
1.对象的蓝图是什么?
8 N0 A$ y" G& r2 F0 c
; @" `# o4 X  X2 l- w- o答案:____________
/ w0 k# x) S! V# j7 E' I2 h+ j1 G' N1 f7 ~4 B6 ^( u5 M$ I( g5 a: W

8 y- W0 V; V8 t/ Q* W2.以下代码执行后,数组$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
- S: |: A0 M' t: P, G' x: bB.b" h" d5 a+ a! D0 R  K7 v
C.a9 N' X2 d( R1 ]# }+ P/ M, X, |* z: c
D.d
, q6 \0 h& ?7 Z8 G4 zE.e  n5 Q" u, W: z! s
( o" x% s$ E* Q
; q# R) l7 S% j
3.如何让类中的某些方法无法在类的外部被访问?7 M7 j* J1 D3 n; B- s

; Y! S! Y- o) Z6 [: b# d0 n7 ~A.把类声明为private7 A8 Y" Z3 t6 ?; w
B.把方法声明为private
. p" }9 J- l8 N5 zC.无法实现
3 u/ \! p; T: eD.编写合适的重载方法(overloading method)3 @6 {: o. ]- O! p, f2 j
: h: C2 J: k% L" F
( O& F' w! r8 A1 R; l# z
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) n4 u; ]' K8 x" L' }
- n) g7 B, W' [. D) K# ]
A.MVC模式% D& e: t! r. z1 L4 Z. n) f& c) Y
B.抽象工厂模式(Abstract factory)- q- y$ j7 n/ W0 P& w) h* k4 q; t/ j
C.单件模式(Singleton), R6 t; l% p' O: p
D.代理模式(Proxy)4 w% H$ c: M: d0 c( q) E3 ?! T
E.状态模式(State)" n( v) P2 [; C% s# z8 k" j

1 J$ Y" u, _$ W* d( B1 P3 c, u6 K1 E5 S: `7 d4 W
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?0 ?9 R/ J, G) v% }- O
  m/ ?2 p7 \: g7 n
A.1个
# a/ N) L6 _% l* u. G9 [B.2个
) ?5 _5 a) f! I3 n2 _3 P# \4 |( yC.取决于系统资源' Y# D- k' g, T2 i0 D3 b
D.3个/ m5 I  |9 B9 T
E.想要几个有几个
  a/ o4 D/ y& b( p6 k  d! `+ }, ~9 t  T6 ^& [/ ]2 |
! i9 k1 r% }1 k: m( g% L7 J: 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.多重继承
1 ~& o4 p$ z/ K* m6 o% P6 e/ FB.接口4 q% H) T9 z0 J' n) n2 _) m6 f8 s: P
C.抽象方法* k4 w) V  [% j; A, X+ p
D.Private方法
& G1 ^: @* ]4 O0 t: }: @! m* gE.函数重载(function overloading)
! f# C- \+ \7 b. O  \) h/ @" z
! D5 \: U! }8 V( ]( w$ T; |0 C( ?! q  P5 G( m5 x" \3 `
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
9 y8 e5 ^  W; w& G$ l' o4 ?, g$ C+ b
A.__construct
3 l/ w# o# ~0 D# k# {( S' NB.initialize) f" T+ L0 w1 i  F+ ^5 ^
C.testclass
- q$ o# S- o8 N5 HD.__testclass$ ^3 ~2 X3 e& n# ~9 P# ~, o. R
E.只有PHP5才支持构造函数( F3 U8 o: z6 u( D1 G' F6 \

: R' t/ J  ?" j: P/ u4 y# v
5 d0 K/ S3 Q; A9 \" B8.一个类如何覆盖默认的序列化机制?. h! b* f6 A$ u+ ?
& h5 t; `1 \, D& s3 u2 i( S
A.使用__shutdown和__startup方法* S8 X4 R7 T7 l8 a( C, W
B.调用register_shutdown_function()函数
2 p9 Z: V  G/ C$ ^& LC.使用__sleep()和__wakeup()方法+ ?- V/ L( o' F- W: u
D.无法覆盖默认序列化机制/ l  Z: D2 n5 ~6 [6 G& d8 y
E.使用ob_start()将类放入输出缓冲中3 o6 F: p/ T, ]0 g) e

2 |2 S, v7 X6 w9 N& |0 R7 T
2 N5 a  A% G! K2 e: d1 |9.以下哪些面向对象的概念无法在PHP4中实现?, F) E, E$ v0 Q, Z' s8 B- b6 F( M
) Y% y/ H) k- j  M/ X- \! e% A
@抽象类
! X( d& D7 K9 e# F# T@Final类# \0 e0 Y9 v% A# I( f& [7 d4 U
@Public、private、protected(PPP)方法: @$ t6 s+ u# f' o' t; ~
@接口) \  T6 u' z+ T
; J$ q; I, i$ _; t: H) j% u
A.抽象类3 l  I, @2 W+ q: }) w. N- g) V) B
B.PPP方法" \+ p% ~2 y# G6 m4 z
C.PPP方法和接口
' X2 U* z5 `% `5 cD.以上所有都不可用0 c; ]% X/ r+ q1 V4 k$ m+ Y* Q9 l: w
E.以上所有都可用2 I( e6 U5 q+ d
% r# @; ^: r1 R# ]# P5 D& ]6 e1 ]' q/ ?
5 ~! j' S- {& |) C3 k5 @+ p
10.如何在类的内部调用mymethod方法?' ~) i6 w: A) A3 b, c2 T

; B$ z- G$ [/ ?  X$ J0 dA.$self=>mymethod();$ `5 n0 D7 n, L, [, J5 z3 W
B.$this->mymethod();
! P2 |" R9 ?" ]  [1 EC.$current->mymethod();$ T6 u( O  G% s# H
D.$this::mymethod()' o" \$ {" W& I
E.以上都不对
3 |( G, A- O6 Y1 ?' ]5 y" e) L
& i8 \  |- D# W$ |/ S( i: R! X! f9 E% C$ Q/ f$ p! ]4 i
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  o. B, `5 j& u( H5 P1 S1 i
B.Null; K! a% K1 P/ r+ @2 E
C.Empty4 H4 X* ]8 M- z- C7 u  ]
D.什么都没有
0 g! R: X3 S$ |6 ]$ BE.一个错误2 V) j3 m+ V( ?# m0 b5 j( N5 j0 r
: E0 W, g: j# i# Y6 X& m6 E% j$ h( z
3 l- O  v3 |% C9 j4 |
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
; @1 A" b' G6 u' c3 A+ V( pB.5; j- ~' ~& o1 \! N! c  n
C.20 b; P: O4 ]" o) N, F% {. U
D.Null
+ Q+ ^" h5 C: G9 r) C9 P1 dE.什么都没有- s+ M9 E! u2 E5 x  e% M& P9 ?
8 V" j0 |) u5 o" m; `3 O4 |) @2 n/ z- E
. ^) ]) `% y% U6 F: u
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
' K) N) U- j9 h" O, B+ {$ l$ D  r4 ^B.10
: E9 V  |/ J! m+ mC.什么都没有  X( S$ R4 |: S2 `# ^! n
D.构造函数将报错
: p$ F  S' t: R0 W. m% HE.510
8 s4 j: K$ J- h2 P- E
% V* h5 S9 T/ O$ z
4 B9 O2 i0 l5 q3 A4 K% G: w14.考虑如下一段代码,执行时,$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函数必须返回一个值
0 X" v; |; ]3 f2 P1 IB.reduce_fraction函数必须接受一个整型值/ T5 c# P+ _. T  M. C: D
C.gcd函数有问题
8 v3 a" C. d3 I7 Q$ |9 O1 r1 ?" l2 DD.必须通过引用的方式传递$eight_tenths对象
& Q! S: x: |( d8 I- J; g# x: J$ nE.对象的实例不能传递给方法以外的其他结构。
! v  w, H# m/ S+ t$ w2 [7 `) t9 @  }, D5 y0 h1 _8 U5 p' D
  L. D3 E& s1 `0 U
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
; F- z* m" ^- z7 S" Z& FB.生成myclass的实例并调用mymethod方法) Z: a0 K; @% o5 k. x# ]
C.产生一个语法错误
& q" Q6 x; Q/ JD.默认myclass类最后被创建出的实例并调用mymethod()& F' ?  A* \0 V7 M
E.调用名为myclass::mymethod()的函数
( ?5 ]) g! t% \) B/ D# T% U/ N$ I* O
7 I3 G2 E# t" y; n* a. q  P" s
1 y1 f- C0 r$ u! a; K# b16.PHP中有静态类变量吗?, z! W$ c, |. Y% v! e( v6 g
/ I6 I" C+ H4 _7 R) P# ?5 x
A.有
* [+ `; e. K# C& B4 OB.没有
2 Y  J+ e+ m7 {8 x6 v+ l% a: F3 |5 i8 `' Q
: z, s7 N5 m! S
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( V5 s2 f" a! c0 Q5 L, A/ q
B.2
- s2 L5 b3 e/ \9 oC.一个错误,因为没有定义a::$myvar7 y5 G5 Z; L7 c$ }' E
D.一个警告,因为没有定义a::$myvar6 v3 V0 P, n  H% f
E.什么都没有8 H$ {: U2 }! t( f: ^
( X9 i6 ^& u0 _  R

* Q( I, a$ c+ f% K/ C18.如何即时加载一个类?! _" h* v" r4 r9 P4 L0 }, ^: f
! @1 R' p7 s: `$ _
A.使用__autoload魔术函数
0 d# h  f$ o" a5 WB.把它们定义为forward类/ a) R; n/ Z1 K, P
C.实现一个特殊的错误处理手段+ ]4 p) v! G0 e- o9 H
D.不可能* q% J& u! H& X# t6 H  k3 ?, |9 W/ K5 O
E.用有条件限制的include来包含它们' z. h6 h. ^5 [% z6 M

. V4 g9 r" ~: `' N' J  G0 q$ O: V4 b3 J1 a+ \/ y
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 ~3 s6 U% T) h6 B. [3 [$ b
" }2 l+ D) x. x( W    答案:__________' a. b7 u* O* U* N6 C. k% m3 u
, L& H, x) Y( z; o

: ~3 q: C9 P7 `7 n) r% Q' ?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
& f( o& k, V2 p8 [0 h0 }' KB.一个错误
: j9 E  @. Q. cC.一个警告
! r3 \) n& F0 {6 tD.什么都没有
- a! f* T% q9 E, q3 J; [5 z. {; I" ^" ^( n2 ^# }

* J2 S: q' g- y7 [, F9 [& P5 A" R0 f. B. S4 y5 x
答案速查4 m' E2 h, t1 f" b* \+ h
1.类
+ ~6 v) ]9 e* l% N" e& [' q2.BCD
" n( h' D4 A- _4 L  |3.C
" Q7 s& _5 i: o" ^' g4.C6 Z2 E9 o7 s7 ~) [- l3 ]. w
5.A
4 N# Y- `2 H" u# h0 f0 ^6.C8 @& F; x* |& s3 r, y/ L0 U7 j
7.C1 [# }9 s# e" d" ?/ ]$ z0 n
8.C8 K; {6 _2 t1 a5 Z. i# U
9.D
1 Y/ C4 P+ E; J; k9 s5 R' N10.B; C; L# i% b6 E0 ]; X' m& `
11.D, b* ]4 P! ?8 J7 S! f6 M
12.B
6 D0 m2 Q6 S, V- I# o13.A
  z* n# e- g6 ~* M, r9 \% c% ~14.D5 M; i/ ^( H; A2 W. [3 e) b; G
15.A+ j( c* Z9 Y8 A4 k" R4 r8 y+ I
16.B* q4 ]$ [! n5 W  f1 Z& L7 x
17.A
  s# g4 `3 z* h5 Q0 A18.D
6 V7 ?1 f7 e' Q' `5 d4 ?19.设计模式% |- A4 F2 M/ V% r2 q9 X4 z% ^
20.D
) t- u. P9 _; \: q+ @3 k# s( J% Q. F; X# G  l4 c: e
- j4 u1 ^% P, [$ J' c1 d- h- D

+ q$ j2 `& r: D! z* e" W答案详解
( F: B4 \3 M( m0 \; ^' M" _7 z
# d$ j. F3 d2 R. K% L5 V# _1.类是对象的蓝图(对象是类的实例)。
- U+ X3 O6 W: {9 B4 ]+ {
, P0 m  u' ~2 u/ @3 N/ V2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
4 P5 s, g' M/ }: i( d4 F+ A/ r& f9 B# v& v
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
' H4 V7 K9 y, p. s& Y2 I8 E
( m8 B' \2 W( r' y4.单件模式可以限制一个类被实例化的次数。
/ K3 B5 `  s% i) a- D$ L% h& S4 }- f% r1 X: ]' }  l( @4 P1 U
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。+ ?5 p  H. R) I; D, {: U& M" M
5 S& |% T5 t( {: V. l3 u
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。: |, U) B0 P% A! v8 w! `0 D
4 m6 y: i7 i) K/ w" Y3 W9 E& |
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
+ y. p1 M( |6 W* g1 B5 Z8 n$ o0 B. B+ a) }" Q
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。( |, ?2 u) h$ y7 E! v

3 M& ~$ Y6 c: ^) ^) S; C9.PHP4中没有题目选项里所列的任何一个概念。答案是D。. Z2 `+ _% V+ q0 X7 g5 p

, |/ j$ Q* B1 J3 c, A& U10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
6 X; p. u, v* Y# g% `  o! d
3 w: T) u8 k' Q! r- c11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。8 i6 M' ^6 a# V0 a' d

8 L0 _- w' }% T% N) c12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
* q  y8 L; o, U: N+ F; k( F- V8 H, s( W3 \. K' h7 A
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
5 J5 |/ ?  k* k4 W& @
1 J; T. x$ @( G9 R14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
# M: o) [. I+ b0 S) [1 F. c. E# J- i回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
! [: }! u1 r! I2 J' k3 ?$ V& ?    function reduce_fraction(&$fraction)- O/ Y6 w$ O7 g
答案是D。9 [0 H' O1 k  O+ @4 M6 C$ C
3 c, H; O- `, G# E8 u" `+ S
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
6 M. K1 R1 n. x+ j' ~$ W) C0 `: P6 g
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。/ ^+ g& W2 J5 u) Q
2 D, u  [. l. c/ I
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
/ I' t) m1 A5 Q* g, Y/ t/ Y$ S1 w  ]7 l8 E8 U- d& A, E4 c
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
9 w, M. y) M) S3 n; O1 u
' S+ C( }1 V9 M* L' J. i19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
- k& r7 F! f/ Q# [: b, B) n/ M
% V9 j+ n( d; n$ M5 s! U$ e20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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