返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
  t6 p8 s/ G6 N4 hPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
" n+ g4 y/ y1 A8 f6 V本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
) g2 ~% z7 a( L
1 q( l) j7 ~! S6 d/ Z问题
8 q2 A; q2 I  \6 y9 _0 K: Q8 h6 t+ ?$ G, l
1.对象的蓝图是什么?
" a1 I- @1 m+ H, U( D3 r4 _! s6 a; j  h" `
答案:____________( b# L/ d  {* ?! P) i/ x: v. M
+ o' x; z3 z% b- a

5 K' \# K# [6 F' o/ A' V- K4 s2.以下代码执行后,数组$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  ~) [) ], ^5 v: V9 z
B.b1 |& _  ?' d1 T+ B9 z; i
C.a
- q, H1 U5 q: H3 YD.d9 n; `* X- p4 ~7 g9 s& h( u
E.e+ i9 F$ s) H6 N1 L( |% g

( w' y; H, {  v' A5 S' f" I$ {  Z* J
3.如何让类中的某些方法无法在类的外部被访问?2 Q* s( o- B- q! f

( r8 ?7 b1 N/ y, Z  |A.把类声明为private' }% O# ?" `5 S
B.把方法声明为private7 Y9 r& O$ ]/ F
C.无法实现# H/ S4 J6 P$ T) _# D& O7 X3 [
D.编写合适的重载方法(overloading method)/ `2 T& ]$ N9 i6 q( D9 g: x
* r9 H8 D5 a+ R# m
# D8 w; n: p  J* ]7 r  \
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?% p' M2 }0 y: Z0 p  f
$ U1 O: U) b5 s4 c* U# l
A.MVC模式$ u2 F* q  l0 N0 [0 x$ T6 k7 t6 i
B.抽象工厂模式(Abstract factory)
1 g3 H/ s6 i4 A8 t$ J  ?7 y4 S" A. ~. oC.单件模式(Singleton); k, q, ~' O; r. b/ `+ C) w
D.代理模式(Proxy)0 Q5 B3 O! c3 a6 B7 k9 r
E.状态模式(State)
4 w& F6 }5 n4 \  n9 {
- Q' {& f/ z+ a$ x, d& J
+ x' ?" S; V( e' J  t- w5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?$ T9 U& n; f  d, F
; _3 S2 V$ I+ J: U5 k
A.1个* E) ]& }5 L$ w) k4 I
B.2个, a* Z9 w  u: ?4 p- a, c2 |( c
C.取决于系统资源
5 \( ?# m4 I5 V- s8 vD.3个
4 S/ Q0 Y! w# I: W* i, _& ~0 dE.想要几个有几个0 g' x% z) N; O; h$ y
, B, |. E' s: m5 R/ r8 P/ E; f6 S

% F9 z6 P: y% r* T6.以下脚本近似的表示了一种在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.多重继承
. g5 U" z3 t% R' _$ y* U1 MB.接口
! x6 W2 f& a* x  m' UC.抽象方法) _- t4 q7 u; D8 B$ H+ V
D.Private方法0 ^; ?/ }- l! K$ c. ~. U
E.函数重载(function overloading)
; V, A) ^! p& Y/ }4 b
9 D, G1 y3 c8 [, a: `! C  ^
* ?" G3 e0 |" x0 U! l7.假设定义了一个testclass类,它的构造函数的函数名是什么?
' j, G, r" L& K* b& Q4 a* d
. C( }0 {2 R& w$ g$ {A.__construct
$ R$ T% A* ^# u' [; B4 X' `B.initialize
/ k  G* e! k9 O3 o/ ]C.testclass3 p5 ?3 m5 X- q" F  E
D.__testclass
8 n3 R/ M0 u4 e- fE.只有PHP5才支持构造函数
$ k1 n( B) l  @; K1 a
% J7 z7 |! z/ B! f  U3 n
$ {( P) B9 g# O6 b" Q8.一个类如何覆盖默认的序列化机制?
2 C/ _) u' j1 ~( [. r' Z- A, R: G0 j$ t
A.使用__shutdown和__startup方法
  {0 q  [  B2 P7 T4 yB.调用register_shutdown_function()函数  U8 k. \4 M. f4 c2 ?
C.使用__sleep()和__wakeup()方法
' C9 V+ X5 i- S% QD.无法覆盖默认序列化机制$ F$ S5 Z7 B( {% K  F( v5 r
E.使用ob_start()将类放入输出缓冲中
- T# U! J& F5 A% d; K9 \/ b8 F4 z! `9 C) o
! {. A% D% z( b8 K: r
9.以下哪些面向对象的概念无法在PHP4中实现?4 N) ~: w( z$ ]$ b; R) k1 d
# ~: k" n' h0 N) f: y
@抽象类9 x/ R( l1 r$ w, b6 t
@Final类3 u! x. Q& y( [0 c. _& e
@Public、private、protected(PPP)方法% \7 u* P6 |2 g' Y" u, ~
@接口
% j% q, Q+ S6 M" z- z. r
. ?) ]  s- j4 T( G/ _A.抽象类
$ n. ]5 ]; I5 h0 `( A5 \5 `B.PPP方法
# X. }% U# Q: fC.PPP方法和接口( q. ?" E" `# r
D.以上所有都不可用- u: X" S# K% c0 U
E.以上所有都可用
1 a- d3 ]& u) `+ i# S; |5 w
4 @0 N' n9 u7 |7 O: {6 g. m* G( U2 A+ u1 e
10.如何在类的内部调用mymethod方法?
: A, N9 k+ e2 o  E8 A! F) L# F- p  V
A.$self=>mymethod();
1 C( O% s- h2 {" W8 |. eB.$this->mymethod();
- r& V# s: X  |) N# X/ }3 B; tC.$current->mymethod();
# r3 V+ t% U( \! {. s  D; l; Y4 Y0 [8 tD.$this::mymethod()/ k! f. S* [, M2 q
E.以上都不对: m% O5 @8 g* u2 A$ J2 J/ ]

$ O$ W1 D/ Y) ?% c4 k8 R4 |( w- I  C( w
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 h, @2 L; {5 ]( X0 a- eB.Null' p" S; z& o3 ~
C.Empty
4 r5 L; R6 u( }$ t- j& G. h& xD.什么都没有( A( b% A1 z7 h0 Y3 f4 i6 h
E.一个错误
3 \! v) R. P- u% p" B8 S) G7 d9 b
$ G$ s3 o0 s8 ^' H7 |! [
) a, Q. H# m1 Q0 J- s12.以下脚本输出什么?

  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
: @9 U4 {- e( z1 d* d% }B.5
: H4 w0 A- \4 U+ M3 ~) t5 X; U# zC.2; m  \" r3 s3 `+ E7 o9 m) [
D.Null
6 H0 G& Z* X& W7 yE.什么都没有
5 o6 K- F2 K3 Z# b0 w, {* g
7 ?6 @! I# N: z; M% b$ R* p$ _; _* s7 b6 m0 ^) d3 J) ~
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.57 Z, w5 y) w1 K' m" h
B.108 e2 k( a: _) p% G6 B
C.什么都没有1 ~5 l+ }7 Y, f& Y# I
D.构造函数将报错/ f5 r. O1 |2 ]& O- S' o
E.510
0 \- I6 T* s2 M# v9 q( q) y
  j0 @2 h, i& A: j  o$ ]" ]2 `! I6 i5 h- T6 R+ p! y" t6 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函数必须返回一个值7 m( J! b' J+ p! y5 z4 I
B.reduce_fraction函数必须接受一个整型值
5 @% ~; h* J8 @2 d# y/ t' P" Q: U$ {C.gcd函数有问题
1 e2 ~3 Y& ?4 B0 JD.必须通过引用的方式传递$eight_tenths对象  C2 v5 _1 ~; Z
E.对象的实例不能传递给方法以外的其他结构。. p. U" z5 D2 B1 b2 M' T

2 v/ n5 Q8 d  k% I1 ], i  z2 ]$ J  m  e) w7 \/ J8 |
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法/ }+ a5 Q+ s  A+ U: L
B.生成myclass的实例并调用mymethod方法+ Y" q) j2 U9 ?9 }  q
C.产生一个语法错误: U/ I6 b+ U6 O6 N% P/ I
D.默认myclass类最后被创建出的实例并调用mymethod()
* f  Z( \; I/ f  e0 sE.调用名为myclass::mymethod()的函数0 o, ?5 P% n6 T2 H
* E( R- m4 b( s  Y; J. u' q) U: \
) x& L- s, Y3 a# t2 `+ T: ^& M
16.PHP中有静态类变量吗?  C' i1 I# l  y5 Z: @

% k/ B& ^9 O) L/ `! M6 _+ ?A.有
! d% d# Q9 f/ ?B.没有
4 Y6 P5 `1 c. \- j) l1 p2 f0 p1 ~$ m/ s- z; X. [, G3 j) K
' `* A# ~5 ?/ J- ~% v
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
# W% V2 T) ~% p, z, }& u+ IB.2! j% i9 [, a% Q! a- U3 p+ O5 [( _
C.一个错误,因为没有定义a::$myvar
' D1 _2 k( b" ~) E; xD.一个警告,因为没有定义a::$myvar$ f1 R6 |5 H7 r- ?
E.什么都没有8 I; K8 a  |4 I% v7 ~$ Y

. b5 b; [) t9 X2 |1 i5 T) t7 y. }( U2 \0 Q8 C2 x# _% c. \
18.如何即时加载一个类?
4 d* x4 ~9 @* i/ R+ Y7 c) \& ?
2 j. N% u- j. h8 {A.使用__autoload魔术函数
: b3 W* @: I3 U& I0 ]B.把它们定义为forward类
9 @) }- {' |1 C* f/ n$ w( O" v+ _8 VC.实现一个特殊的错误处理手段2 o6 g! T- L* ^6 v8 R
D.不可能7 ^$ d* x! l) V' t$ ]: J
E.用有条件限制的include来包含它们
, u) v' t  r. }7 N4 k% A5 Y* O# _" X0 l1 _# j

