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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
- ^% t/ O; H1 T: h9 bPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。7 x* C4 R% {( R
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。- x. x0 v% Z" a% f/ |

, O1 u6 R# ?) _% X& p问题
+ Y1 n" Y3 q4 h; K7 x3 Y$ P$ _' {: |  V5 {8 x' m  }& P* ?' K
1.对象的蓝图是什么?
  O, B, m3 @. P3 D4 G7 i0 t9 }4 x& O$ U0 B2 H. h! }; z5 I
答案:____________' H0 w% m7 V# l
' [% w) A( a# ^
, c. w0 C, q( w
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.c1 o0 q; t8 T7 ^% S
B.b5 O" g9 ^3 ]9 w, x- ?4 Q$ ]2 `
C.a& Y4 H5 K! c4 E) J5 y
D.d( L3 V* I1 M% T4 P- r
E.e
" z' Z: ]: T4 }1 j& x" m5 x7 l: a( e' g0 V( B* \

7 g& d0 g$ ^+ |$ r  L$ B7 t! c2 Q0 Z3.如何让类中的某些方法无法在类的外部被访问?
/ k* M" n4 d' t/ Z! k0 f7 O- r( M  w& m9 D$ i& w. d+ Z
A.把类声明为private
8 _/ D2 A& A% J) ?$ ^! ~B.把方法声明为private/ t/ i6 ?6 t! _) j* R
C.无法实现
9 S  p2 m9 g7 x: mD.编写合适的重载方法(overloading method)
( k3 k' v! r9 `+ b! w8 ~  W( ~( S  b* h. F% V+ |

! P1 N' [2 s+ L$ b" a4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 X1 w7 S- I' l/ C
# |: A4 t- R& _
A.MVC模式% q: V! g1 T) u" @. S
B.抽象工厂模式(Abstract factory)4 l6 [. T: Y* F
C.单件模式(Singleton)
! J7 ^+ h% X2 [0 Z9 M- }D.代理模式(Proxy)' g* X3 k  w5 @) ^' o3 h
E.状态模式(State)
; t" b0 x6 `! f& e& @4 x5 F
" o) R) x0 \$ J
; f, B. Y: Z% k$ Y! z, e/ m5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?5 V/ T! L. N3 x) O: ]

9 B! L& P1 j+ M9 [A.1个8 e0 ]4 A. B3 T% A5 }9 Q; o* O
B.2个
, }9 {$ `: e0 Z( E+ N) SC.取决于系统资源9 r7 F3 {! y$ M
D.3个
: K# ?- q8 R# Q) p$ jE.想要几个有几个
2 N9 i! N! _" T( }+ a  G& G) w3 L; ]4 U1 z& ]
; F* T- Y0 v4 X/ }+ f
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.多重继承, s% Y. B5 I! P2 [% `: y
B.接口( X; B4 `, d/ V9 ], M
C.抽象方法8 p( p: O, E8 u6 r. @
D.Private方法
' l, j: W; h7 j0 W5 Z2 hE.函数重载(function overloading). O$ G& |+ \0 T' [
5 u7 o+ T. n5 X7 r# ~% c

; u8 Z+ r7 O6 Z, t+ H7.假设定义了一个testclass类,它的构造函数的函数名是什么?. o+ s% w# c0 h) A7 J2 P; T0 f

, l2 [4 `7 M! o2 KA.__construct
' k& m" X' }; R0 b% j  d3 w& S1 VB.initialize
7 T9 r1 g9 i/ t$ Q0 |% n/ {, _, |. z0 AC.testclass( }! `2 l; D7 q" ^
D.__testclass2 f; D: Y) ]6 h" I& A; V
E.只有PHP5才支持构造函数
8 b7 L7 k5 Z0 e
# J7 A! K! d* T6 c. e
8 h1 S, @8 k5 \8.一个类如何覆盖默认的序列化机制?
! L$ H" T- k7 u( c1 I% ]: L3 t9 B
+ ]( U( t) @( I4 V. p# u6 o! aA.使用__shutdown和__startup方法6 Y9 K# A% I( j: \  B6 i
B.调用register_shutdown_function()函数) J5 y+ j4 X/ l5 _6 V8 X4 U$ Y
C.使用__sleep()和__wakeup()方法
% |0 {7 }* E  l9 _7 B' U8 J8 CD.无法覆盖默认序列化机制
/ b# ?* L$ |1 F) tE.使用ob_start()将类放入输出缓冲中
( f5 P7 w& @; H3 ]3 Y3 N9 r
( G! \  d/ E2 h" Q
( B0 z  H7 i  q! @% Q9.以下哪些面向对象的概念无法在PHP4中实现?
, K0 Q! R% L4 ~/ v
3 \! K9 L( p2 ~; E@抽象类
  }$ k6 u7 }  e$ w) x# v@Final类
0 ?( L4 I' W) }" Q! O$ @9 S@Public、private、protected(PPP)方法
9 S$ @: H- ^7 E@接口
, y9 z/ H6 [5 f" W# o- t, z" Z  S' _* C
A.抽象类  e+ d9 I" f: x* K" o' ~
B.PPP方法
0 R1 F- r0 T9 P0 AC.PPP方法和接口- {+ B& Z8 m( N3 M* K
D.以上所有都不可用
/ t0 k4 w& ^) y2 T9 T% }E.以上所有都可用
: p( s: e' _$ C; i5 F3 R' C" z: H' D/ F2 N; @+ O: A$ `
& L( }6 V% i5 ]
10.如何在类的内部调用mymethod方法?0 }9 M- x" P# J+ F

