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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
, n# e1 J/ l/ d/ fPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
2 R. A6 l  K. P" ?本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
, \. A/ S, E( b+ U9 |1 u. N
2 g, A6 V$ |9 @9 h! \& S" `# b! a' |+ V问题
5 \: U( n+ j' e" i2 |" m7 d  S2 V# }. ]2 N4 g
1.对象的蓝图是什么?
" N$ t5 G* L& }& ^% j% u: d4 [" L9 Z
答案:____________
- D. i. e) [$ E. E6 Y8 c" b: I9 d9 K- M. \  }

4 B6 L% @! {0 D2.以下代码执行后,数组$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
9 c- T% o4 \  t! I* e( Z, ZB.b$ z$ E" B) j# G+ f
C.a
5 {+ A3 `& J$ R# `: z6 OD.d
0 r8 T; b9 D8 ]E.e
  n: t! e* {* X# `8 m% c: }+ Q' L+ k8 n6 d# q" v  }! X! c% H/ ~

+ A( E  v: [0 ^' p/ d# M1 \3.如何让类中的某些方法无法在类的外部被访问?
" Z; {% j$ z4 [! R# @9 I  O
$ T& l3 D. M/ g, W( i/ ?/ lA.把类声明为private
$ Q* G7 l0 f9 R* I2 I1 B; BB.把方法声明为private; s2 q- m3 M) q5 o- r4 t! M5 m) q
C.无法实现
% |/ g  W  G, P. a: ]& m1 C  bD.编写合适的重载方法(overloading method)
6 S+ {7 O1 [) |' c6 D1 c, g& k7 C, d* `

& v8 p1 p  y& m- f( a7 j9 n5 Q4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 z/ K; [0 k. j" A# @  j
" G0 \; f+ L" v
A.MVC模式' h- ]% C0 U! V# }; N: [
B.抽象工厂模式(Abstract factory)' L/ Q4 P6 J( Q8 A. S" t! x
C.单件模式(Singleton)  t$ M, U2 D4 B4 g; u: q" E4 u
D.代理模式(Proxy)
/ m) }4 T2 ?3 k+ l5 C1 A) UE.状态模式(State)
: g/ w" n" E, r- X% f
" ?4 f9 h) P. ~' l$ E4 f! [/ f: V% v5 j& w8 u
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?% E) K( ~# G) y: c& [. ~7 d

% q# y* Q& }) z! U1 SA.1个
9 ?; ^$ ?6 r" D# gB.2个. \2 ~+ R+ W: M0 j5 N
C.取决于系统资源
) f" N4 O* X( Q& D' ND.3个+ A6 i& z2 a( m1 ~" @
E.想要几个有几个
/ y6 c# q. B/ L, h  m9 \: ~& A1 p+ S! c8 Z
: I1 Q* I3 {0 _2 I
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.多重继承4 T, g6 C9 A: f$ R6 H
B.接口/ t) m5 ?  }% Q0 j5 A2 o
C.抽象方法
# i- a& R5 h0 j' J- G; @D.Private方法
# C+ `% G5 Z6 ]* X$ UE.函数重载(function overloading)
0 H6 c: y) N9 E6 w9 j- s
5 R$ r& D/ u: g, L: {( o) Y2 Z. ]. ?% f, B. W+ `9 ~3 ~
7.假设定义了一个testclass类,它的构造函数的函数名是什么?: p& B" s+ M; g( w, F8 y( ~
: e: q- q8 [1 t" U" Z
A.__construct; q7 G& h4 a' [5 Y
B.initialize: P7 C9 k* O2 ^
C.testclass8 I! ?0 N/ ^0 I7 z* x% T
D.__testclass( _# L7 T* L# ]5 g9 D
E.只有PHP5才支持构造函数
5 Q  A) J+ K* s' ~, y
# K" o$ ?5 j; S' i7 I2 O$ j
( N  U) s! ?: ]% h* M. I7 n* J" K, j8.一个类如何覆盖默认的序列化机制?
  C# p; o6 @' x2 T) h+ r% V
& C1 h0 X9 G* I" U% L/ UA.使用__shutdown和__startup方法
% }5 c$ C  K8 K2 ~7 f3 |B.调用register_shutdown_function()函数  y  O2 W$ |  t3 ^
C.使用__sleep()和__wakeup()方法; i$ k* o; e/ `
D.无法覆盖默认序列化机制3 I& h' p! e. s$ y: e4 d% E7 h3 x
E.使用ob_start()将类放入输出缓冲中0 E' r; U! D4 w) I

% p5 ~0 p5 [  E3 x2 w* }; a
  Q. T/ ^9 s: V9 B9.以下哪些面向对象的概念无法在PHP4中实现?
, k8 n$ x- [' h
+ |; L0 Y3 I" T" V@抽象类" {% X1 n$ o0 i5 R4 `% `* T; e( K) b
@Final类6 j: g6 u8 K  J+ c4 e
@Public、private、protected(PPP)方法
! a; e" L" G5 i0 c@接口6 f8 L- ^3 q& y/ P% P- k
0 H" o3 ?3 `" _! X! G( B9 i1 a  K+ \
A.抽象类
  G  N% c' P& r! U2 {B.PPP方法
+ V, Z6 i0 T1 R5 J! SC.PPP方法和接口0 b  b8 U1 _  {/ ~% \  z
D.以上所有都不可用
( ^8 z! y& W) }8 D3 u" \3 {E.以上所有都可用% d6 `! _: c$ ^4 O& [2 E
9 o* @* W/ i+ ]

' l9 M' y, U5 e% `" G/ v2 ]10.如何在类的内部调用mymethod方法?
- g. A% ~8 ]& n- M2 k& ^' f- {
/ g8 e- u" B0 I* cA.$self=>mymethod();
; O- i, r. }+ R9 e8 xB.$this->mymethod();
- k5 l, D. a' v, g" z4 n3 aC.$current->mymethod();4 W1 k4 t8 r: Z  ]. D. S# R, l
D.$this::mymethod()! h# m- [$ Q1 H" H2 b- V
E.以上都不对
" v1 ^6 r0 }) B7 a; g0 ^6 d5 d
6 D$ x9 ^1 k. q% G9 ?; J0 u1 ^+ m8 C. M
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
7 E# l- h  m: L$ j$ u- G6 ZB.Null
( t( K9 A- s: k7 G! x/ L9 q! h6 _, OC.Empty
% x* o' n+ m7 ?D.什么都没有
0 S; J* d5 ^9 X: f* kE.一个错误
7 K4 }5 x5 ^: n9 N: ]
2 N- V3 J. \# T* w, z7 o' l" ^
4 B  z$ u" A+ |7 d4 b; z12.以下脚本输出什么?

  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
. {  h; I0 a3 a4 F# eB.5$ v; I' u4 |1 B$ T+ F8 |  z5 |
C.2# X* ^* c2 u2 U  ]* u/ f# i7 d1 H
D.Null# q' [" q$ w' L0 s! O$ w
E.什么都没有- a/ F1 r8 y$ `- r  L: u/ e

0 R# B- @7 y8 m: X& R; z" k# O; @% y( Z0 l. G  F# y: y& T5 p
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 ~( [& N5 q$ Q2 k7 e
B.100 H8 }5 u3 A6 d/ u" ]/ s
C.什么都没有
" b1 L) B* i! ]* R0 }2 }5 xD.构造函数将报错
7 X0 d9 z; j, \% \% w5 wE.510
( z  @' c+ c: \9 J# ]( T
5 g% T  R" m5 `4 @& @5 Y$ Y, c( K$ P" O$ ]
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函数必须返回一个值
; g. L3 r+ n# Y5 `# _( \B.reduce_fraction函数必须接受一个整型值% c* M* a6 h- f0 j
C.gcd函数有问题
/ P6 C# i3 Y: J8 Q; fD.必须通过引用的方式传递$eight_tenths对象: j+ w1 ^* t3 e" D* C
E.对象的实例不能传递给方法以外的其他结构。9 _# |5 \& z; {) [6 y! ~
8 B1 `8 m, {& H7 I( Z% X

" S: |8 \# I* m- _3 `15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
# g8 E) Z! A/ r3 s8 fB.生成myclass的实例并调用mymethod方法' E0 h9 \7 f9 p( F% ]* t2 X
C.产生一个语法错误( n% y: R6 K9 B8 j- O! ^/ p
D.默认myclass类最后被创建出的实例并调用mymethod(); |) k4 q8 W0 [
E.调用名为myclass::mymethod()的函数. A: L/ ]8 K# O% F7 D# `" s
) R5 F1 a0 p, Z8 k2 _8 q. Q
! g; g+ T$ m- F7 ~/ {
16.PHP中有静态类变量吗?, N* b; o$ Q) l' d! d
1 ~9 l7 G! u+ u, W5 h
A.有
2 v1 c8 l4 P( w  O! W+ |" o. ?% nB.没有
8 V- v% o# m1 \. S; R' J4 A# }8 y1 H8 ~3 n
, c+ _# @: `9 S: w
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$ J% n. Y7 O/ T3 a* P- j% _) a
B.21 k  {1 D* E) t$ h& C2 j
C.一个错误,因为没有定义a::$myvar
* u$ L, \# E9 c2 u$ ^3 GD.一个警告,因为没有定义a::$myvar' G+ p8 x: v* S  f
E.什么都没有
! a. \6 [- a. e- |/ Q( l2 Z2 d( c4 [! q7 m. ]' s2 A4 k
7 K) ?( _" Z/ A% Y7 s3 l$ b1 S
18.如何即时加载一个类?! ~; q0 e8 |6 k+ ~2 |$ [
% @" V( q$ d* H# w& s3 D9 A! J
A.使用__autoload魔术函数# y5 w/ R$ M4 n% X* S! \$ e
B.把它们定义为forward类- p/ l3 ^8 D" Y) z
C.实现一个特殊的错误处理手段
/ H5 ]: j/ Z9 ?6 Y' xD.不可能
0 ]0 F8 Q8 j3 U& Z/ qE.用有条件限制的include来包含它们- f% }: n0 p, N

# W( S. h( N, d, G8 ~/ Q# ~+ _9 H# ]) e% ]3 E' n5 g7 y6 Q8 {
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
6 d; y2 V6 X) r8 y: d
' W4 w4 Y* a0 `7 J    答案:__________4 K0 G! B% w; D. H& o' D$ W3 W: J& _. q

, Q# M; X: B( O& q
+ g' [, M- |  k& r20.以下脚本输出什么?

  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+ X% d+ c, R  a: O4 ]
B.一个错误
7 p2 ^' b' K. S0 N3 BC.一个警告2 e+ w3 ?4 s- n5 S4 T  E
D.什么都没有
9 D. A& G- F6 D4 T4 H$ \) L
" m" m( Q( W* P% t! I" Y! @4 X5 u% H% f; u* J4 j1 E% T2 s+ p
% s" V5 ^% Y2 h4 n% R/ j  @
答案速查
5 z6 q" a( S# v5 Z: ~+ N+ ~1 c1.类1 U5 U9 E" X' Q/ W" Q
2.BCD
$ T) @  v  x/ F" c3 j) r3.C
3 d) m8 I- t& ~& z$ x4.C
, v2 F$ C- L( m5.A
6 \8 G! e, C7 |2 ]7 x& |. l6.C: `8 L( _; k' D
7.C
: G6 Y2 x: z& N" l8.C
+ x5 k- @8 V1 G+ \! x9.D& G! f  C. I. j) y
10.B
: F$ x3 \4 v. z0 x; V11.D
0 a8 b/ o0 F5 g4 K" }3 G12.B
; f* ^3 b: j& b7 g1 v3 L, C13.A6 W) u% b5 N) X" a8 x+ N: _% z
14.D
& _1 ]/ F7 i3 O9 s6 B15.A
5 i. n8 I4 t2 E+ @2 M( o+ W4 M+ l16.B
, Z+ \1 r) V3 `# ]17.A
, ^0 k# f1 X$ D/ g18.D
+ t4 x1 k" C* y9 R+ a7 ]2 C3 z" I19.设计模式; W4 |& W7 Q* E) i8 S4 t6 S
20.D; [! X$ J, z( P2 t# T! v2 l
  M" o3 ?( w& Y# y* `6 Q2 P$ x
0 U5 F1 W6 G' k4 Z* Z' }- T
7 C  ?+ g  Y8 \7 i. ]
答案详解
, i% g4 F1 E0 t" a) g
* c1 F) T$ n" O( G5 X1.类是对象的蓝图(对象是类的实例)。  [5 m, y) i! B, Y& d& E

