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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
1 Q5 `3 f/ ?1 f/ K  e7 ZPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。3 \7 z. e9 O1 K7 l) y
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。  }1 w  U) s8 ^
8 f8 F8 A' @7 U! j8 B8 \( f' ~
问题
! H# U" Q1 c, V4 b! Y, [: j9 [9 l: |) Y! U
1.对象的蓝图是什么?& E4 k/ k0 X# N! r. d! }% {6 K* u

; t% l; A% o$ D- }* ?7 [# o答案:____________
! `4 e1 k9 B( d" @" O- ?  W- r) v. P! A4 z/ C- Z# F6 Z
1 s! m. E5 z# N- J
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.c4 J; K$ f3 ?( }9 ^! @5 a
B.b
( F1 c% n  t# d" I& O' Z% CC.a
6 K- ~, j, d+ P! W/ jD.d
# a" {: w3 O' t5 E6 VE.e
2 A" f$ l, `2 u, U2 J
1 \+ B# j" ~) ?& C: i* X( W7 s% Y3 d0 e! x; W' @+ M
3.如何让类中的某些方法无法在类的外部被访问?
. P  {( h5 N' }0 j" F; p/ |7 y. n$ b: N- x
A.把类声明为private
* ~8 y9 S7 E# h, S+ }/ D+ ]3 bB.把方法声明为private
' j0 v8 V0 j; b# t4 Z0 T5 }: R! Z/ eC.无法实现
0 \; l  S+ A' ^) w5 Y# ~$ Z8 _  [& MD.编写合适的重载方法(overloading method)- c1 Z5 v' ]. K
4 ?% F5 {' ?1 f
8 F1 E9 P6 d! L: s& }
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?5 M; @: s$ r5 M0 B3 i" }6 O! I1 K

% k9 ?  ]) ^0 N3 cA.MVC模式
2 l  s: E8 m- ^4 Y& R1 jB.抽象工厂模式(Abstract factory)
' d# R4 U6 _  N' I+ O% E0 ^4 GC.单件模式(Singleton)
$ m7 j2 X5 y0 `+ s  l- B0 mD.代理模式(Proxy)& d# w0 j" r; ?
E.状态模式(State)9 X5 ]. t! {. X3 [2 h3 ^

; O: X5 |1 u. C( z7 ?
% u2 \$ L6 j  i8 h' c* }0 W- [/ J5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?; Y0 J' ^3 o7 B) l

, D6 ^- i- U( A( NA.1个
2 ^' _5 G2 R/ |' X3 uB.2个9 M0 r, J. K/ I. J
C.取决于系统资源$ k- t4 U8 X: {4 x  _5 v4 I
D.3个
! l( z+ H/ h: b; o2 TE.想要几个有几个
0 p6 w8 G3 u% b; A+ {+ d+ Y8 R) `6 M& I
+ @+ x2 ^5 C2 ?; R6 X
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.多重继承# H3 R* D, z. S7 Y
B.接口$ u* `9 D4 J* @1 e6 P
C.抽象方法
% b; I- P0 ^( t: SD.Private方法/ |3 P8 m% _  [2 c0 X8 n" M1 g. J! T+ s
E.函数重载(function overloading)7 {1 ]# k& L: J' b5 i0 Q
  C$ E8 J( V- I! f( S

& h( U/ [, G0 X0 T% h$ `7.假设定义了一个testclass类,它的构造函数的函数名是什么?
1 n2 w( D4 K. o. E3 c2 |7 e& [. K5 |  w% C: r: \6 D
A.__construct/ k( n) l1 q4 C+ ]! P
B.initialize2 |0 e1 c# r& R. |* v
C.testclass) u' G$ x1 U6 k% S& D) p; e1 f
D.__testclass
9 P* h$ ?+ U0 }' q/ ], t7 E$ tE.只有PHP5才支持构造函数# F( v- E+ f# w1 \% @9 Q! s+ e6 \9 C+ J
! ?& m) }7 D' V" ~% q6 L
' p( B$ U1 ~' m# F
8.一个类如何覆盖默认的序列化机制?2 c1 P  u. X  ]
$ A1 G/ s/ p' j
A.使用__shutdown和__startup方法( K( v  p4 z; |7 K0 `- I0 B! O
B.调用register_shutdown_function()函数
- Y+ R2 ?( j2 @& b  q% VC.使用__sleep()和__wakeup()方法
7 v% c' t. w1 u! F: nD.无法覆盖默认序列化机制
/ s% R5 u+ ?: D4 `7 \6 NE.使用ob_start()将类放入输出缓冲中# b7 G" `  D- v! }. L! V3 \5 _
2 V/ b# ]: w+ Y! y8 |

4 \* t6 R; c% r( R2 i9.以下哪些面向对象的概念无法在PHP4中实现?
& C3 e/ y, }! `) k) |  r9 p/ l4 g) J9 `5 H
@抽象类  p/ m9 R( E0 X2 A5 @5 A/ q
@Final类
$ V& {& A2 `1 q& _3 {@Public、private、protected(PPP)方法
" C# ^2 k( j# u1 p' m" L@接口) d# t/ Z) }7 z# u
( ~. |! l0 L9 O: ^( r
A.抽象类
1 T, m3 m. Y) t9 x& ^  Z" @/ }B.PPP方法
4 q, N5 s9 Z! j+ gC.PPP方法和接口+ H1 E  G! x/ W' M0 Y! U6 d# T! z. W4 A
D.以上所有都不可用( o" M9 r; Y4 Z9 y! P) \
E.以上所有都可用( o  h& e& @7 n& a; N" I1 g

/ H  [4 o. u. \& G: s: J) V0 F; z6 ]8 N
10.如何在类的内部调用mymethod方法?1 D1 O1 r% L+ \+ M9 [, b* d: T/ @% k) O

* ~  O) f! d" l, u0 }" W- `A.$self=>mymethod();
2 o% s9 B- }5 Z: f1 d! w% W8 B: l; iB.$this->mymethod();
3 O3 F/ \* _6 [3 G' kC.$current->mymethod();' \& t: G6 r& w8 D: \" b5 j* a) Z! M
D.$this::mymethod()
' C9 z% V% Q# T9 h3 M4 \2 mE.以上都不对  D* B1 R5 G$ G" R2 g4 y

9 Q: ]* o  {* \& ^% a2 X/ X
& f! h/ [- Z& T# M5 I11.以下脚本输出什么?

  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+ h* p# O1 Y3 h; m4 p
B.Null
% D/ W' C8 R4 q8 @0 W( [/ BC.Empty) g2 B! f: ~( c
D.什么都没有
7 [1 d, b6 h) k3 l, v& {9 N0 g- AE.一个错误* W# q& D$ @+ W, @8 R7 k/ j. X
9 N( H9 e$ A6 M" o$ |3 g, |- {

4 ?! h/ Y$ L' X2 ~5 z/ ~+ _* p12.以下脚本输出什么?

  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- P4 S% E) f3 t  \
B.5
# g1 N  W. s3 N6 ^- {C.2* q; A$ `: Y. h; x9 ?' @
D.Null7 I- R7 @( J' X8 [  ?
E.什么都没有  t0 D' K/ u1 c+ a5 t' M
' [0 a1 Q% k: A$ f/ ]' ]
: G, R4 ]# I) w  R0 V" N, W
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
( g& o8 n  A6 c/ _: \B.10/ l, d" m6 j3 h3 o% c) L
C.什么都没有$ d5 y, Z. E  W- y' K: m; c6 Y
D.构造函数将报错
5 I, E+ E4 X: g* d4 ?. yE.510
+ N% z) V+ o- I5 _2 `, c6 N) H/ B/ _  O: H

2 g' I( ^" n% o( f14.考虑如下一段代码,执行时,$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函数必须返回一个值) m: H+ T3 R/ {5 f4 F& J4 H5 t. ^
B.reduce_fraction函数必须接受一个整型值0 G) |* a5 T, O! i6 M& ^
C.gcd函数有问题7 F- l4 R0 I6 @+ e5 [; {  T
D.必须通过引用的方式传递$eight_tenths对象
7 E' n& b$ ~7 m' pE.对象的实例不能传递给方法以外的其他结构。0 l1 a; d% L; |7 A" ?
4 S+ I1 I+ d- R

3 ]0 X# B- e3 t: _$ g$ d  I15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
6 a5 L1 w2 d2 ?" B/ Q; ], \( CB.生成myclass的实例并调用mymethod方法- [( B1 k2 n7 H! U1 s% B5 w$ y) k, G
C.产生一个语法错误
3 L( i- H5 V% BD.默认myclass类最后被创建出的实例并调用mymethod()
) }$ T: [* n5 V% i% l" A$ cE.调用名为myclass::mymethod()的函数
, F  C3 S7 `7 q8 }
4 w: c: o4 Y% C6 L( H
9 h$ E& m7 m/ h$ y16.PHP中有静态类变量吗?
8 ^/ u9 S$ ?/ T9 L# @1 |  T+ \, I9 l' U
A.有
' h: j( f# X0 I( HB.没有# V9 G1 O4 _4 d8 K

" D7 @  l9 v3 C& ]: M
+ Q2 [) m5 \: j17.以下脚本输出什么?

  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.14 R5 w" [( R+ v
B.2
. W; Y* U( V* {6 ?4 W( CC.一个错误,因为没有定义a::$myvar: n4 V% ~0 ^9 i2 e8 H" x) t# \
D.一个警告,因为没有定义a::$myvar5 A/ c4 O- F/ o
E.什么都没有
  m/ Y/ \6 L3 K* t4 v+ i! S. j$ I
$ \9 z. B. z' n  K) h
18.如何即时加载一个类?" P3 l. I* c4 m$ u2 m% d" C

' D+ @+ X6 m" b; M4 WA.使用__autoload魔术函数
4 A# \' r7 V  N8 p; A, V6 n, ?+ E# hB.把它们定义为forward类% R2 X# S9 G3 y0 X  D3 l
C.实现一个特殊的错误处理手段
- l) Y, w5 w! }8 l: t9 ~/ BD.不可能9 {; b& f" E) n) J8 g8 D. J
E.用有条件限制的include来包含它们8 g* D- M4 v% `
1 X9 t8 ?# v: C1 D- }2 D) [
( T1 y" d; `8 W7 H& V$ I' T
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
$ U# @. a# X7 a2 w  l  U# z  T: C5 Y* P* H8 V2 w
    答案:__________/ x5 a) {" w+ G. \

7 Y  \1 O5 Z% K* L% v  B: E8 f8 y
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 called5 N3 I; B. G" w
B.一个错误4 D# D  t, P1 U0 M" e) [
C.一个警告2 W: ^# N( _2 c  I, l  c
D.什么都没有
# a1 ], K6 o. P- j1 b1 J' s
6 J% x* m( a! K
7 \9 l: T/ Q' C3 d# a" y  y2 @5 _# ?' L7 W
答案速查( @, n. \) _1 K. R$ h" T! G1 ?
1.类" u, Z, _6 r$ r8 L
2.BCD: d. ]3 |' w) `: H& t
3.C
, n& p- {: s, y4 ^+ T! q" m4.C
7 h) j' _0 \* @0 g5.A* F4 Q/ S8 g0 p' a) r1 x
6.C2 K' r3 h+ B1 J+ L) }
7.C! T) [4 d8 r' A' x/ N
8.C
( Y8 b6 W* b/ M& o9.D. f% ?. i. a) e% s& O- t
10.B: A$ G4 S3 e  q
11.D
8 d- x+ H! g+ w- W* [! J+ {12.B( u% x5 B  ~2 x) s
13.A! @3 ^0 f% j% b0 L! ^8 s
14.D
0 j! i4 c5 a' B15.A
' m2 ~# U$ V4 h16.B0 y+ l4 [9 K7 d7 D0 Y$ P' T# c
17.A
- _# m4 B: S) ]. v6 j) @& W+ Z4 }18.D
) W: i$ W7 k1 @  t; H- R19.设计模式: N: ^' B  L7 S) I* \% m
20.D
- x! ]' g: Z( m8 ^( t& j
9 x" A1 w. U# b  G& ~6 @* t* v
2 ^0 q" t  p2 [' U- X: q8 G& H
8 s* x% q+ z4 P答案详解
) X) W8 a+ O+ y; T8 i9 O$ o8 ~
) Z2 b/ E8 ~% \: C" J$ J* v8 f1 ?! v1.类是对象的蓝图(对象是类的实例)。
6 g- i, \5 c# b. [5 ~$ a! L% `& k1 N
) s2 t% `7 b  |2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
; |* w1 r- ~/ W
, j) y) Y6 r9 l5 D: z3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
/ |0 A. X( `  Q/ b) u1 Q0 u. _9 r+ H* }3 j4 z' U& h0 }- _
4.单件模式可以限制一个类被实例化的次数。
3 G% h- v9 c4 e: j* U& H) t# [2 ~% t& k) Z% @# Z# X) f
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。- R. l, d9 z; o7 e3 t5 G: ?( D
! z% S) K! |9 m* y3 E0 z
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。- c" `8 W# H6 b, M' T8 P
) q7 }; {# b- Z& [
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。. K" B$ ], C; f9 w- \
7 _: J# i% E. E6 y
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
; }4 U: F, L& D8 o; R7 A7 h8 j& M
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
. y2 i; J, a4 \) p7 [
2 L. y0 H, o/ u+ Z10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
0 `  w1 ]+ T% |3 }: `" u* o3 }. \. u- t
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。" p  s3 e7 |) b8 l' n9 `

6 k+ p1 @5 k4 T4 j0 h3 f) p12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
$ {# R6 Q* O% M0 q  s! w5 y/ {. I% K3 a; b0 o" O
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
' {3 J$ ~3 K5 i; G, i3 ~2 x7 t! G$ Q
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。6 N3 h# N; a5 n& z
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:* N# O" K5 s1 v+ {, R$ v$ ~: g0 o6 e; J
    function reduce_fraction(&$fraction)# B8 k3 O! ?; A0 E% f
答案是D。
/ `7 w6 s/ Z! L. t+ p5 P! I
+ I; |% y2 L0 R4 E% `15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。& _  `, |) \; m9 x9 p
- [% @! ?! L1 P1 u/ W
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。2 A' d: F( @/ a& u
+ U# K0 U+ q! M6 T
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
3 g0 V/ g5 ^% m, n- N( N4 t% Q" x+ n# l+ q* s1 a
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。- b8 C+ D  `# n9 |2 V3 q7 B( i
$ R% N- F6 x$ o9 F( v# S
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
; a# A' L/ J( f7 r0 F. _# f/ H5 {. p' R
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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