+ X5 g: f! J2 M19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
% ?; v% I% z# S5 R  x3 X" \% p7 Q! [! D
    答案:__________" @, ^0 S; x- S4 G! D

6 @) K, l% L# {9 v' L2 e# ?6 o7 |; V  j/ `& s4 x" [' w  ?  N& X
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
: }6 A5 @# ]7 l7 x1 v8 UB.一个错误
2 D4 b  ?0 x" t3 EC.一个警告
+ g5 @$ C: e' sD.什么都没有
6 \! J) u$ w9 D2 Z. ~+ W
; M9 }0 P& _8 K2 k+ ^4 q3 a$ U/ [- x7 M- D1 s+ e" \
- S. M# D% W$ a
答案速查( a% ^; f/ q; u7 F
1.类
. U/ a0 u6 R9 U4 A3 q/ |2.BCD
1 ]' |3 t) W5 }" d- ]* X+ H3.C" u. @& ~8 V6 r& L9 H- z& `
4.C+ F; N% V% b. ~/ O1 A
5.A$ J3 }+ S+ o5 b, ~/ Z
6.C+ l, c7 c$ h8 E' H1 n. N
7.C2 ~' a/ s# S8 b( s! Y6 K% t. {9 K' c7 A
8.C6 ~8 K1 a" u5 K9 x( }$ y. O
9.D0 {; X* _5 ]5 O+ y
10.B3 j4 e# o0 i# y! N& k6 K
11.D
, o' x0 E  F8 A* t12.B
/ K! K$ E% S) X" y9 ~% C2 M13.A
& j/ e; r5 Z/ I& e14.D
. |5 b- D. `! o/ O: i' A5 r15.A
6 o/ T1 j8 K: F- Z16.B3 T8 N* J+ S4 b6 s
17.A
+ n4 U; N! Q7 k( d, \8 ^& `6 M18.D5 T- J* b9 t/ [& u, `
19.设计模式
* s# v- g- ^7 a1 R7 u+ F7 S6 p20.D
/ r4 d: M2 R- D# l3 D
& w4 k  n- p+ H# E, ~( d0 G. Q& i7 E6 s% g! @

$ X( n4 w& e# G4 \答案详解
9 i( S/ }2 @5 V+ ], [/ V& }
) a$ h6 s$ x3 Z7 y1.类是对象的蓝图(对象是类的实例)。
$ H2 Y% z( m- o. `
  `: R2 V4 b2 V% j( u% `2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。& b* m8 F: D8 A( U7 r
& S' L2 W  q" t0 o% r
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。- |! ~7 K8 h: Z4 b( s3 l* D" e

# @; t! i) I+ u- A, I) z! t/ o8 K4.单件模式可以限制一个类被实例化的次数。
" K. f; z, R# x8 }/ i* M+ y( S
: `/ P' U. b* b" `) _3 z& x! @' V  a5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
' E. J& F3 O" n1 f9 ?
. ^2 K. f6 p/ n! ?) L6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
) g: f5 M! X1 D, U* L4 C1 Q! ]3 X: ]# v: S) e+ o; T' w' ]
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。6 ~" v& _, W# l& {) V0 f! @6 d

