Board logo

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

作者: admin    时间: 2008-4-4 02:24     标题: [Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
  _. K- @7 J5 `" n& d: d* tPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
. G; t; {* |6 u& Z9 U# t本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
# `6 o1 y6 B0 N4 V7 B, I+ E$ v, W: @/ V) w9 |
问题/ C6 M4 o! M! a9 K6 V8 q1 _  K" M2 c- b
) b) Y( j. K2 v9 P) f
1.对象的蓝图是什么?  x! `, d1 b9 ?

# x0 A0 R- D/ \, R答案:____________2 |' G: q2 s1 G) R; s

, c9 j* R+ w) u1 c! i9 y2 j0 ^, ]& H
2.以下代码执行后,数组$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
: c$ b2 i* B. u9 Z, LB.b
( o& ~5 T7 \% mC.a
. t" K+ N2 H" [7 FD.d! @- r2 Q( y$ k
E.e
2 m( D+ M9 A; p- D* e4 e% T: k
; a! K; r5 K9 |4 |2 \4 [/ `. b9 M+ v" H" d! |. \
3.如何让类中的某些方法无法在类的外部被访问?$ E9 X: _1 y/ r5 Q! H" I
. H. I$ n, `$ {
A.把类声明为private
# S: h- ]) d- d# W0 T" rB.把方法声明为private, j% e9 R3 ^( w+ Y% o# P' E: V6 M
C.无法实现
% [0 U1 D% {$ e& U$ [D.编写合适的重载方法(overloading method)
  n! i4 |) X: g& z
- l- e6 o$ }0 F: l2 P2 t, i1 d+ w$ S" g! k8 q
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
$ Z7 d1 c' n$ d2 ?/ c: q$ S) Z
( j$ ?1 p4 F3 RA.MVC模式
" f9 j( u! F$ O& XB.抽象工厂模式(Abstract factory)7 o5 i5 d# B1 e, G0 e( @; U
C.单件模式(Singleton)$ M& d( O! A8 e  f
D.代理模式(Proxy)! q0 A& m& |  K" s6 _: w
E.状态模式(State)
7 m- Y9 Y- A( L" v: p2 [! ^/ F2 f# V/ G$ I  J7 ?
& T8 E( g+ H; j, K8 m
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?/ b$ X: O% y- @

1 m" M2 t9 r3 ~# w& y; g" n+ RA.1个$ ]! L& K4 a. n4 o
B.2个
  t+ z5 C3 m9 C5 d( t9 H& F6 EC.取决于系统资源
/ M2 i, ?) [, U3 ]D.3个
8 O1 f  T5 r( qE.想要几个有几个3 C. v" C0 K" J
! T( m" Z8 y$ M) n
9 b0 w2 x/ v& ?; _
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.多重继承
9 K& ]& e, F! U* X6 f5 CB.接口
% e, I1 n6 g; O) jC.抽象方法; G, a9 {  ^; q* y
D.Private方法
2 Y$ c, R5 u/ J2 ?7 |" _6 YE.函数重载(function overloading)+ m7 N$ y7 O- P; b$ n. W8 j( B. R
+ F- z5 u* W( Q0 Z3 C7 N+ a
$ l0 s3 T: {% q- |$ u
7.假设定义了一个testclass类,它的构造函数的函数名是什么?8 V5 B$ v, m) H$ J8 F* G# B  ^% N$ z% E
4 K6 [; I' V1 W
A.__construct6 T1 B1 b: `3 S7 L4 c
B.initialize% [* b6 v% \! }8 Z- g6 @9 }
C.testclass
. I# I0 I3 Z. I) H' mD.__testclass0 s; d2 H! P$ f$ N
E.只有PHP5才支持构造函数
& R! }: s; f, I! |- r
* ?5 }; ?5 `9 J8 y* p1 y, P" q! M: `% I2 C% u& H& j
8.一个类如何覆盖默认的序列化机制?; i9 e6 U, }7 A3 m  b5 S- L2 J2 n

