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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
% \& n7 W- `" l" }( GPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。8 o- h; y$ g. x4 |. b( T
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
2 Y! b8 r* K; a4 z8 Z
( s/ p* s0 ]7 _问题* W0 `  Z0 }) m0 Q  Q, Q7 Q
: ^( M! U1 T/ C9 y$ q- N
1.对象的蓝图是什么?
, _+ P3 H6 ^  Q  r
* J; M- V# ?# M: B: p1 w0 B6 A; _# E2 n答案:____________
9 f/ h* Q# x# H. _% n1 y
, ]+ S2 Z1 j4 p* O' h3 i6 C5 w- n, f
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
0 q- C2 ~! g( ?( k" y  xB.b2 K! ~" |4 m: |  G0 k' C0 `
C.a
8 [( H1 P' _  ~+ {; [- ^D.d
: X, w+ A3 r, h  i) DE.e
% ^. @4 l- _( x4 _% ]6 {
# I( N2 l! N9 Y; W8 t+ X  S) v: G# }
3.如何让类中的某些方法无法在类的外部被访问?8 y5 E0 }4 Z1 _: N3 ^

& @! A, m# w8 [A.把类声明为private* b" m. n6 I, F. L+ W1 ]
B.把方法声明为private
9 k% s/ v, {, k; D$ r5 X6 p4 U  gC.无法实现3 `3 S4 P, z, Z% g4 N  C$ K2 D( z
D.编写合适的重载方法(overloading method)
$ ^0 T, T7 c" t, l
: [9 u- ~' ~8 U. p8 m  f& k3 ^* k
4 z  Q9 d( f  i* D% P3 n; L" q4.哪种OOP设计模式能让类在整个脚本里只实例化一次?$ M+ z' ~6 ~3 B7 j: E9 J
8 g* d" d4 m9 d9 R
A.MVC模式# K. `6 Y5 K+ F. O3 k: I, P' u
B.抽象工厂模式(Abstract factory)
& j/ \4 K& e/ L- ~1 H( }" yC.单件模式(Singleton)
9 D; U/ g' D7 ]3 m0 VD.代理模式(Proxy)
1 D) |( Z! s7 X  \( N, h9 J; IE.状态模式(State)" Q2 F4 P" d5 u" g& M( |+ U

; _& @7 \% w  b- y+ o" o
; E% J4 J" y( A' L5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?2 g9 M0 q* K- W& e: a0 E) z* a' ~6 e

' @( M# F1 I1 Q5 u, f8 KA.1个4 V0 o9 Y4 A, F/ B1 m1 s$ o
B.2个
) f) y# }4 L; D; oC.取决于系统资源5 I; s& N9 z5 m: q/ a; E0 _1 ~
D.3个. a4 S( E  s! `( }3 z! F
E.想要几个有几个
! n5 v% F% o% N+ W- s) f1 M6 w8 {1 t
2 z- {0 }( V/ W6 t! T5 i, k& e: u+ ~
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.多重继承4 Y3 J- X4 S4 p2 c# L
B.接口' k9 }- u8 G0 Q. h$ T3 c! }' O
C.抽象方法
; Q2 X, d4 R: K2 b' R! Z4 ED.Private方法
. K5 ]% c5 M0 Q0 N! BE.函数重载(function overloading)
" Y0 T; \  V( v" T  K: h& c- L
4 ]% ]! S. H5 k$ J" h, `' G* W" _' U' E  B* s. w) t
7.假设定义了一个testclass类,它的构造函数的函数名是什么?  a/ \4 x; A3 L! [# j5 A. h- H

4 @( h) _* m' q! B( LA.__construct
/ [  J0 P, f& QB.initialize: z1 X8 q: B; b  p) ]
C.testclass
# a' c: P% c& I; x0 n% i- aD.__testclass3 h# H' Y! A7 l7 l0 y  C, j% o/ D
E.只有PHP5才支持构造函数. G: B4 c. k7 g9 E, k4 |

$ @% N: l( j, |. a* o, P  Q- ^! g% ], F7 R' Z
8.一个类如何覆盖默认的序列化机制?( C, M3 [2 l) C7 [" f- p

) i) m3 u7 ]. K: a7 }A.使用__shutdown和__startup方法6 N$ M! q1 L8 X: a; F
B.调用register_shutdown_function()函数5 s) H; X: W* d$ q5 I$ B* O( v: I' f9 w
C.使用__sleep()和__wakeup()方法# G3 B! E% X3 i* f' k
D.无法覆盖默认序列化机制
6 ~' g; A! U2 Q( BE.使用ob_start()将类放入输出缓冲中- L, a0 c- Z) U8 L' H; R: h

: `4 k9 ^+ ?( X  I# b
; U5 `  k8 Y. J0 A9 d$ c9.以下哪些面向对象的概念无法在PHP4中实现?
- f* m8 j# z3 I: @: v; v1 `! a! T: \+ Q0 O# o
@抽象类; V% ~% p  ^" N2 A) v9 @" M% H
@Final类
% \5 l8 Z2 C$ v7 k8 L6 {@Public、private、protected(PPP)方法
- N4 `' G& `5 n# u* w4 g! a@接口, X, ~3 q& ]  i$ X+ B% \* F

* N; V# s: K2 K) M8 L; eA.抽象类
( S% _2 o; J- k  hB.PPP方法
9 X  g6 P; }! T1 c( g# UC.PPP方法和接口
1 u. b" z% t/ q5 ~7 TD.以上所有都不可用3 E9 k  Z0 O( C! V9 Y1 D- l
E.以上所有都可用. U5 X) G( P5 }5 H% h" j) O6 G0 g
2 V; L2 N+ ]- V9 ^. X
6 n; K7 H2 c$ ^7 I+ k( C
10.如何在类的内部调用mymethod方法?1 I* v/ q4 P+ _6 f) E( e' E5 Q
! t# e7 J% I% S6 n
A.$self=>mymethod();
1 l8 O, K  {* c8 QB.$this->mymethod();: o  o8 @1 g. q1 z; N- b& w
C.$current->mymethod();' o# N8 p3 [" G% N( z6 [; o; U
D.$this::mymethod()4 V2 [, O3 r, [" V
E.以上都不对
. r% D1 q: I) l; j' u0 S# M9 g* J% F

0 x( L% A( U8 \. v8 l$ b: W11.以下脚本输出什么?

  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 c" R- E" Q+ K  X, o. r
B.Null- \5 J+ e7 f, u2 @
C.Empty
7 y; H) C( A5 \D.什么都没有
& i$ y; z. r! EE.一个错误4 j1 `5 a  I. I, x4 z" q8 W

; _8 a* U, f1 k+ @% I1 y
/ W  k% \6 y, l6 K12.以下脚本输出什么?

  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
  A0 H! k3 Q( y6 L4 Q& d% gB.56 ~- n+ U9 Q) ^# U7 p+ G3 L
C.2! X0 x/ ^& a0 T' Y0 C
D.Null: J1 t) Y3 b+ l0 h8 w; w- f
E.什么都没有: m- F" ^# [" C1 E# p
; q8 l+ T( P  b6 ?4 X& m

  F2 L4 X  @  r: E+ ^0 B13.以下脚本输出什么?

  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$ G' }$ f4 F' F* I) i
B.106 l2 L0 f" c' ]! o
C.什么都没有
1 ?$ G( L4 O# a- aD.构造函数将报错
$ R8 b* q+ C: ]1 `* l3 s& YE.510
: E& [+ x% i9 K+ [
8 T( R- i  a7 y% A3 k2 F6 _2 D- s0 r. d9 T: O1 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函数必须返回一个值( N0 E; ]7 {' t
B.reduce_fraction函数必须接受一个整型值
" z4 i) u6 U4 {# _C.gcd函数有问题
& o* ?6 v" R' G4 N$ j7 P+ ?D.必须通过引用的方式传递$eight_tenths对象# H1 B6 h2 j4 T, t! Z5 \% E4 e
E.对象的实例不能传递给方法以外的其他结构。
" h% m8 \4 n7 A
' H# k$ g) }, m! q. h9 i
9 v1 T7 u8 W6 w! V7 V, T, A15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法  e4 d. j' y# }3 k; g) @# C
B.生成myclass的实例并调用mymethod方法! U$ ~- q' B) Y) N' q& ^6 Z. g
C.产生一个语法错误) w+ Y" @% @7 ^# U, m8 z
D.默认myclass类最后被创建出的实例并调用mymethod()- @) @( }4 K# Q/ x+ n9 P, p
E.调用名为myclass::mymethod()的函数
' H4 Y  m9 E, A+ L( k$ N5 }6 J# k7 O
4 L& P1 k: w! E
16.PHP中有静态类变量吗?/ I" I3 I) k5 [( J4 l

4 _* ~9 ~2 C  u6 G8 g" qA.有+ J- Q; M, Q, }1 S
B.没有6 d7 A$ L0 ^) v9 [9 Q, j

! }; r2 l5 O& J# W  q% S( C0 h  u: U8 V% K, O
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.18 M  n& k- N+ R- w2 I; B; P8 {, V
B.2
; b/ q( `7 Y# X  I! J! K$ r- c9 uC.一个错误,因为没有定义a::$myvar1 D" P9 m; ^% }9 W$ W; A$ X
D.一个警告,因为没有定义a::$myvar
9 o  P7 @2 \4 ]( K) j6 a& _% S$ j- ]6 ZE.什么都没有
, O( \7 b) \) g# J, v' V) i' _8 N, E& c4 q
+ T$ B# V0 l7 d' T, d
18.如何即时加载一个类?, [( `4 ]' r1 x

1 H* Z3 x$ Z& i- Q+ e" B1 ~A.使用__autoload魔术函数
8 y/ w% \' E( {8 E% ]2 u1 W) OB.把它们定义为forward类' ~+ q! K' V1 p7 A% E% ^+ F: s2 T
C.实现一个特殊的错误处理手段
+ a- q0 T7 k: u+ B- vD.不可能
* B# I+ s2 P/ F0 Q4 K2 e9 _E.用有条件限制的include来包含它们  K) C, _5 [5 `! H, a8 G2 U2 w6 f( B
3 R$ h" J, h, i1 N: T
, j1 }2 m/ c  B- f0 b# ^" `$ J
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
# F& e8 p: \( s' L1 j, D( [3 l* C1 m
7 L- D1 n0 W" O    答案:__________
' R  z3 h) k+ R
8 Y' ~. a, X% j+ f! W
& D% V  z- Y3 x- y+ E# d# J9 h20.以下脚本输出什么?

  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
' w# x- P( u" B4 {B.一个错误
, C9 r- L# H1 h0 W" A' Y$ AC.一个警告
1 N1 E2 d: A% ~* p" u0 M. VD.什么都没有' {  Z- A- w5 _+ p. H* o' k" A0 D

% x# [- s( f5 |! ^( U2 N+ m, Q/ H* D9 z# _4 T! K! R

8 P' P0 M  n0 T4 y答案速查" k. b% I% Q3 ~  l
1.类- e+ N3 [7 h6 s, ?! D& O$ G& q" G
2.BCD
% y1 Q7 D$ r6 x$ B& i4 d7 @3.C; l$ n. c* V  w/ ?- D6 T% N
4.C2 w0 \5 X( E! Y
5.A
/ a8 C( ^/ p& n6.C
, i  D4 @8 d6 F9 R3 d8 w7.C) F$ m- @( j  Z) |. i0 h- l( J8 ]
8.C
7 W% r1 {1 c' J9 a/ M9 f9.D
/ {8 f6 f' M+ e' F10.B( }/ W- }/ V" \4 M
11.D: C! E/ l. d# _2 D# P
12.B
* O% c' `( @1 ]5 Y; l8 {13.A0 n( H- Q0 r9 X3 x- H
14.D) B% g7 \. p% {' U
15.A; x) H: A* x9 f# J
16.B% |' y1 H% I/ Q
17.A
1 N4 K# z1 c3 _; _( x1 t' @4 ], \6 {18.D
) |7 ~$ i0 u* N% c4 D2 Y: N19.设计模式/ w% }2 j1 H7 T5 @4 r
20.D4 R- v% C) a, g

( P, w/ T8 X! H2 `: [
' K, p: `  u6 g) r& r) [5 m
$ o! V" J& H# O7 w6 F答案详解
+ g& [+ H# [9 u( o
% \/ ?/ n. _) D" ^( r" b1.类是对象的蓝图(对象是类的实例)。
( R# X  p) n, @2 n% q1 v6 v: `4 \( ~$ x
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。( |: n1 I. h! y9 h2 P4 b

6 J9 E  j. G% r3 ~  I8 a4 ~3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
: z  b$ H3 H" M( ?! ?2 R# p4 i5 W/ S9 R4 L2 q
4.单件模式可以限制一个类被实例化的次数。
5 K  U! Q# q+ x: {+ P6 n4 ?9 ^  B2 ?" f9 ]- ~6 H
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
5 ?& Q; D7 n5 R& \% p& w6 ]9 H( B; T8 j8 V7 c
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
; e) C4 C6 a. _" Q; m7 r  Y
/ W+ J! T3 n2 l7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
& l; u) b( f. B+ o6 z$ v. U
. `6 ^  n; L0 G  y& r! [8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
2 o! r8 w. y; K% f
3 s/ z' W5 O3 h$ M9.PHP4中没有题目选项里所列的任何一个概念。答案是D。3 ?$ {' k- H4 {$ W5 @, E
9 f- d3 j& t; }4 R/ ~' s% ~, v
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
9 M0 H, l1 I* Y5 M# v
  q" k4 ~( L3 i8 i- Q6 u/ p11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
- W0 [5 O3 B4 F& R7 N! }1 ^+ ~1 e) Z5 d6 I1 ~* Z3 Y8 M
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。' s- ]1 Q9 S: ?8 x$ s

9 I# @8 O% y& Q* _( R7 H13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。2 `5 {% \' z2 S. ^
, Y" T4 I4 L4 [  x% I- y! }. Z
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
" F) t# A# W& O, _回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:3 }4 H5 m6 J2 `. |5 i( n
    function reduce_fraction(&$fraction)1 b! Z& `1 D% Z3 q) s
答案是D。( V. P+ l5 X8 z  f( k* x

( U# N1 f0 O) {15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。+ K$ u/ i) R5 h1 d8 B6 p3 [1 p
6 l' A8 I9 J; _( g
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
3 l: U9 Z/ C7 C& J0 Y: {" c0 G; p
, C9 V3 m" v" R  ~8 ]! g; r17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。  g& m* f  [2 @/ q
* o4 s) Q4 k. q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。9 s3 x5 l  I) N8 B9 g* Q- _8 j& Y' h

, A2 E  H8 {. ~7 K. S# I1 H19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。6 n, i: A: T, k5 e: ?! J& h: V

6 V, F( I4 j' o1 K, o0 }20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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