Board logo

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。7 ^/ `9 K! m9 `1 _
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
  e3 s" I; u3 \' a* x本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
4 W' F  \" J3 C) [7 M4 m& W% W/ w( u5 v( o
问题
# @" c" ?, S  l, K. J
: E0 N; F, J% n9 k8 D1.对象的蓝图是什么?% I9 Q6 ~1 W) [# q$ }

) V2 }8 h. R: U& t/ R+ ?+ z$ q答案:____________
3 f0 o. f; q! P  ^. J  |- \9 `' W
0 q7 ]6 g' U6 A+ Y: s! q( J4 a
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
' ~: Z$ t2 ]5 V. k# {2 D8 A: lB.b! e" A# P7 \3 E' y+ K% n1 `7 Q* |
C.a3 \6 x3 Y0 T2 c5 Q
D.d$ }( q* Z8 V' R6 H$ o& z
E.e
5 c1 q1 n$ Y$ X8 q% @
) Y& p) {* W$ L; w) ?
1 q; T/ i) h! `- F' s% K3.如何让类中的某些方法无法在类的外部被访问?) a4 ^$ Z3 s% W) n6 H, B8 w
" x1 f" j) @; S
A.把类声明为private
2 @) ~* L3 L0 j) j9 S# B5 T0 ]  [3 YB.把方法声明为private; I: X. u% z% J# A! v: p/ l. \
C.无法实现
! g, B. W' W8 {1 x) PD.编写合适的重载方法(overloading method)
1 ^; f5 v- j, i# {4 F
: y& Q  b- m! P5 X, D- u; z# b1 `
2 b' ]* }, b& k: {7 s4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
/ w9 U. M4 i# Z8 P% Y1 Q
% j) g! F& s. X# E8 N/ L. {A.MVC模式
, Y! z2 i1 k% u$ ]  r$ q1 `. zB.抽象工厂模式(Abstract factory)
; F, j+ |7 `% _C.单件模式(Singleton)
% I# t7 w% P# G& u) tD.代理模式(Proxy)
: t& A4 ^$ e. l2 ?) b8 uE.状态模式(State)9 R* S( e) S, H) Z2 N