% ], V3 [& l4 {- X! e0 i$ ?! ~% X( H; sA.使用__shutdown和__startup方法, y/ e+ w1 f: z% O6 G' |
B.调用register_shutdown_function()函数
9 P( r% V' H- n2 g& f: O+ nC.使用__sleep()和__wakeup()方法
# \. [' D% }' A0 v, e! c# {D.无法覆盖默认序列化机制
+ X8 q- ~  g; G! VE.使用ob_start()将类放入输出缓冲中) Q+ Q" b& r) g3 M3 E9 {5 |

7 H; n. ^2 S+ M- l$ g
+ w4 v1 S+ Z5 V9.以下哪些面向对象的概念无法在PHP4中实现?
5 N) k% z% @* u- o  y& d* l7 A, `4 _; G  [' `
@抽象类
. ?$ J+ B: X- l6 ^/ T1 m  x) o- e@Final类
; \: M/ c) a9 ^@Public、private、protected(PPP)方法2 F$ @2 I; r8 U* h; s
@接口
5 u* s/ \) ^' `3 {, K" g# C6 ]; _& c! C% b7 o9 m
A.抽象类
' r. G/ m5 q0 t. O+ MB.PPP方法
* }1 F1 g  _4 L: e, wC.PPP方法和接口
+ A% p; a, ^0 t; t% u$ a8 J. GD.以上所有都不可用4 _& C9 T* x* m! a8 E2 s% d$ M, N( q
E.以上所有都可用
. E% z# E. R/ |$ a) @- K2 H
9 r2 }( f, u3 {+ O) r! u) `( r
/ {0 n9 ?" w8 S3 Q" C10.如何在类的内部调用mymethod方法?
" z, D- e' ?, a7 w6 L5 T0 I# N* N! d! _' |7 H- v3 D$ _) p$ w
A.$self=>mymethod();
1 b4 J( W/ g- c1 \4 S$ |9 F  hB.$this->mymethod();6 R$ D+ v& n& i5 k8 e# F/ l
C.$current->mymethod();
, u- y! A+ z+ i; u7 eD.$this::mymethod()+ e. t! H0 l( }* O9 i5 ^" R) u
E.以上都不对, T5 N& q; _" U6 w  g
% `+ u3 @. u3 v) c
* u% I1 i$ C0 c5 L$ G4 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
! y  C3 ?' S. a+ n  n4 c8 X$ K5 ^* q- WB.Null, Q9 n3 l2 V3 `, U% R
C.Empty
" W7 b* o# M# {7 P. O% }+ H& xD.什么都没有/ ?$ Y; |9 M" k( _& \
E.一个错误) z9 f, i) V, ~; }
" S' _# r! C5 h7 i

# e- ~7 y# z/ Q4 J8 N* ~; D7 j12.以下脚本输出什么?

  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" `; C# {% b- n/ ^9 n7 [4 j
