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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。- l  m0 y* z+ o5 j8 E
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。$ \3 [5 M$ R2 j/ E
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
; J* B# u4 Q& `/ D( E5 _* w' Z' H
问题
+ p+ @  b( K! G+ O$ F: [
* v  ^" x4 _: z7 |, P3 C1.对象的蓝图是什么?
  y+ [4 m6 T" ~# C. `7 D6 r$ s  K& z. |6 j  F' K
答案:____________: C8 b1 E, I8 r) r3 _0 o
: d0 `) `* l. c" ~: k
4 t# }2 z: Q/ j! 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.c% F% v/ f" `2 _$ d3 n
B.b3 S0 Q# m2 _, `* w" R0 ~% K
C.a' a1 m( B; ?7 M4 v
D.d
3 C" z# O; h8 @, y$ oE.e. U2 B* R9 v9 U# p4 v- ~
8 r4 r# m- d: X! L
1 r# H7 }6 }+ c6 X5 q1 q8 J
3.如何让类中的某些方法无法在类的外部被访问?+ e/ c. ]# ?$ P& b0 e2 S" k( h$ Z

: @, X+ ?' J! _$ EA.把类声明为private3 F1 C5 ]6 U0 C! g8 q5 q
B.把方法声明为private
% {, W1 W4 K+ N0 qC.无法实现
! B/ p0 g' }6 `  \1 G0 ], e0 R4 CD.编写合适的重载方法(overloading method)
* @0 j0 g$ E1 v$ p$ H! z4 c
7 Z5 w" R- m5 w6 q
9 W3 N& f$ Y& N# b4.哪种OOP设计模式能让类在整个脚本里只实例化一次?" V1 m( J$ N* u) |2 l

& w$ O) \+ `7 ^( r# `6 u  }  ~A.MVC模式( K5 `, C1 ?" n$ Z  R9 V8 j4 x
B.抽象工厂模式(Abstract factory)
- P, ^  ~( U, j6 |C.单件模式(Singleton)
$ B) V, E9 E7 fD.代理模式(Proxy)4 E. x3 z9 n( D7 ]6 |2 C# a
E.状态模式(State)& o) X4 U" y9 T/ A( e1 {; v0 p

0 \% E8 t" G1 s  \
. U6 [/ V* q2 l6 V0 ^4 @1 Y; t8 u5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
# U/ K& g2 b& P+ J1 l7 i
* _# C7 W6 |, u2 LA.1个
0 N+ m/ V* i7 R( R9 Z5 e% W* jB.2个
$ E" C6 B. d% U6 u) eC.取决于系统资源
, t) f% e( O8 ^* k4 RD.3个
' V. j8 k$ s6 A  g  [; lE.想要几个有几个
8 C' P6 A' X4 D" I* P' A
! g/ ~% {3 b4 O( d& t' A( g# [/ D
' G0 ?8 r. ~/ @( w6.以下脚本近似的表示了一种在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.多重继承
' f% }8 Q- B. L  mB.接口
* H0 @: Z0 p0 t$ q- JC.抽象方法
1 k! Q4 Q2 H7 p5 z  A& X8 \- j  AD.Private方法; s' X6 y4 i6 D" X1 b
E.函数重载(function overloading)0 G0 K/ }: i6 a, Y
- Z% H3 i1 I. e2 o. T+ k

; m. f" Q0 T9 K$ ]' y+ R5 O7.假设定义了一个testclass类,它的构造函数的函数名是什么?
6 p4 \# v% \& O2 T
4 r  j* {, k0 }! m  |* \A.__construct
# r; O1 A+ I1 A4 KB.initialize
/ W; S: N. \, H6 cC.testclass
  Y8 H! D! U* D$ h! [D.__testclass
3 i& z* F# J9 ~9 S& b1 ~1 n$ SE.只有PHP5才支持构造函数
  M! K" y9 _" n& m
! S4 Y/ q# K" V* r8 ~% C' K5 u* E' s# L" m6 m8 s) d  |; v
8.一个类如何覆盖默认的序列化机制?4 m1 t+ Q% G7 V
0 S. u2 F  f$ Y9 W1 Z; n. e5 O
A.使用__shutdown和__startup方法
0 T  y( @( p$ ?1 ^- }; {! r5 OB.调用register_shutdown_function()函数
6 y% J5 M6 ^- K8 b5 _1 zC.使用__sleep()和__wakeup()方法
, m( I; u0 H+ C; n, pD.无法覆盖默认序列化机制* Y# G5 G( [  _1 P) q$ j# E8 n
E.使用ob_start()将类放入输出缓冲中
* x; [8 V5 e# w( M4 P
/ M6 T3 W6 j: I4 {, K6 \$ ~
, R" N1 C& l3 d/ o% c; _( }! b9.以下哪些面向对象的概念无法在PHP4中实现?; I, U: [4 G# s
; D/ ^5 L' ]+ E  A+ D8 ^
@抽象类3 \3 u4 y0 Z* Z! h! }& k- N
@Final类2 Z2 i5 s8 E9 {3 u& U" \
@Public、private、protected(PPP)方法( m; |! B: k, B4 l5 \& ?
@接口: K: o  R( t* H- _
% d! o3 P$ l& y$ z
A.抽象类5 R3 |1 \0 B' E3 d, f
B.PPP方法8 }# F+ V0 @) X5 B3 v, ?+ f
C.PPP方法和接口$ A. x8 ~! c* m* t
D.以上所有都不可用
) j( u' O$ K( u5 i$ L" dE.以上所有都可用  f! A9 X! l8 @2 L; l* a7 c; [
" Y* c& v7 s4 m! U" H7 s" F+ S

  U6 M" j. R& ?8 P10.如何在类的内部调用mymethod方法?6 A0 Z, n5 n- x2 d' z+ \

8 f+ w" |$ ^  ~/ n4 H/ Y# mA.$self=>mymethod();
+ N7 Z6 ~! W" ^1 M1 nB.$this->mymethod();$ n0 c& \5 ~- H, F( d: }1 d
C.$current->mymethod();. T! E" Q! p1 k6 m- Z1 ]) m0 @
D.$this::mymethod()7 I0 ?. O3 s- Q8 o4 }
E.以上都不对
$ ~+ `; m7 I7 ?
' K& ]: O+ G4 b  V% i
2 \5 U2 ^, k$ d11.以下脚本输出什么?

  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
# f; _5 `! v* ~* y( G' \B.Null: Q, ^+ V$ V9 _+ l9 w+ W& W  |8 H
C.Empty
  U* X; d& \4 I! aD.什么都没有6 `- Y! T  k3 S1 N5 {0 U- j; \
E.一个错误
$ D) Z' m6 M5 r6 K
* {) C9 ?9 I7 O; k+ V; v, p5 p" q& J; o3 y3 [
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) k7 }9 [+ i: A+ ~' k
B.5
( S+ x+ v0 B6 k( G* w/ EC.2$ s" L" d" t- B0 G/ \
D.Null
% S$ X4 @4 j0 aE.什么都没有1 {& h- @8 B- w+ }8 q0 B
; i0 ~" j6 ^* c, x
. ^8 q" K- ~8 F0 g, Q
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
( Z/ G+ M$ a* C2 O  ?8 EB.106 X/ q1 c- `5 b2 s! J: f- F
C.什么都没有
9 j4 n$ _% w+ R) z# yD.构造函数将报错
' E! t0 |. ^3 ]0 sE.510$ f2 M/ u; T& g  }" A8 G7 p) E
0 ]  }- h8 y. \& `7 o7 A3 |
' `; t- T7 }! M
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函数必须返回一个值4 ], V* P* j# M/ P! y4 [
B.reduce_fraction函数必须接受一个整型值) [- m4 r8 N4 ^5 v. s- J& M. X& s% F9 u
C.gcd函数有问题
; j, g. w- Y5 RD.必须通过引用的方式传递$eight_tenths对象
* Q3 t- e5 w; C  X8 [E.对象的实例不能传递给方法以外的其他结构。
: `6 A- [; t2 _  ]6 r% b) S4 ^2 P3 u$ R* p0 Y) z

0 E4 \7 \% \9 e15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法* s  e( ^  F7 `9 ?3 W6 e
B.生成myclass的实例并调用mymethod方法  ^3 z2 Q6 F1 `9 T
C.产生一个语法错误
3 V$ c5 H' c# i- R0 ]D.默认myclass类最后被创建出的实例并调用mymethod()
3 H" D9 S, V) n4 t" rE.调用名为myclass::mymethod()的函数
4 P  w$ D) V% L' T1 y+ Z/ B- h9 h% m, @  u5 o
9 e" b, ]- Y) H# u6 f9 a
16.PHP中有静态类变量吗?% j' b' s$ g, Y, A2 b3 K
; U7 O, k1 L8 v& Y4 L; h  ]; f. ^
A.有
/ V1 b4 L% o+ z) [2 kB.没有! k  p2 S* q% b/ p( @! A

3 }% C1 ?, d  N/ h* ~& y" x, P9 o
1 H; Y  b: a- M3 l7 F8 Q( T17.以下脚本输出什么?

  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 u4 M0 ?9 J$ r$ i6 g/ AB.2
6 e, h1 N; k$ ~: R4 x0 ?C.一个错误,因为没有定义a::$myvar
+ k7 }, q1 |  MD.一个警告,因为没有定义a::$myvar! o+ Y4 a$ i0 y" i9 p& `  _
E.什么都没有4 V- Y' F+ |& o

& T7 A1 D; Q$ E7 @1 D" ?6 C
% B5 D5 c- C8 O& {! B0 @18.如何即时加载一个类?8 Q+ E9 \' n+ m* `

& f; M* ^: H, D! s* k2 M+ Q+ EA.使用__autoload魔术函数& R9 \: ^6 l" ~5 M( F5 J
B.把它们定义为forward类
. v9 r! y2 W/ a" wC.实现一个特殊的错误处理手段( b8 M  O8 x: m( e5 E4 G& U/ Y) S
D.不可能
) V4 o) I* Z) e, Z' i' tE.用有条件限制的include来包含它们- V( Z7 `: Z4 l& w) M# ^/ u+ U+ @; B

9 g- }7 x+ {$ r- c
# ^/ b$ B& b, R# O/ \- Q19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?. R/ K) B/ h3 t; N$ Y* M# i4 x! r

4 Z2 E! {8 J& `, o& L    答案:__________
  e0 x) c+ h, I/ q) @  h+ w9 S- V' e1 F* m5 D

) F0 J8 X: q5 ^6 z4 ?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
( X2 l& p+ q8 Y9 t' GB.一个错误6 k2 g, O: Q  j0 j- {
C.一个警告
. I5 s  R! D" S1 kD.什么都没有
% U$ T. I4 ^/ @& Z7 B2 a/ g5 s9 I/ L) {
+ `1 [0 e8 S! u0 b$ X% ]

4 y  d3 j0 o) X" M5 d1 `) M答案速查% X! h" _6 W$ @" h: R' O! Q) }
1.类. v+ g1 O8 J4 m) H7 \/ Y
2.BCD
8 T# ~  _8 W: ^4 m$ _* [$ D3.C- D- r. o' J* p. G! z6 S  e2 W
4.C
( t7 j: `0 g: s0 g5.A
/ v$ p) F  R2 |5 A  P6.C( [+ r' s! \+ G+ k( j1 Z
7.C5 Z, x4 E) o6 D
8.C" y$ Q% p  P1 _- q- e; n
9.D
% U" g9 o3 Q( Z3 [10.B3 I4 b: f- @+ y# x0 ?
11.D. b3 a8 C. ]6 j9 U( H
12.B/ T6 q* \- `* C/ i3 ^+ y2 W
13.A
8 r# ]3 S9 b9 b: I1 O4 i14.D# E7 _4 F! \; B- a
15.A
% A: i$ B- M' y6 ]/ d5 g16.B1 _- o# `9 K& W" _3 k
17.A
0 g1 H: E/ u! W! W18.D# y. g* Z* I7 r# m
19.设计模式2 R+ @* {8 w6 d5 F5 |: T
20.D8 t( J- |9 S/ i$ y# ?& c& d
- K, R( I+ ~& ^, h7 M/ P9 ?7 S
/ [+ [# b1 R( h: h" ^3 {
  |7 L! p0 t5 G( b- S- D
答案详解0 y. ^4 ^5 H3 ~0 m2 b% h
& L- h% E; t& H5 t) q8 F+ q7 C; O
1.类是对象的蓝图(对象是类的实例)。
& K' {8 V6 f* w& E' h% O% ?5 ]! p9 v) j  G" f+ m
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。+ O+ h& B& f0 a* ^2 Y& ^/ i" r( f

' V& {! p* B5 D; P4 ^/ @5 e" h3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。& {& C# L' O4 H  q( L+ g! ]

+ g0 H- Q- z& q. t: _# e( A: W4.单件模式可以限制一个类被实例化的次数。
! W, S) B8 P0 ^: W! H& N' Q
( A. C6 `4 c1 @0 a8 V8 i1 y  S5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
# d% [, o* Q* b9 ]) v
7 f. r5 ~' ^, I) x6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
4 p% ^, F3 g* k; P0 }9 @$ w
& J" ?, ?, w: q; h9 M7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% X0 t& R5 X! Q) u$ L. i/ _

" D8 R7 p5 D- u8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. w) ~5 H1 s" O

' [" O  r- W5 g: C' \6 @9.PHP4中没有题目选项里所列的任何一个概念。答案是D。1 W9 g: V* @2 T/ W* T6 S7 `8 w' L

; X* e$ i7 h( ?10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。# E& y5 o9 z% Z5 r4 m
8 u7 z" a  T7 s# j
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。+ O3 \5 t  i" Y+ \- h# O# N

% o7 b$ _+ I' U8 }12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
/ g1 }* x1 U2 m
, N2 f  N( ~6 T- D, U13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
. I) u1 C2 v" F- q3 @1 H* t8 h* Y7 [6 O8 {9 G
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
1 e$ p, S! }4 h回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:( Z* Y0 C% M( ^. l) e, x
    function reduce_fraction(&$fraction)
( Y- H- G5 c2 A% q: i8 U答案是D。+ Y- v7 r0 C9 M+ `

+ s- L7 R+ q0 C$ A15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。- }" o9 x* [- S, L9 f

1 r. R# v/ e6 u$ |& {, R16.没有。PHP4只允许声明静态函数变量,没有静态类变量。, G5 i# F: m" \3 u* O0 z' G
$ G$ T" j" p+ \* \. A3 K
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。, `) ^* p# Y1 y

# y+ A4 [5 W, ?' W( Q18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。$ L: @: d6 s. Q; x6 \9 u
, J8 i  l2 K6 r1 s4 @
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。! \& T, q) ]$ ?6 f' E; z" L

2 z  U' ^0 A8 L' K0 \* P7 U20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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