$ m* S/ x+ Q/ o# a( W* ?! ^
7 B- D' y$ a; ^% j* o- X. l5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?; p4 {4 A! ?' e* q! z. V/ Z
) i2 }" F% R; i2 w& C8 b) F7 u6 W
A.1个
) F8 p& j9 Q, @" H3 A. UB.2个
- |, W  i, `/ E0 ?C.取决于系统资源
! x1 S$ {/ n( t: R5 _D.3个
3 A6 g' y# M" c7 b) [( r* j1 C. ~E.想要几个有几个8 C! r, t( m( |- J" g. p

! o! w& Y6 }2 }9 c$ X
( N3 Y! E' u& ?& ]) U$ H6.以下脚本近似的表示了一种在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.多重继承7 f/ _( }9 ?& Z! J$ u) U6 I
B.接口
8 v5 s+ a% K3 xC.抽象方法; |, t- k* N9 h& L, m) b. a  q
D.Private方法
0 B. ^! o$ b$ H: f$ v1 ME.函数重载(function overloading)# e' Y& {$ s4 A7 e: z) d( o

# s+ D* }7 E, B0 \' N
$ W7 c4 V* ^/ P, x' R( x, @7.假设定义了一个testclass类,它的构造函数的函数名是什么?
3 c4 L) M- ?  J
# ^7 \+ }5 A0 m+ ~. Z/ d/ kA.__construct
4 F/ v  y3 J- s8 h, @7 OB.initialize
7 X( W  a  H  X$ hC.testclass9 W: s( u8 W/ F2 H3 u2 A
D.__testclass! u/ R7 s! L2 D2 e$ f, f6 [, r9 y3 u* Q
E.只有PHP5才支持构造函数
1 w, C! l8 D& U  i9 h+ f( R& V
' M# n, M. v3 I$ v7 W. t$ O
! t% U% i% o+ _1 [$ T. o" l8.一个类如何覆盖默认的序列化机制?
0 E( B( ~) w% m5 X: W
, ^  p3 H, [3 P! G" _5 D0 f% BA.使用__shutdown和__startup方法
- C+ B$ i9 i: W' `$ cB.调用register_shutdown_function()函数( m" d  X; M- n' Z& N* C
C.使用__sleep()和__wakeup()方法: l# G6 j* r5 Y0 ?
D.无法覆盖默认序列化机制: T0 i! Z1 A1 J& ~* ]
E.使用ob_start()将类放入输出缓冲中9 s" P/ o, h/ }" P( u5 y  b1 F8 t

* R7 l  k; t% n! \
; }4 N* F8 |% \7 }9.以下哪些面向对象的概念无法在PHP4中实现?
  g9 D9 N. [  \- m- W: Q* c1 Z
: r5 N+ v  a; C/ T3 v( k  V@抽象类
7 B  `# u3 T$ @" T8 ]@Final类
/ g3 a1 r0 O  ^6 b@Public、private、protected(PPP)方法" `/ ?* l: X4 Y, y3 O# j
@接口; _/ G8 q0 f4 }  O, n
4 x1 ~5 N6 L0 \. M- Q
A.抽象类
' B$ _/ {$ q& a- uB.PPP方法
3 p2 K) u' A3 eC.PPP方法和接口; r: J1 K% \6 `2 G$ Q/ g
D.以上所有都不可用
9 @* J5 ?3 q- d& {# n. o* ZE.以上所有都可用
  D2 \1 {$ B9 W+ R! w6 \* ^
. W# I( ~5 t" e1 {1 p
6 U1 g& m( N; N' }10.如何在类的内部调用mymethod方法?- ]9 ~- |# J# G& x

* H  t! a4 F2 n' ?  SA.$self=>mymethod();
4 H6 y" @. K2 t6 i  ^0 IB.$this->mymethod();# \) `) w1 V& M" O. N% Z
C.$current->mymethod();
" x4 V+ f0 q/ N! P7 `3 g, kD.$this::mymethod()
% k8 R1 w& E+ m- [$ y7 ]: XE.以上都不对8 I! w# a" K8 n" n
2 B. k8 E" B4 U, p% A
, n3 ^1 D, ?. T: z  ^% Y
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.103 V5 C4 P8 l$ D& h6 U( V9 h0 j; k
B.Null
8 g8 Z% \; ]# t" S: t* s  sC.Empty
. {4 }. q$ }/ z9 B0 zD.什么都没有
, G7 q* `. q2 r* t5 Q" ZE.一个错误
$ m' |) o: X7 H9 F$ S/ p! g) o: j
* |7 [% W& @5 B/ P8 n9 Y; T$ q6 I! _0 p4 t$ `! G# K" G7 z5 S7 T
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
4 J: U) Y) I/ Z) j! M( b/ QB.5: A( \( D6 z& ~
C.2
& C+ x8 y! u# oD.Null: h2 h. c9 w& U$ r* M5 ]( v
E.什么都没有
8 W/ z$ h* A& {/ I" y& d( I
3 J  b/ u4 R7 S0 V# U2 }! B
( G. i* S9 ^9 i13.以下脚本输出什么?

  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
1 j, Q* a$ T$ w$ g" M) oB.10* k  `' G/ @% v2 P/ Q
C.什么都没有" U$ w2 ?5 m/ Z& P/ b
D.构造函数将报错- w# k! a+ T8 F; z
E.510
* j8 T4 X+ K, _# r8 P8 K
8 `: a) r# N( `, u2 x
/ d/ @0 h5 H$ f6 i14.考虑如下一段代码,执行时,$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函数必须返回一个值
* Z/ }5 ~0 n! z+ ]B.reduce_fraction函数必须接受一个整型值
- G, P- t+ T6 bC.gcd函数有问题
8 \/ x9 k* v% g6 W( M- o# ?% {: ~1 YD.必须通过引用的方式传递$eight_tenths对象) l! a) K6 C2 ?* S" ]0 |+ ~8 x
E.对象的实例不能传递给方法以外的其他结构。
! ~1 M, k- m5 n; s2 a% z8 ]
+ |) j' C. a" {# s6 y( s" A+ ?- y$ ~4 ]- v
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
0 C% [6 `, N- w& t" c! `2 C6 [' EB.生成myclass的实例并调用mymethod方法
* a4 r2 k/ |7 B7 j- B8 j' f, w3 vC.产生一个语法错误  s/ p# s& K# w6 g; g3 ?
D.默认myclass类最后被创建出的实例并调用mymethod()# g/ G- `, ]) z& h
E.调用名为myclass::mymethod()的函数
. l2 }' {" P% k8 O- F6 q5 ]$ L4 J0 c- [! H) t- P" R! v

0 }  k! i4 L  e" {8 u16.PHP中有静态类变量吗?
' `: d+ K$ a. T, A/ C* A& F' h5 U
, U0 I' s4 c5 y8 @A.有( l" m4 z3 U! Q7 ^
B.没有# p7 F- x% D4 ?' V

" ?6 Z5 o: ]: Z
* p% X, q6 y: Z9 z" }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
/ Q. U( A6 c# D  mB.2
# q0 I8 J. K: K! b# `C.一个错误,因为没有定义a::$myvar2 D  x: ?# ~& X- S: v' [/ d3 `
D.一个警告,因为没有定义a::$myvar! u7 R5 h# b; K1 F8 w9 M
E.什么都没有6 m2 c# Q/ L" D- s- h
7 }2 l1 U% x$ [$ r! q# ^
1 Y" B* f: N" q$ W2 ]
18.如何即时加载一个类?8 ^, W. Z; z, }# `1 V

' T0 T5 k& M. A9 u2 Y7 F$ uA.使用__autoload魔术函数
  l6 E6 b9 M9 D; j5 Q* B' ^B.把它们定义为forward类# @7 ^2 y! z% a; u; \
C.实现一个特殊的错误处理手段
, \; k" F, ~. t( c% D( ?D.不可能& ?! B/ h: M* V/ I+ o
E.用有条件限制的include来包含它们
9 Y( v; }! B. D5 d& [4 j
$ Z8 h- F- t+ u, ^5 p' h( e8 [- O$ @' \1 Q. h* T
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
# ]/ p& M( U5 c* {, }* E" H& ~; q5 S! `" K) D
    答案:__________5 e; g& \; t* O+ |* p' [, @0 C
" y' t/ b. i$ c$ @4 E0 v, T7 g
- f, M/ N  O( L/ L$ ^! }  L  r
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
0 A6 c! e1 G& BB.一个错误
" `' J$ u( |; x' q5 f) nC.一个警告- @% R" D0 i+ s
D.什么都没有; V$ }% `5 m7 r. ]$ e% B

& v& |' J4 e6 H8 X$ W7 k* O: e+ E  R  a5 V

  H! u% K: l& d) O  d. o答案速查
. j) _# B3 s2 r7 ?: U" Z1.类
& K- n# @! M. `" ]6 g/ G2.BCD
5 n+ g5 [; Y+ B# \3.C
2 r" z/ \  P% b4 K  p4.C: v- M4 q  q: O$ T/ O
5.A! b, J; n$ s: \
6.C
- [* ~! g4 \  t7.C
3 j/ E( Z, d& h( W1 Q8.C$ W9 C* n! E9 v$ }+ |5 }2 U
9.D
6 h7 T7 n. Y% Y$ @9 i10.B1 q; t9 b. m5 M2 ?' O3 C+ q
11.D
3 z# ~" m/ L% y7 m1 e12.B. t# x% o. f, U9 i/ \9 Y* E6 m# I
13.A
3 g5 e+ G. f- E' d4 L14.D+ d5 C) J4 ^+ g
15.A
5 j0 Y1 I% q! H& H& ?16.B
1 J' V( c9 z: |( `( G17.A9 F+ g8 ^' l$ L! D5 C/ b$ P" M
18.D- M9 O) \7 X; q* |! b
19.设计模式
" |+ _+ b' w+ R. P% n20.D6 p% ]( D+ L! y2 x! e

8 C: ^% b- n3 g/ x& j( w! S$ w. V: D  L# x* V, P0 e% T% H9 z( t$ I
5 F/ I7 `- b6 L/ F) Z
答案详解
4 B- d6 S* N$ e1 s+ K, M' K; z* X& Y7 v
1.类是对象的蓝图(对象是类的实例)。7 H3 R9 L* A3 D  n  c1 O
# e7 @8 c" x9 \. W
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
; }( \2 b* B2 \1 j% l
* B7 G* }0 I* f' r% G3 A- d2 B+ h3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。4 ^; J, m$ x( ]3 |! O

8 d. u; _; o" ]: O( ]+ m4.单件模式可以限制一个类被实例化的次数。! o. u" H9 ~. |

. W  O# z3 b& B2 @5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。6 m2 M, a8 h8 T# ]7 O9 J

. p$ ]% h2 O6 G: L6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。0 @. R4 L3 M2 t) G0 G" M: m" x

* S4 N; t: ]! t1 B2 ^/ c7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
1 g! w# Y7 Y4 `7 _; _' r+ I0 I/ M( N4 w7 F
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
" v7 P9 Z. r  j% f3 j
: s; o6 M) B5 M! U0 ]9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
5 k) I: R" Z0 ~; x8 i9 d
+ n1 D) A2 C1 K6 q9 k& G& L10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
' t0 O& X! Y' Y5 K3 i9 L
/ f( m. \+ ~  i% d/ D: o  R$ I11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
; }* S* @) k) g7 [# O' u
5 c% ~' u$ p7 e# i12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。; \: W4 v0 q$ D4 g
: V. G  ]4 G+ q, w; ~
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。+ O( U) f1 c7 b) P7 i

% }$ y$ p$ y; u  [9 U; K5 Y14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
% s8 j. R* r' i; P回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
+ `5 E; Y2 g6 x6 b6 j9 L4 c    function reduce_fraction(&$fraction)
5 {# d! u2 [+ m: _5 A答案是D。" _/ }4 \4 s0 d+ Z9 H/ B

$ r$ N) S# b, |+ A15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。  F; d3 n( _3 A- @: x  b

: Z) {& O) G( w! V) M2 B( A16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 l! d& n! n. U, X" y4 g5 \
1 ?( N" U# [! g4 Y/ U; {; W6 p
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。7 [) g5 `2 e9 P9 m
( _) b0 `: _' D  u1 u8 T4 i* g
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。8 o# _$ v7 Z/ y( b9 p& z

# J" P" B  _1 Z# @: |2 A! E6 L0 G19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。2 x9 p' R% i7 i% l4 t

* q  u0 f; _! Z" j7 o- c20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




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