Board logo

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。! s* X/ F5 Z/ V' G( o
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
. C6 j5 h2 h: \: ]* x) b& e  B本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
5 ?5 S. O9 |% D$ t  Z1 Z0 C
5 r  Z! ]: S- S* J8 s7 z. H问题% O, [  g* h* p5 J+ l4 `( }1 i' r

8 H; x2 h/ U9 z1.对象的蓝图是什么?
% _2 @: X5 I  A4 v5 |- E- v% Z) j5 r+ O; y+ z' N
答案:____________5 Q, d/ ?) ?4 W* s7 t* K

) }2 ]6 K5 K  P; F$ }5 R& |+ n( a$ n' j2 ?' x
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$ h* H* K% r: T0 fB.b  q& {, m) F( p
C.a
! z' D" y1 J* l4 rD.d
# Q8 c  P8 s/ N( ?( ^E.e
8 x* V7 t* q( Y, V+ i7 ^$ S
7 c6 t- ]1 j/ I7 q( {% Y$ g7 s4 t" n4 z' ^3 F
3.如何让类中的某些方法无法在类的外部被访问?, z( E/ z4 {4 R" i5 q, A7 V+ }  G

& \9 c% \1 A7 `! h$ }A.把类声明为private
2 o9 N; h1 o2 X+ f3 ]1 v# Z# bB.把方法声明为private
, [1 w( X1 D. ~3 f+ nC.无法实现
9 {9 R  P  w! k8 D+ WD.编写合适的重载方法(overloading method)
; u+ x! M7 l0 I# T6 S) ]7 I4 s/ V) m! M. ~% a* j
* j  ~2 g2 {- N: Q8 `* W* a
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
' j& h3 c7 j& n9 R
3 K" a$ [& I3 X) R# x9 P" A, E6 _8 uA.MVC模式
# u7 Q: @3 y7 o* [B.抽象工厂模式(Abstract factory)
- ~7 ~. f4 n% X6 UC.单件模式(Singleton)
2 z3 H4 J7 h! G$ G7 P6 WD.代理模式(Proxy)5 H2 j! u) @+ p, d4 g
E.状态模式(State)0 s% T# w- z! _5 F1 g4 L) ]

" b0 Y" t1 `) s( ?* b
3 L, ], k0 x% y+ G+ N5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?% e" q5 W* ^5 {: `
3 z8 W) n2 }" x, h* D4 N! H9 R' k
A.1个* k% D, V- m5 u9 V. s
B.2个+ K/ j; s9 J! O; q
C.取决于系统资源
" I/ x3 E1 q" X$ P1 d( B5 I# cD.3个
  K: g/ r! N2 |3 p+ m# l7 ]' RE.想要几个有几个, x6 n3 S2 S8 @4 ?5 l

# m& `! ~6 ^) i9 v4 Q7 p/ [
9 `1 |' g' @3 `" q! _  t7 Z* L6.以下脚本近似的表示了一种在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.多重继承
# G5 _! k* ~$ o* r3 z* |7 K- _B.接口
! }- O9 u' a0 b5 `C.抽象方法
$ y1 ]" [/ Y( P9 H) C  [* {D.Private方法3 U# H' H2 c* x3 _1 o
E.函数重载(function overloading)
8 C+ Y" w$ B$ j0 C5 N3 K$ o! t: t7 V9 h2 b6 k/ n