* h. Y9 ^& P0 k7 @2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。# y* n! @! q/ M2 p

  x5 X; ~- t! ?7 @$ J3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。: ], [6 I/ @8 |, C3 ?+ N

) I  V3 N5 b  b. n6 y$ y0 w2 T5 \! w4.单件模式可以限制一个类被实例化的次数。
, ?. r( s  x" o
0 J5 d  ]" {& U; @6 S5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
: p* X* S/ j7 @9 A1 ~  N7 |/ U! k: H  x# p$ w  R# F; K
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
' r  H0 e  s  ~8 U3 R6 }  B+ c: _! e$ F
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。( |0 L  s0 T2 I1 Q* x! H

' s8 A; Z6 F: R8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。6 m- P6 t( @- n0 ^
8 r) \1 Q% B- [
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
, r, ]# h; m. f! {3 w$ M7 {* W* U9 ^% `- r! y& m* J7 T
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。- I4 W( w0 L, }0 O3 z! X

8 G+ i3 _5 X  U4 @4 a4 |& ]# w11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
& y8 K6 L, @; K' |  |# E0 d, @
5 ?; [5 p* D2 T  [5 Z/ I12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。$ j% b% d9 A3 A% |- }
& q1 j4 \4 u& `4 b
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。$ \+ z1 [9 w) Q2 r0 G/ x

: L* U3 |0 W- ^14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。' H/ ~8 ^/ c# B/ C! l
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:% j" `+ P# z6 A% c. P' U
    function reduce_fraction(&$fraction)
  }5 t! I+ T" J& `$ Z8 c( Y% N, y答案是D。4 Q( M1 b( B; _$ B. c( X, ?0 m
0 }/ C, R' v5 }0 V
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ i; h  B- [$ }- l

, [- ]8 q3 h, y5 }16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
  ~# R' w3 g, {4 i* r( F
/ J3 o( o7 @$ @' N- h* x17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。  h0 m7 D. n7 W7 @
* k: k: Y- T6 B& }* [
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
; D5 O% H/ D/ C/ Q* b4 c- o, K: W
  `3 [  x, j' z/ u1 [/ {19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
9 J+ }- u5 [+ i/ \( k
: B1 P/ I2 F9 `: [$ {7 s! c; ^4 V' C20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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