返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。; u8 }* p7 Z) Z1 R+ |! Y
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
" o; ~. t! H1 m( I, S本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
8 j$ o6 _. f) M1 l8 D/ h
$ W' c5 ~$ Z3 k/ W问题
( T7 l) k. y1 j& l
* A; l/ H, c! p( V' E' P1.对象的蓝图是什么?
7 u# M' X/ m9 R2 [, `
7 `& y* g9 i* v& f答案:____________0 e) i. ?9 k# I. y3 J- t# o& K
4 b- ?1 }4 I6 f$ T
  C7 m* N7 {; G- p0 W6 W/ T
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
  @8 X7 q/ s: yB.b, v3 [/ s% `2 }- N
C.a
( r9 k/ h' K- L! p% d1 U% wD.d( q. ?2 Y7 X' w, ?& E
E.e1 Y" D2 }( n/ J2 ?. l% [

+ ^+ J( k( X( }* F8 g6 r8 U' v' D% }: A9 a; e
3.如何让类中的某些方法无法在类的外部被访问?  T& k. j' m! c7 Y$ q- ~% G

; A# S& N9 W) \0 f! E  G0 E. }9 {A.把类声明为private4 Q4 A, v0 ~" ~. Y( V& P3 m) L
B.把方法声明为private- d/ J( [1 O5 J
C.无法实现
( K) y! V- R5 ]1 }$ t0 AD.编写合适的重载方法(overloading method)% i& @7 v8 s9 d1 T

8 B7 I' b( T& g) i% b: f: G9 L: C
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?6 E% D9 {  c* v  o. c
' N, @! M; G9 {$ n5 z( b. \
A.MVC模式
. o3 d: U* E: [+ w) fB.抽象工厂模式(Abstract factory)* x+ ^4 Q0 F4 X; W2 `/ O% F! Q
C.单件模式(Singleton)
. i, j; S" T% K* ~7 [) yD.代理模式(Proxy): _. |! N+ b& d0 z
E.状态模式(State)
5 F2 p+ R' {; p' R; S* z9 E2 L
7 y% k+ `% L1 Z# Z7 z7 I4 b( I' G+ m0 \6 R( {7 V, E. V! @6 Z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?+ J' R6 U0 x! R7 ?

: {+ s, w5 N  y7 W0 d1 VA.1个
& t1 ]; _8 x- V- S/ W; u2 @7 CB.2个
. R- s, D) n9 G- }) x8 c5 ^C.取决于系统资源
  D6 w& J3 \6 H# g0 hD.3个% U/ f7 s. W) W0 X! I
E.想要几个有几个
  O- u6 B, k  o: e7 |9 G4 m/ K3 E3 ?0 c3 |- H) Z$ z; E

$ r" V" d/ F* p) M) G* q6.以下脚本近似的表示了一种在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.多重继承/ j. m2 a, h+ C6 i. n: W2 Z* ]. e' J
B.接口
0 i2 v! o' d1 W6 j. m4 cC.抽象方法0 l9 D. W* r4 T4 J% k  U7 y  c. H
D.Private方法
  a+ [; s9 J0 j9 d- vE.函数重载(function overloading)
* L" s& F# p/ c- v" W; i; S7 o& T. C2 Z, K$ h, w

+ u& K9 Z5 _2 ?( Z. R  H# H" ]7.假设定义了一个testclass类,它的构造函数的函数名是什么?3 M% J% m0 \0 U9 j5 P

6 e* T' R- l/ h1 Y0 K1 nA.__construct
0 B- _" A2 t1 j  }6 v8 q( CB.initialize
8 m  L* x) |9 |& x' I! VC.testclass
0 c. v" f5 h- eD.__testclass
2 O8 R7 R/ ]/ {, sE.只有PHP5才支持构造函数
6 l0 M- \: L, d( ]: s4 s  y* L) u2 Y' }3 k

