返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。9 j' j  F% c) b! T  X) ^
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。, ~' i5 D6 E) y* S. G" C4 \
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
& e  j  o( T4 p6 M* R, a
8 F) L8 V# q  T" E: h问题
4 ?  y3 ^  X2 v/ C+ }3 U. Z
$ x8 o& E5 P+ _# ]. e2 k1.对象的蓝图是什么?3 j- o: O" q# T) w

2 B# y- ?7 H4 [3 e- v! u: s% `6 V答案:____________
- v0 z6 m7 y6 y5 a5 A3 D+ R0 J+ P: @0 a6 L" c
+ M1 x2 F, x5 [9 }
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
  x) E1 g$ K# ~8 o9 V% ]% \B.b
2 k$ w0 E! X! IC.a
: k5 B) i1 u/ `9 E& wD.d
& E8 ?+ y1 ~# @$ l4 b9 R* F' b0 hE.e
0 A2 S7 O+ [9 h8 D9 {5 g
0 ]- A" T1 l% w" o! H& Y% f! z0 `# j* G
3.如何让类中的某些方法无法在类的外部被访问?/ h; l. Q# m9 P7 f! x
7 n" _! J9 V& e& {6 T
A.把类声明为private
, F9 X" ^8 t! M0 AB.把方法声明为private, A% |  d% L  e1 ~! o
C.无法实现
0 F* x! K! B% ?3 aD.编写合适的重载方法(overloading method)
$ A& G% ^) K% ]# y$ v( }+ D
" }, z2 t; r; J: z, n# z7 S2 \8 B# G/ x
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?" W1 P/ U8 G- V  _6 x
; I+ R( M4 N3 F$ V, v* R* Y
A.MVC模式
' Q, x4 d; @+ @6 f7 h$ L( NB.抽象工厂模式(Abstract factory)
9 ?+ m, m4 p0 Y; O4 N% s: DC.单件模式(Singleton)
& |3 g: o/ Y; {D.代理模式(Proxy)0 N2 n$ y- A. ~/ Y4 V8 z/ A
E.状态模式(State)
3 g1 I5 L) ~) S, w: w8 A$ q. }# ]% o
/ V3 x& p! r9 N- \5 m, x) w5 R
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
- i% U" v4 N! Q/ a, @! b, g$ Z- |
A.1个1 k: b0 K: O3 O# N
B.2个
/ ?, \  i2 V* v% y! }! GC.取决于系统资源& X* v1 u" G: z, V' O  _
D.3个" X7 a. ~8 n; `4 E) P# G
E.想要几个有几个
- B- r& g3 H. Z- l* y  T0 T5 f; s) c) f& N$ L8 H0 N6 G1 u% `
( d% I1 F0 z7 C0 W' ~- l) g. e
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.多重继承
( Z4 f1 \* J/ A8 r' X& iB.接口
  q. |+ Y1 B- Q7 p6 g- v0 H. wC.抽象方法
1 t! |/ E0 K7 J. o% q6 P) [D.Private方法! F( R  [3 ~/ E. ^% @' F( q  @7 e
E.函数重载(function overloading)
3 G9 j1 o: ]. S0 ?- Z5 l
$ v5 P8 j8 c  L, D8 a% D/ C4 f! R% x2 j! c! s
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
' ^2 Y. O' X' P* e& v. h5 `. F; I+ \+ c. c: X& W! C9 t5 u+ T
A.__construct
$ J) I7 i3 s/ D2 ?# WB.initialize
, O5 y: J' t& iC.testclass. `! x1 k; _8 z7 P' q
D.__testclass
9 V3 P4 k/ N5 w( T) G" X, T' q- bE.只有PHP5才支持构造函数; f2 `8 t6 l% n4 w  M, P4 ]