, G, w! j4 C1 G* ]9 KA.$self=>mymethod();
0 C3 U8 ^, }) T7 ^& D. r; ]B.$this->mymethod();7 P& f) {. Z% E" W" w
C.$current->mymethod();$ J: X3 V- U; J- j5 l
D.$this::mymethod()) X6 q: p+ g; f7 n: U
E.以上都不对. |0 x4 S1 R2 E$ r6 s

3 p7 u. @8 ?0 y. o) d1 H; l, K8 a0 Z5 `+ m; k8 Y3 n
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.105 \4 M  p+ K3 R0 g
B.Null; _$ L2 ^' s- w5 m8 T& o2 \
C.Empty% i- a5 M9 E, m: P
D.什么都没有0 x9 x$ s9 B! P" |' r# ^
E.一个错误
3 ?" Z* A6 r' G7 ]8 ?
7 L; W; w( A/ @( l8 J$ Y0 J7 a( g) R
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/ n3 G; P. I- c2 E# A
B.56 t- l; z- \! Y$ ^2 W
C.2
) b6 f4 J; |% R; eD.Null* S& I$ u7 @1 }0 z" l
E.什么都没有
0 X2 K- K! o+ [. w. r4 U6 x2 x9 f. h# @$ e/ U9 v" p7 _
/ @# s& Y1 ~3 X! L: [
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.51 R2 X$ {* s9 Z3 A0 {
B.10
9 [6 L0 K" {2 \/ s, Q3 k" R) B9 dC.什么都没有
  R2 j/ V& ?& t! W" O1 r5 R, N. D* }D.构造函数将报错
. k0 E4 P+ U8 N4 ?) jE.510- Z/ w- R; V, p+ o' V2 b6 G
6 R6 b. D* ?* ^  M" j% K$ g8 J
1 h8 h, S' @% 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函数必须返回一个值
7 G! d7 g5 G! p5 U3 E9 \B.reduce_fraction函数必须接受一个整型值
6 {2 Q( ~0 y. E5 oC.gcd函数有问题
0 U- W) ~" D2 x2 AD.必须通过引用的方式传递$eight_tenths对象
; t4 s! N$ ~- ^# B3 k/ h# H9 tE.对象的实例不能传递给方法以外的其他结构。
3 E$ ]* b! _8 h5 O& @. ^0 L! ^3 F" `; f& {7 \5 }
9 c8 }: G" j/ w
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
5 u9 I$ k9 _3 K) O6 MB.生成myclass的实例并调用mymethod方法
5 ]$ G! J: G. E8 k5 k! q; AC.产生一个语法错误
% D6 o: q" ^  ]- t" k8 bD.默认myclass类最后被创建出的实例并调用mymethod()% n" o, m1 l4 I4 k6 K( t
E.调用名为myclass::mymethod()的函数1 O- n& `% o8 B. S

' P  F+ C7 H$ q; }' |& I
$ j: A; ]* G4 D16.PHP中有静态类变量吗?
( H$ l& ?+ i; S, G6 V6 G( s3 b6 n; n2 H( l; P
A.有0 `/ B, `7 E" ^! y
B.没有
5 s+ m+ Y, h$ O$ P/ S/ Q" a4 F2 e( {: h. s- h, j7 e
5 _# p7 f: J$ T7 b5 {
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
9 [* ?5 O: X8 D; `( jB.2/ R" i9 g) @1 }/ U( E
C.一个错误,因为没有定义a::$myvar: x  |/ g9 M  d
D.一个警告,因为没有定义a::$myvar
/ O% W7 |$ f) u, ]( ]5 oE.什么都没有# J0 Q+ ]& S  r2 G8 A

& n, G2 H, r! s! a
3 l' `5 w5 B, H3 b& n9 R5 D18.如何即时加载一个类?3 H! a( @- o5 S
7 G# U- b& V4 ^
A.使用__autoload魔术函数
2 O# Z7 P5 G9 X- L* eB.把它们定义为forward类
  }" E, \( s! EC.实现一个特殊的错误处理手段- D& D" U4 i9 a' t  G+ Q5 f