B.5
( M3 s$ {* i3 R! P- N1 V4 ]C.2" j- ~, @$ }8 f/ |) R* X
D.Null
2 h- d0 u+ A# N  l; W4 HE.什么都没有& A9 R4 d$ ^: d; x& W  H

! C, U% N4 M1 t- P5 @" l) @* r5 T% [  _/ d, t) i
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
4 N' e$ l) P( ]. K4 B% J/ L( r$ fB.102 o) j0 O! \/ M5 ~, \# X
C.什么都没有" ?$ e; {  e0 q6 t
D.构造函数将报错
. F5 J  `  Z8 n6 A: s9 U6 ?E.510) P3 c4 y8 w' d( `5 k& g8 f

. S' E) k7 }6 b: }6 k4 T1 P0 n( W/ C4 k4 g
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 r# b  q# N. a! A* X! r2 K8 X6 ^
B.reduce_fraction函数必须接受一个整型值
$ q0 l  {, w$ K+ S  xC.gcd函数有问题
7 }7 e0 U) o; L0 E. S! v- o' T/ TD.必须通过引用的方式传递$eight_tenths对象( S1 U( q4 X: e$ N" b" G0 F
E.对象的实例不能传递给方法以外的其他结构。
4 K, A4 W* w5 U& r) ~- b' L, S
  M3 f5 l- S8 \4 `6 R5 {
5 w0 d5 k- o( h8 G7 }15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法2 H) m2 k( H+ W4 ^& x8 j
B.生成myclass的实例并调用mymethod方法4 {7 D. K9 Q) @$ y" o* x) V
C.产生一个语法错误
! ~9 B* n6 h( _! g, C/ FD.默认myclass类最后被创建出的实例并调用mymethod()
% I* }6 x* e; q1 `4 x. tE.调用名为myclass::mymethod()的函数
0 s) C2 R6 b: ^1 c
4 {2 m8 [& ^  m+ i7 B" S) c
* d, d. h! t( f' T! y16.PHP中有静态类变量吗?
, I7 F( @5 s8 Y) s" k4 N
' Q) {+ Q2 ]0 R6 [A.有* e- |, ]$ k: a, Y7 M5 @
B.没有" W1 [( w$ ~  K. V5 W6 @2 W# o
$ |* N& k) D7 q$ R; h/ b5 o
  ^9 w. X3 P+ j+ k$ \$ J3 s& R5 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+ n3 j0 m+ V# d
B.22 F% ~( p2 d2 ~& M# r$ b* i/ @! s
C.一个错误,因为没有定义a::$myvar
1 N+ U) X& L1 O1 M  ID.一个警告,因为没有定义a::$myvar
, Q5 U7 v. T/ g. n& R6 ]! IE.什么都没有
) I* ^5 ~' z$ B+ `' ^- a7 J4 E
! X8 x0 z$ e1 o- u+ q, t
" z* L/ r( X* [8 [( s& e18.如何即时加载一个类?
& l% D8 N( M, ?7 d7 \; E5 l( P1 V
6 B8 N: `& G5 ~  J( J# |A.使用__autoload魔术函数
1 c. u3 b9 E9 n$ E8 hB.把它们定义为forward类0 M0 f$ i8 ?3 C8 }) M" ~9 H3 }
C.实现一个特殊的错误处理手段
. F" V! R7 u' y6 _% r) \6 R" ?D.不可能. K" J3 q# t+ f0 h0 o
E.用有条件限制的include来包含它们
4 [! S* V- y/ s
% m- k2 z" b: y! y  i+ k+ `3 y7 J& V3 N" m% Z+ R# L
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
2 K: ~* F5 E$ O0 q4 k) T! c: D6 A' J# Z& U% L0 s- {- `& a3 d
    答案:__________$ d. |' ^% ~# |. u% n- c% e' ^

0 c: A$ j# ]) S0 W" ^7 u) H5 E* k9 [. H7 I
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" u4 m" ]7 x, Q% |+ |2 n
B.一个错误" M; @$ m: }" i7 S" h
C.一个警告
0 O7 p4 Y* h% {4 L/ CD.什么都没有
- v& |6 y7 B( Q9 N. p7 e0 H& O+ [( {
- e+ r% H; @6 h( N9 ^) K
; W* k7 j; D5 h% N; [$ u% y2 i7 ^$ ~( U( j/ j. k; U) z& z
答案速查' ]( Q3 C/ u7 O+ V" M
1.类5 W( w) L3 z, J- o9 n, y# p* b
2.BCD2 Q4 v' k+ ~5 @
3.C- N2 N8 k: s- f$ a
4.C  t7 J) p, }1 W3 M& L+ c+ ~4 b
5.A, a; B' E6 `. B" f1 j8 I. Q0 X/ L
6.C( p2 q% S4 b& E4 z3 _
7.C
$ J; C# n$ o; m8.C
5 I0 d3 a' z, J; m7 T9.D1 f( u& M! k: x+ F. {/ d0 p2 e! O
10.B* K8 W$ h% f- e% u% ]
11.D2 E, p/ \9 T2 d4 P- U# r% d/ m4 o$ B4 u
12.B
3 [& Y+ e; H$ }1 H: N3 _; e13.A
6 [2 b7 r( H( y! @: N14.D- s% N- L- [0 C+ ?" k2 P
15.A
- s2 f, y4 B6 }) ]2 `  _16.B
+ G, T3 K* r$ ?. |& c+ P17.A% A4 Q1 ]  c' R" A5 D
18.D
: M$ {5 |0 h+ k0 n7 P19.设计模式# `/ x5 d; U5 d) l2 K2 E7 j
20.D# Q6 m) m6 l0 V5 {5 m. k
* T0 d- a8 k( U/ ?2 U
. q* I& G" P* Y  s: P0 \2 T

3 M" ~1 _* b' U( y6 c/ W6 j# _答案详解* i' y) Y9 x: g) K6 y# X4 z
. [" S& B6 P. n7 G6 w' |$ H9 }
1.类是对象的蓝图(对象是类的实例)。
. \+ G/ s$ i- V) [4 A
3 e1 v8 P- _7 |6 N2 \- E( a' \2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。* p; j, n8 i4 e& @
* v3 S. [# n# q9 f5 r1 b
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
& R9 z- G* U3 b, C8 Z) M: s$ W0 q8 Z4 E
4.单件模式可以限制一个类被实例化的次数。* Y' ^' W0 F8 c, d

1 }4 t! z8 F9 P+ I, ^5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。# _5 `" J7 d* e8 Y2 N" p
8 D' u( e! _: E. k9 s
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。/ \" z# p/ w. j; n- C3 z

* ^5 o/ V1 O! T, o1 ?7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% P; X  x% h0 @, l0 @5 m/ f

0 b) P: ]& Z' P7 M6 T7 |8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。) N+ b) M' Q. c+ b% d: h/ \

' }. |5 i8 P" m% {: e5 N9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
7 ]5 I+ Y8 H7 Z+ F
( m# l1 x7 W3 C- d10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
# W: R1 V; g/ V& `
9 {0 K( I; R' n( z; I' N. k  Y11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
/ s0 Y4 t- z, `5 K3 [& w0 K/ X5 V6 j% T, q$ k) C$ `
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。$ n% ]& L6 }9 k
) \1 X! m' `+ C- q3 ^7 I$ |
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
$ F* S6 N# s* b+ |2 w% k1 F& K
6 S0 X9 ]( y5 \# _14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。/ b! V$ R- L' F! r. x& @! L
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
% u. {: l9 i+ y+ b& ~6 C' j5 V$ v9 n    function reduce_fraction(&$fraction)
. {% K% ?& }% ?4 U7 w  o2 T: ~答案是D。
4 e5 L2 U" s( G1 h# n! y$ e
) K  |/ u1 u3 ^15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。6 p6 k  n( s, }7 M/ s5 Q
  j: m6 i! d  \% S. b7 u& e
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。/ Y6 d5 p8 q# E' X
' l7 b0 a: z' {8 n+ b
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
/ N- }) s& G* X4 R1 l4 R" D) e
1 F% t( i" {$ F6 Z/ [% Y18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
& z  M' ~! `; H# ?3 D% Q$ S8 V7 h' o' g6 G
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。! a$ X6 G( d; [5 N3 F) X8 H
; Z/ f* @6 V$ ?
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




欢迎光临 捌玖网络工作室 (http://89w.org/) Powered by Discuz! 7.2