6 X$ a8 e# t+ l. |; g3 ]! o/ b" P* d8 d: ^# I. A
8.一个类如何覆盖默认的序列化机制?
4 E; j) d, }0 ~% T4 M  _) i5 l& v1 O& A+ v0 z  M
A.使用__shutdown和__startup方法
8 E# D0 Z& Z" w- n5 _/ E9 CB.调用register_shutdown_function()函数! O5 D$ A  J9 [8 {9 Q5 l
C.使用__sleep()和__wakeup()方法
8 R0 p. [9 {: w& u  ~D.无法覆盖默认序列化机制
* d7 l- E7 K+ xE.使用ob_start()将类放入输出缓冲中$ V, ~- k6 I, I1 [+ z- L1 ]

6 w8 V6 ]. a8 ~& c4 P; Z9 h$ u) ]2 t. Q8 N8 d6 {
9.以下哪些面向对象的概念无法在PHP4中实现?
, R4 A. B0 I) U& M, `0 b
8 ?- y- E' E" Z+ o8 a- B@抽象类2 Q) ~0 p& F- v, F+ C1 m# Y
@Final类
# p2 j2 }! ^$ x0 L4 c) T@Public、private、protected(PPP)方法* q9 g. `- E; S- G0 h  w& d" y+ L
@接口
# V! e4 o3 ?1 z; o" x' j9 E
: k$ {) W! ^' q* t" s: IA.抽象类
7 ~' D1 l# {, f# ?- TB.PPP方法" z. ]9 ]3 I1 w/ q% g
C.PPP方法和接口
1 x/ G2 {( Z' GD.以上所有都不可用
( C4 P1 e% A# ?5 _/ Q4 ~$ y3 nE.以上所有都可用  R$ R3 ^  @0 e

; R. Z% {, l; `  s2 I& l; M/ U, h) v3 h- W7 ]; o: p8 Z5 e
10.如何在类的内部调用mymethod方法?
9 E( y. G  V; `' T, ]7 i- n# n: x/ V- E) T- b: u" H+ R
A.$self=>mymethod();/ h* g0 M8 u" ?
B.$this->mymethod();4 o: f  o7 {2 e: E
C.$current->mymethod();$ f5 I; g" l+ t& F! o) t2 Y& j0 U
D.$this::mymethod(). W) N2 [2 W2 J) {9 }
E.以上都不对
3 i0 ?+ E/ k. g5 ?+ V: ]( O  P. D
- e# d  x& {0 W% `$ V. m# 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.10
! i/ {% _$ ]5 y: A  U" QB.Null
3 V3 D3 V1 \( E" J0 W* \/ TC.Empty
; U- `( v1 k6 }D.什么都没有0 U6 v; B. T. J! ~' P
E.一个错误
9 u& n3 z( o; e8 R* `- m. ^" Q
2 D* N% Q6 i* I. ]+ |+ g
% @9 i5 N( C% }! M9 z$ C( s2 n& N5 Z( q12.以下脚本输出什么?

  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
9 Z5 M1 f" r' v4 d# y8 QB.5
' j9 S0 l2 p3 O2 l7 X; FC.2
) ^3 a% }( u  k$ pD.Null
$ R2 ?3 t/ k$ e+ q4 I3 l3 i2 E; NE.什么都没有
( ?5 G1 d. `! o
* X1 E( b, y5 v& U  @8 N2 W
3 Q4 m  ~: Q8 R% Z13.以下脚本输出什么?

  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.54 E. n$ [8 O5 A; D" b5 }) v$ V, p6 {- z
B.100 x+ k: U: ^. n
C.什么都没有5 Q1 L0 {8 J8 o: [
D.构造函数将报错7 n* Q1 ]1 n8 I/ m
E.510
) v: _9 _+ H# x: Z; y
: a0 B( g  u& J& X
# {" i" K# C4 D! K4 n  @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函数必须返回一个值
: P  ~2 A/ @, h" d5 fB.reduce_fraction函数必须接受一个整型值
1 n, C9 d$ w% P6 X4 v. l7 tC.gcd函数有问题/ Z9 |0 H* r4 q
D.必须通过引用的方式传递$eight_tenths对象$ s( p$ w) v! _% V( r( ?0 J" I
E.对象的实例不能传递给方法以外的其他结构。
8 e6 Z1 T; e- {* S
/ T1 r8 o+ a' I+ J% C$ ~7 r
/ U8 C2 s4 I5 w: D' g. I% y7 |( X15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法( k7 D9 d! n$ w( `& K7 S5 [
B.生成myclass的实例并调用mymethod方法( s" q5 N; `) P7 C
C.产生一个语法错误
, ~$ @3 K8 @* T. iD.默认myclass类最后被创建出的实例并调用mymethod()( z1 ^5 \( F) p. x
E.调用名为myclass::mymethod()的函数
; ?* I' Q+ w; w% s" e: o) u
/ w4 M6 ?- D2 c2 _# G* U  x7 S" |
3 z+ H* ]9 U9 p2 i16.PHP中有静态类变量吗?1 r1 ]$ p. t' W/ d6 z
) {" f  E: u: P  Q7 d% d
A.有6 g% W1 ~# t" D- \  |2 E6 k0 O
B.没有
) L: G3 L; x0 T! U$ ?& m, t( v2 r& T: T1 V' ^

) H% j% U" L* T5 o& k) 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.12 g2 v% y. I$ H5 P4 b
B.2% W  W  p& g: D! `1 E1 c
C.一个错误,因为没有定义a::$myvar
$ ~8 L, b0 I/ i1 e- UD.一个警告,因为没有定义a::$myvar
1 t* e. v' y  d, X7 F0 e. S) w& DE.什么都没有3 Z  P; P6 j+ i5 A
8 E2 S" y; J4 e8 `( S2 O+ a( b6 T0 @" m
( l" K- `- U6 u: g
18.如何即时加载一个类?
- C7 O& O+ W6 w
8 M  h" C/ k  b8 c+ p1 MA.使用__autoload魔术函数" F4 w7 |9 i9 e) S$ L! {2 J
B.把它们定义为forward类
( P' s' T& e3 I- d9 ?! tC.实现一个特殊的错误处理手段* A) c( T0 G& t  Z0 J
D.不可能
0 K- p/ \' O+ |+ dE.用有条件限制的include来包含它们
, L- y! e1 d8 W5 W2 a3 s
1 G3 ], b, {6 D- }4 A7 i: r4 S
4 ^9 H' E1 ?! a; L5 v19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
9 o# w* a' X. F" @' w* i9 W6 U! T% o
* Z& m' i4 \6 `# |; P# |    答案:__________
4 E( ~; a  X  t
& ?& R; i* O! g+ ?, ^4 L
( ]9 m( y% \2 c; `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
- Z+ h4 e, }- d0 VB.一个错误
0 T& P& _* B. @- n/ i% W1 OC.一个警告' j) }4 x( V, w2 s. }
D.什么都没有
' @% e6 `! X# i- n( Z- Z0 r4 Q7 l  `, p& j* P4 X" O* V

5 o) W. b8 U/ u/ ^  H8 e. V# Z$ j4 G: |! g' O1 T; E& e
答案速查
% H1 i7 B0 j# A& O: |6 S7 j1.类
, C; _3 N$ J0 @5 [& e+ i2.BCD: L. p( ?- M2 c5 D( D6 S4 \
3.C; w5 \# X0 w' |! c
4.C
2 Z) S, h4 U. v1 p5.A$ I9 X" n, S3 p: c5 @: C
6.C
& s/ I3 A; C0 ^$ Q/ j8 K, W7.C
! o5 M* m: z! i* B5 \3 X' N& @8.C7 Z( f" D6 R- P+ [+ h% K
9.D
) e7 D  B  }9 b10.B( W' ^% g+ ?  e3 o; k* R
11.D
8 C7 {* O+ `$ p% I12.B  b. X  E& r% X0 i
13.A$ {7 {( H7 d5 A
14.D
! X# r# d. M1 W; i: ?+ O15.A
' Y, P8 L4 H4 i$ E" j, D' e16.B
; v- J0 b" s" m3 S17.A
9 M1 [3 o0 q+ k& i7 e8 o' I! L18.D9 l" d# G' ?9 T# g
19.设计模式
9 n* {7 Q3 l3 ?; R20.D
% B2 J$ Z# Q8 B. `
# H( b+ C3 J! u0 e% t' `; S, }* `, E9 l; g+ p0 r3 ^+ ~: C2 F! e+ N# S
0 M7 o- \8 ~* Q5 I5 [, e
答案详解
) p4 h. a! i% p
5 P7 N# L9 N3 w3 F) k; x9 ~/ z$ s1.类是对象的蓝图(对象是类的实例)。) R0 m& i* a3 J
! a/ j5 j5 ^+ r# N
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
5 B6 I7 l) r( e
, \- A/ l; s3 l/ h6 M3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
7 ^3 v6 O0 b) _2 {( r4 w: P& P; @) U# I' g+ K. i' |7 ]1 K
4.单件模式可以限制一个类被实例化的次数。" q7 y; U( F" z" B. `# X8 j5 ~: F0 m

- G+ n- t' m- x: k5 Q5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。& o3 J$ Y1 F7 K! [/ I( R. L
8 m4 H( T$ v) M* l" f" g9 |7 N
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。; W3 C; \4 @' |9 d( ^* n5 b+ Z+ _

: |% |- t. e: H6 M7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。; \' H" A' R+ `" K, F

3 {# |4 G* g3 ]9 F, C8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
4 m3 ]/ {9 k6 B! |* R/ r5 m
# s9 w0 B( \8 T. Z4 ]9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
8 J$ q5 \3 _! e& L) K  X6 R( ^& F7 @4 \4 [* G0 s
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。' v8 t  a- e) P2 r  A/ K

% r& _9 U0 F( ^" j% Y* h) E( D11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
# l, _  w. o( Q! s2 r! _+ O; T9 G6 K
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- x  F7 i4 x1 I8 J8 {0 Q" D

$ G6 A! A! F. v) Z13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。& i, d+ ~( [- A+ E( U: R& _( k

" X9 z% u; O- Y6 ?4 [* y- Y14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
0 b9 X# ?% l& T! @9 z* ~回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:4 R7 l; G$ ~( x! I3 a
    function reduce_fraction(&$fraction)- \9 s- H; A; y; s3 s
答案是D。5 w- t  `+ H* L% H' |, {$ Z/ l& I

; ], T5 [7 S9 j9 |. D2 n  d4 @15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。% C+ b. b; V$ [  D* E

! o* O0 H3 Y9 \! C0 B16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
, U3 Z; X& O$ H
2 b! K' y0 C+ I/ P/ S17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
8 r, d  \( f  S1 A: a8 ~6 H8 {* {7 p  |
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。# J) g, v2 j' I

, u! K7 a# }( `4 @. W19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
0 c7 C) \2 o' U! E- e4 P. r" k, \5 @9 z' L% S, b
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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