D.不可能4 P% F7 x4 [" C1 O1 e* g; w
E.用有条件限制的include来包含它们
9 z8 g9 ]2 v% x& u' z/ F4 M, ~0 i. C/ x9 I% D9 w/ T5 l
2 W6 ?" m% a; x4 l- b
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
3 i/ F; Q* f% ~9 _7 {
$ `$ |% C# \) G9 P4 e    答案:__________5 |5 T5 {# v1 Y  \% h

1 w2 L5 V/ {' o5 a4 ]8 M( l4 D$ q2 r0 N$ I- n1 I5 h' W, w
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
% Q7 Y& V3 v- H, G4 NB.一个错误: ]; N* D; @  W
C.一个警告
5 b. a: i* v. }7 C* yD.什么都没有
9 I8 C7 K  q) X/ P2 @% ?2 w1 I
6 t$ u! _" g# {* g( R7 I9 \: O7 g( b, d5 r: i% N0 j. L
1 i5 z7 z( d+ t/ Y& n! _
答案速查6 W, i) |, m2 u5 A6 e3 _
1.类
( R! S; y  N5 p$ r: v2.BCD
2 i8 D7 d6 [, O3 a6 O8 v" f3 a3.C
, n. i4 R% k8 i2 Y$ E4.C
! Z" O1 X- w% [% E6 E: {3 b% [5.A
4 `( ^  _, _6 Y5 X5 Z6.C7 h" i3 u8 Q5 Y
7.C
+ H; U- f7 \6 D( B4 v8.C
: ^& m1 |. @+ W7 `, b  O* d$ b9.D' U% ?% |( q6 I- X
10.B
: k( a+ `! r: E7 s1 c11.D0 E& T6 y/ W" M* @, P* k$ w
12.B: `4 ~) g+ t2 u9 H, s
13.A
0 _/ i% e' z. t8 j- V# K14.D6 x/ }8 L( u( e: h$ {8 z
15.A, l0 x2 `7 i  P/ R# t5 @
16.B6 F: w1 o. ~8 [, R& F
17.A3 l; T* W; g; c: p$ L
18.D; i' Q" B; h) A( u; @7 X
19.设计模式% _- y0 ~4 g9 M* A7 ^5 r7 q9 p8 s$ H
20.D
( Y. i  L5 y7 F, g7 A' l, n% n5 o
* ]. n: O* c$ N) k" g  r
/ J! `) {& o9 S1 Y8 p8 Y* z5 c- s1 D/ ]$ H4 p
答案详解
" K" B% C7 M. m; B3 K8 U* b  T% `4 J! D
1.类是对象的蓝图(对象是类的实例)。: Y0 d6 S# B2 i- x3 x
  W: K  b. n7 E: G: ]: H
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。8 K( I9 s5 B7 \4 k0 s( _

/ T4 U: S; g, J5 V+ V3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。+ T0 Q. L% U8 u" h) P' x0 o( i
; f' B# a! r: Z* ^1 y
4.单件模式可以限制一个类被实例化的次数。2 y  Q, t: n. l- Y3 A, B
' m2 f8 r% T4 `! K
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
7 R4 H2 x# b0 s- D, j0 S5 p  J7 j) @) ]3 z5 ^) z
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。( \8 a% v7 K- t  v4 @7 @

3 X4 l6 j4 W5 p7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。0 T$ d2 Y% a( d9 {5 p1 G  n
% w. k/ D4 A- g2 [4 x; n) U
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。9 ^, K0 f, U5 L7 T& y
5 [3 y( p% D! y: Y$ x% {4 f, d
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
  F3 n6 n5 m+ Z9 D7 }: c) T/ A2 \7 K( q! j) \$ x
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。$ E& z! f) F9 w: ?8 O3 \

. n4 ~3 R6 r  C3 g11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。2 Q, p/ w% d6 I# ]1 c9 D$ L' c3 `

2 p/ [9 c* A* V9 q, X5 m- Z5 ^' O7 V12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。/ E# S- j6 c' g5 {8 \9 V, _# w
7 K, R" g1 K$ r% v
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。8 t, }8 o+ i5 c6 s/ p# y$ `
/ o6 e7 L0 G/ l0 s
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
" C9 e' H0 G) |) o+ t回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:$ r# z, j; H9 a
    function reduce_fraction(&$fraction)
' j1 Y: C- b9 w. e答案是D。5 @7 z! m4 S; R& t5 [) x, C( i* ?8 m

: g( Z% E8 p' B* F. m1 f15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
: x, B, b  C/ L* W# e: G5 ~0 ?2 |, B4 M0 y$ d
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
, g- H$ t* s9 i/ v7 c
) G* ^; S# U! J% T1 x3 C5 o. z17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
/ A, X7 f, n; L6 a; W8 `, B2 d" V2 {# p1 c5 D
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。" {3 J1 ?& E7 p+ V, }4 c4 n1 s

/ C9 J4 i1 q" y# H/ t19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。9 \1 s2 j& V, D1 u2 T$ y

: G$ [: z% B$ t% i$ Q: f8 W- K! G20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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