7 [, X5 |. `, R) N+ b8.一个类如何覆盖默认的序列化机制?
& A0 P( T/ s& e4 \. W9 _# p
* ^3 z1 Y. Y1 X. PA.使用__shutdown和__startup方法" z# U5 m3 W& X$ X' a
B.调用register_shutdown_function()函数
8 s2 [" e; U" v2 JC.使用__sleep()和__wakeup()方法
: C! F! l' G( M  CD.无法覆盖默认序列化机制
' \2 F5 F, l4 VE.使用ob_start()将类放入输出缓冲中
8 j7 T; Q/ \9 W" S% W& U. @5 V# K2 D4 B# s

/ \8 z/ T- R+ z, x! F5 i3 ?9.以下哪些面向对象的概念无法在PHP4中实现?
6 W6 d( k8 P0 [& {, Z8 ~3 j
. m$ B& c7 N% A@抽象类
# o3 _' @  M; Q@Final类" Z7 d9 k' f% L" m; b& |
@Public、private、protected(PPP)方法5 }3 I) A0 y1 P" Q# J
@接口$ T8 p# y" j6 h9 S9 y* Z2 h
, f; F5 B7 p: f7 b( \$ @5 {. s
A.抽象类" J+ Y0 o! A; N- n& {
B.PPP方法2 v. a& v7 E9 n' _7 |/ v' ^
C.PPP方法和接口
2 x4 ]5 e& U: O" [D.以上所有都不可用& K+ G& h% n6 P7 Q* x
E.以上所有都可用0 [6 L7 g8 R  R$ ^' k) _

& A0 R" _  J/ k! W* T3 ~9 H) {8 u, ~) X$ n( h/ E
10.如何在类的内部调用mymethod方法?$ w- j+ P/ m& |3 H6 a# S

+ z7 C# y' Z; X7 D% GA.$self=>mymethod();& ~4 F; \, v- I: I$ e
B.$this->mymethod();8 A+ u3 D( b, l) @; @
C.$current->mymethod();
2 B0 L* @2 q: Y$ i! lD.$this::mymethod()
, Z  T, `  u3 `; p  WE.以上都不对
6 k0 Y0 ?9 P- V0 M7 W/ w: X+ L: T9 H& C9 x! M* w& C, r

) i! E# f& ^+ H11.以下脚本输出什么?

  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.104 R2 Y8 H' `8 @% |
B.Null
/ ~3 [/ P. h6 V2 C" WC.Empty
& L) m7 h/ E/ E! u2 ^! w5 v8 fD.什么都没有3 c7 m! j( E9 W. z' \, H
E.一个错误
# y- R! g0 z: q0 s
+ R/ R4 |- ^$ l& _$ s( P" [7 ?
, M! \, _! i9 w& d0 e. u1 T! e" ~: S12.以下脚本输出什么?

  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
  s" L. k5 T- Q6 Q4 E, `B.5+ d; l9 ]  l9 V
C.2
. Y2 _5 b- Z; B1 j( uD.Null5 i) I0 k+ i  v2 f5 {
E.什么都没有& P! a- S9 y3 b: m
; Q7 v+ j3 ?/ f
! C: A  s/ ]4 s: _6 z3 ^% 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.5
7 O6 z7 s! z) Z( i& IB.10
& `1 O! [! v/ T% R! s# ^C.什么都没有
  q+ n' U9 z3 t. }& ]# a9 @D.构造函数将报错
& G! k- u$ l' E9 TE.510
. k$ C8 Q/ _* z; k/ V1 n$ ]7 B8 x2 v) m) s; P0 T

" j9 e, W. v8 p+ G5 |* Q, 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函数必须返回一个值/ K8 ^: o' V  P* U% u! b8 m
B.reduce_fraction函数必须接受一个整型值
* ]: i# y% s& O: p! B* p5 \  r/ SC.gcd函数有问题
) J3 S7 }" u# E- aD.必须通过引用的方式传递$eight_tenths对象
$ r! G1 G* J" b* `9 L* M; OE.对象的实例不能传递给方法以外的其他结构。& m" I- j) L( a8 Q( v8 _* {; Y
0 V6 M6 k7 \. H& |. o# f; b
" ~9 y. z3 |3 Y, t; E  T/ O
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法2 w' M  k, G( P  C8 i9 ^
B.生成myclass的实例并调用mymethod方法& U$ E1 _6 Y+ ^: r
C.产生一个语法错误" ]! I/ V: D; c  r! l" w! {. [# s
D.默认myclass类最后被创建出的实例并调用mymethod()- }1 y' K1 n" S1 W2 y
E.调用名为myclass::mymethod()的函数& b8 L3 W: R' y3 U
/ z6 a+ V4 k1 L3 z! N- o' E* R
" M: D5 h% p; q8 j7 c" ~- @- c/ P% b
16.PHP中有静态类变量吗?% c6 m3 D' V7 K, O

$ k& G8 Y1 |$ s- b2 \  `A.有' f# P  X6 J+ v* Y. d# ~. P
B.没有. g5 j- {. d8 N  m
) G  B1 M8 T# n" R
5 W9 t" ?( D5 |( G& H
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.13 Q6 X' X8 G' @5 {
B.2
* B. k5 `3 m8 \; m$ JC.一个错误,因为没有定义a::$myvar
7 d% x+ h" Z' `/ C$ \: U( AD.一个警告,因为没有定义a::$myvar# q. W4 `- S) M& o
E.什么都没有9 }# R. e6 R+ _

1 w: x+ |( p" E! [! u, E) f1 m+ V6 N- T; X( W  Y$ ~4 I
18.如何即时加载一个类?6 p5 s( {, X* y8 o' k

. o  z1 \1 o: X& O+ A( @. rA.使用__autoload魔术函数
4 D/ E* f7 ]" t$ o5 z+ d. B+ mB.把它们定义为forward类6 y( [2 [( f5 w; n9 C- V
C.实现一个特殊的错误处理手段" [! H2 o; N2 I+ B
D.不可能
, l$ z/ F7 i% ]& |" ~1 b. w# UE.用有条件限制的include来包含它们
" S1 o$ a  b* b8 D- z4 o! A5 U9 O5 t9 U& R- l7 [  W! K$ J: l. X" ?
& ?& o0 X9 I$ g$ J' q# J# ^* i# o
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
2 k+ g+ S' C' w# J. p
4 w2 S5 |- l! x$ ]1 I& i' T    答案:__________
' Y+ O- X0 Y& U6 y0 j5 j+ j9 N8 Y- M: l) G5 a

% T5 i7 t% O$ P20.以下脚本输出什么?

  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
8 B  U4 |" ~- J) tB.一个错误* }" n) K5 [, x- P$ U6 h3 L$ D; @3 P
C.一个警告
1 ^; ~) t: C% S( SD.什么都没有: M0 L2 B4 y. B2 i& G! _' g9 I
6 \- }5 f& C0 K. M

4 Q" i( k7 H( L( J. F' G" y  r0 _! ]1 @3 ]: g
答案速查
% m. F( |5 n5 u( ]: J1 |1.类
8 {2 R! ^1 ?/ X( j2.BCD9 x3 m# b: m8 f; o
3.C1 H/ a0 ]& D( T) U; L8 p; l
4.C: y. E: S& h; h8 U% a. N) B
5.A  S% s# |' d: [& q2 z) ^" a
6.C
; Z( @1 n! j  x2 d8 c* ?4 n7.C! \2 R( y+ d; b6 ]% H& g, b
8.C
' M0 h- U8 a1 o# u) m) C9.D4 W$ M, V) C6 W* f/ t$ y
10.B6 w1 N5 h5 z/ Y) S+ h0 A
11.D0 r% i; }3 Z# B, @0 g" s, T
12.B
7 {; p5 ^; ~* t- s; l& V/ }13.A& f* M! Y7 r! n& F3 g5 K! D
14.D: h' B" A9 c7 h2 k
15.A! n2 r5 L% Y$ D. k# S9 g' R# G
16.B! T$ Q3 T5 ~5 j1 `6 s8 I
17.A
0 M$ B  G. j% B# n( p( D18.D9 ]& E0 A  G, Q% [; R1 b
19.设计模式; ]3 P* Y$ w0 I% o6 I
20.D
8 k1 c  M( C. ~
, G; ^1 l/ u  A
/ C! s" j+ t* k' b$ c7 |* c6 c1 S  X' m0 F$ \$ E
答案详解
# s! ?9 L% q  C4 p7 ?5 I, n  x7 u; D+ {
1.类是对象的蓝图(对象是类的实例)。
2 i( b4 a' l# [) ]+ \' P3 u7 l
$ ?; l& ]/ o# |9 u4 B2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
0 O/ E( v* u3 J* P% E6 N
+ r" ]& p/ u0 m6 d: ]. ?3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。0 ?3 M& n' \3 `+ x0 f, v0 t7 m4 H
( F( ^9 J$ E8 {7 }: S" ]5 R; L
4.单件模式可以限制一个类被实例化的次数。
! T- M* g/ o+ T# }: w7 X3 Z; m! A1 V0 X3 Y
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
  `5 x2 |) f( }# m% @
: f9 b% r7 t, J2 R9 x+ f6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。: G$ d1 l7 }# i2 w2 s8 h( V) {" g+ I

$ p) m- X( v4 `/ s9 w* g- p: ^( b7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
8 ^' s( q# D) G% Z0 v- j' q$ s3 c% x/ A, o4 K5 ]6 q! [
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
! ]# i: i" J0 N5 a$ y# `$ p! Q4 `) `3 b% {5 Q6 _9 Y
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。  ^: `) b" G  G* u" _. @- |
* [. o) H1 ^! H4 L
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
" S+ q& L; f: Z# C/ z! b- B
+ G7 x% u  F& e% D) R# A11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
5 l$ n9 S6 }5 y$ h% ]+ i+ L. f9 |5 U7 b# ~/ z' u
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。3 k- F1 X4 U) b

  q6 @0 x, _2 P) o  |! _13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
8 D3 ~. n6 b- X" w% I
* D  d# ]/ V  o! _/ N14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
4 l( L1 L+ C3 g回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
  w+ x: f5 p( b    function reduce_fraction(&$fraction)9 b4 H- S. {! K- R, Y" [
答案是D。! ^7 w% O1 i- [6 \
$ O9 t! p* J( C" j3 A
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。  Z- \, {4 V( V. S$ ?" A$ Z. `

) I2 |! L  V+ g. j16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
) p# N5 z7 ~4 X6 I' @: O, ^: E( l% N9 S: Z: e9 q
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 |$ A% x. I# T( `3 v& |+ v
0 g' z# {% x6 \3 V( Y1 Z  L! x18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 h5 ~1 s( g3 R! d+ {* T
0 _* e+ V% [' x. y: a19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。/ \. N) |% h: l
+ l/ s3 a% \1 n6 }
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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