1 a" a" \8 v' B8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
+ a6 f4 m/ d2 P0 I' w
8 w* [+ N, o+ }9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
6 I9 J) i6 [& ^* y) {) ~" L0 v) y. I( _& p6 p
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。5 M/ B- n' f: V: M2 b. }- |
, ?0 R3 C' j* r( I8 o! x7 N$ d
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
. @0 `, D7 ^3 H) V, ]; Y
4 B0 k3 _! J) e/ D12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
4 Z; h+ P* P" t* H- X
9 ]9 H  D4 k: a) N$ K13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。- u) D' x* ?# w8 D4 k0 l5 N
9 r8 `. g) s0 h& l* I1 h6 X
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: O) K' a1 b% n
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:/ w. s5 }- _) g: P; V4 H
    function reduce_fraction(&$fraction)  s' v. J& L* ?7 a1 B
答案是D。
# x3 F6 T+ ~- E& [
+ d. D5 z: N5 V( s0 t5 N. U15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。* C+ o& v8 h- u: u1 z* ~+ }
, n+ w& k$ V! t* e! _- @
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。. P: }, M' K) i- G

8 F; P6 S* v, }, O' ~- ^. M17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
9 q( v1 V/ Z# y  y6 `7 S! H  T1 B/ d5 D3 m
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。) _, V# n' f3 Z- k# d! `

" k; u7 `7 E( T+ a19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
9 ]$ f4 H1 M2 G8 P; F4 d; }. A; V. Q! y% g' M' H
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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