- ~. E) T( i% {8 n' B7.假设定义了一个testclass类,它的构造函数的函数名是什么?
8 }$ ~+ A  n4 p5 O9 H; U/ v' s3 X4 e" K# N
A.__construct
' O1 y5 i/ M) K# ^2 t4 ^5 cB.initialize
( B& z3 K7 z, [. W) ^C.testclass( L/ o1 _' e1 i* Y
D.__testclass
8 D$ ^+ ~6 ~5 I2 K1 wE.只有PHP5才支持构造函数' {# S, _) }- L# _# w0 d
$ M$ _: W0 r7 U+ m
, l5 v5 W5 a+ @* |: ~# c
8.一个类如何覆盖默认的序列化机制?
  Y- W+ E! O3 u' [
7 v  |# t6 ~+ U- YA.使用__shutdown和__startup方法
" L& I3 O: [, t/ T: s( U0 R$ BB.调用register_shutdown_function()函数
6 S+ L4 v. }& E+ dC.使用__sleep()和__wakeup()方法
9 M  \! ^- B0 a( l9 B7 R5 G- gD.无法覆盖默认序列化机制3 z$ H1 G8 N7 @5 i# R
E.使用ob_start()将类放入输出缓冲中
. Y, W% A- p* r& `0 A
1 v3 K8 X% _4 M5 s
& y8 }0 J4 U: V3 B& O! r' m9.以下哪些面向对象的概念无法在PHP4中实现?. L! ^* s/ ]1 B: M: V
+ e8 s9 x( [% S/ Y- [
@抽象类% s& D& \) B) E: x  C
@Final类
* N; @" N  L. L) o/ K) F3 q! \@Public、private、protected(PPP)方法2 m" w4 [, ]: Q4 m, K8 C
@接口, W7 @+ d  l( Q) X2 L& `
- w  m, k/ H4 o5 c/ k
A.抽象类
6 K$ C/ }8 q' x( N% T; @B.PPP方法& W0 Q& F: F! c
C.PPP方法和接口5 _7 p3 _3 ?3 O- I
D.以上所有都不可用
4 ?" b9 O; b7 Q+ r0 Y1 vE.以上所有都可用4 {9 Y  l% ]3 X- v4 f! ~
4 o3 k7 ~0 j6 z  I- _1 y1 G9 L
; ~: K( b3 S7 ~: c  y3 x4 V
10.如何在类的内部调用mymethod方法?. S5 T& D/ I2 _/ r2 ?

, x: x+ u0 j1 [  y* NA.$self=>mymethod();
: j( h  ^& D7 e1 b# NB.$this->mymethod();
) C& C( ]5 H( D  B# Q- i* a) U1 \+ YC.$current->mymethod();! f1 y1 v- H. S) ~4 G4 u
D.$this::mymethod()$ H- @3 B: P- z
E.以上都不对% _8 ^. h4 e0 d- p8 k+ W$ d" O
  d8 @/ ^9 T' x5 d1 ?# X# x

! m1 Z# Y3 `2 Z. X% x0 Q- J+ W8 F. p11.以下脚本输出什么?

  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.109 F1 c+ I  w. Z4 J3 D0 |
B.Null
* T( L( K7 R; }! _- W- KC.Empty
6 J& s' Q1 H: w! N1 LD.什么都没有
: s3 x" ?9 C. G: P* SE.一个错误
3 i' g/ @1 H& w# Q8 T% t% M7 C& c0 @3 g/ f: W

- q9 e" K' {* l: e: w/ Z2 d12.以下脚本输出什么?

  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
4 M5 j$ G6 F1 S+ M# hB.52 u7 X! H- T$ U: ~1 }+ o3 I, |1 O
C.21 `6 O2 G+ D0 V
D.Null4 |% j8 w7 m  _6 w
E.什么都没有9 ~9 z3 m, g" D9 M+ q- n
' k2 e0 Y5 q) X+ W- h5 X

& E+ w/ S* H$ d6 J/ l( P13.以下脚本输出什么?

  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
$ m' @( C8 t7 I( @. ]B.10
+ O, j, ^8 A6 q+ X, KC.什么都没有! {1 v6 ]' W3 n2 \
D.构造函数将报错
+ O; v6 O' r- @$ `E.510& f6 h4 B- Y! U+ v1 {3 m
9 O6 w5 B0 A) @0 z, I+ ]
6 i1 I8 a3 r. S1 V9 U. ~
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函数必须返回一个值
9 o. \4 ]: y6 D0 Q, H" s, SB.reduce_fraction函数必须接受一个整型值
% Z: c$ y/ ^' x. l( v, LC.gcd函数有问题$ p' ]; q/ I: Q, c* E0 l
D.必须通过引用的方式传递$eight_tenths对象
* x; I# _' m, V( K% f; ]* fE.对象的实例不能传递给方法以外的其他结构。
& y% Y7 }/ e+ E- c0 H( r  B  f
& G1 |2 {, y/ e9 j+ {0 F
, U( v0 g) \/ W$ Y  T" w15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法7 ]; m6 x7 f# C7 F& Q7 _  B
B.生成myclass的实例并调用mymethod方法
) a8 w+ c  m# _- t+ l+ ]C.产生一个语法错误( A) E& o$ s& H% }) ?9 E
D.默认myclass类最后被创建出的实例并调用mymethod(): T+ w& m, i- {7 l0 `$ d: K4 Z( E2 o
E.调用名为myclass::mymethod()的函数" W4 e$ h6 [, U

8 u' f5 Q( U5 c# A8 r( o, L6 U! N" L& f2 S/ S
16.PHP中有静态类变量吗?
0 l) X& O8 Z3 D, F5 h0 D: q( J+ U" Q. ?1 Z: z* y
A.有
1 n. |4 ?5 E/ y; {' z3 d. d. vB.没有- i, W7 A' i3 t; U

7 o6 a9 d0 a$ n: J* k: S3 O4 ]& Z$ k1 X2 R
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.19 Y  Q* ]9 w$ }) `  e$ S
B.2
$ E' f( Q7 @. R" O8 K, L+ ^: }C.一个错误,因为没有定义a::$myvar
+ m2 z, o5 |( M) _D.一个警告,因为没有定义a::$myvar8 @( M2 ?1 F% I: w3 k
E.什么都没有, @1 J& Z5 G/ T" O2 K! R
7 j/ x+ z$ G+ R- {/ e! ]
( J! H4 x- ^+ p. p
18.如何即时加载一个类?, C# y" n/ \( ]9 f8 z
4 ?+ X( g. ^2 f
A.使用__autoload魔术函数
3 y% x  ?, ^# M: @5 P2 p; E% f# ~B.把它们定义为forward类
6 H% d2 h0 Y5 x# wC.实现一个特殊的错误处理手段
  i1 U/ R5 x% Q  WD.不可能
, [7 ?% i4 Y% o2 F% {( h' i0 {E.用有条件限制的include来包含它们
8 `4 f0 p6 \# b! ^& T: K$ @
& P! |) x. T! x
: v  P. J4 E; W19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
( h% T& d! y9 ]
5 ?4 K6 |8 g6 }    答案:__________5 Q: p+ C& ~( o5 z& @

+ N% t; n) S2 d7 {
9 A+ g" Z) D0 A7 b3 G" ?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 P$ R/ d7 w' h+ h$ D
B.一个错误
4 P$ ?5 ?4 K3 j+ v1 \& q- xC.一个警告2 R+ K0 k: g- m  e8 t0 u
D.什么都没有% P" H0 O; s7 ?
1 O. S+ o% u0 F- f" k) B7 \
* o4 k9 u+ @! i/ {
% \  u1 M  |1 T+ w2 `/ A
答案速查1 L8 W; Q' V$ R$ F
1.类
# W) G$ F& z: O8 u/ X3 ~: g. ]2.BCD3 b+ K6 r, c9 }& g8 A6 D
3.C
5 {# g* c6 e/ ^- b* Y4.C
7 {& [! s* n* a5.A- I6 ]' k: z, t$ V. T6 D; ~
6.C5 k" E# ?8 O9 n1 k. i: s
7.C; _/ k) c. `8 u+ r" G3 z
8.C
; C$ H; H* Z6 m2 i  V) B, s+ D9.D' _( ]* T5 b/ Y3 }* f- g+ w
10.B: B4 F2 x" x+ @
11.D& A9 Z3 K' S# ]2 x7 E! {" Q# U( A
12.B* k. T$ @$ e- \' a% @) S6 G
13.A
' C' Q' e0 c8 y# J, d8 s14.D
9 `) f: g0 W" A8 D4 t; U9 n" `15.A
. @6 G+ b4 K2 {( b16.B
5 J' X% e& P9 D  k( F: Y17.A) z0 U1 x5 \9 V4 l
18.D7 P. I9 o" h% Z1 P2 C4 S  Q' n
19.设计模式
4 b4 a9 t' t# t9 ~1 `20.D- J: @# d% U) ?! x. M5 J2 k

+ {9 ]) V8 c3 ~9 s9 r6 ]* n4 [- @8 N: |% W* h6 W, ^
- r/ N1 \- r5 ]% \0 ?( Q' j" s
答案详解
- R- I( b, E* B$ h( J9 _1 j
: i; \& ~# z: g) U) f/ A1.类是对象的蓝图(对象是类的实例)。
; l+ F5 z! V: ?6 h+ k+ f8 Q' [2 }% A2 H" i
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。1 N9 ?3 x( ]* o$ Y/ E3 }6 l

" N: @7 I# H  O! v1 V0 \6 ?6 f3 C3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。& M+ V) c  B  H2 n: P$ B
: t2 D7 t) S* {& j& J1 V
4.单件模式可以限制一个类被实例化的次数。8 C6 N/ \2 E( q9 `

# z- G  o$ k2 K1 _+ Q) Z2 H+ U. D5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
: A' d5 R9 ]/ i! J8 D) P# c7 G. D# W6 p* f
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& U- m  J" s7 e) J
( ]3 z8 ^$ S+ j& B/ I7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。4 a% I4 ^% s2 M& V, P
6 u, B0 `" T# `. u
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。, R# K2 s: {0 u# B2 S
/ V# n* m4 F' ?' T0 _( F
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
# F; P: [! d* q0 X1 w8 T4 q9 x9 P& O1 r6 i% V1 X# d/ [6 Q
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。6 u3 w4 g5 q1 w7 I% j

4 s8 z, t8 R( z11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。8 y4 e# c7 b5 `5 u8 U+ Q0 P# O

: {# \# i  Z$ R0 m12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。! b( Y# L# o! h% J) O1 u" E
3 ?, Z* M5 X6 h( G& X, K
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。5 E9 X0 U' T8 x6 T9 R7 I

/ ]- K7 ^: Z; e- U6 N+ c14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
. `% _( V  ?! e/ q回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
2 y( ^; U. }1 ?) {: g1 d# a' g* Z    function reduce_fraction(&$fraction)
! m! C( g  o- m, b) m答案是D。
$ E7 ]8 i$ [) B6 _6 j* P4 d6 V
2 v$ V' x" }  Q- G6 E0 y9 j- a. v- y15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
; r8 @4 g, t3 H. x
: s  C% k% U+ J16.没有。PHP4只允许声明静态函数变量,没有静态类变量。) s& x$ ?4 |' Y4 z# |9 H! ~' O$ K' N

/ R0 C% h: Z/ h4 n) j6 g! }0 w17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
7 `8 G- \5 m7 f( O
1 N2 c" g& b$ u18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。/ s0 P1 l  E$ ^( q$ Y1 |

! N4 Q; I" U( o19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
  [' W+ u0 ]6 C/ V2 O9 }: S3 v% K/ K9 Y# a3 F9 b# U
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




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