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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
6 S) H( g' B' yPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。( _2 H. c& U0 {6 m: s% J6 V
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
, S0 q. r0 r* P8 u1 J6 H' v% S/ ^6 x* ~% k7 T/ F  z' f
问题
) T& \+ j% ~: p" S: W% g+ S+ m, C3 t& ]
1.对象的蓝图是什么?' w( X) N$ P: f* h

% ?- N1 q0 E; E答案:____________
' b5 H! ^: i4 P! G5 k" q; E# r4 H0 l' g) b8 c2 X

8 `' d. A6 t8 m$ @, j2.以下代码执行后,数组$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
, V* x; |2 `% fB.b) R- F3 m8 p8 |5 J; H1 {
C.a+ U! [) F8 I) X# E5 ]) O  E
D.d
7 w% Y- H3 @2 _9 \: LE.e
! V% ], u% e; y1 ^2 Z9 e: U' e: u$ Z1 v5 C: p4 a# ]
4 W$ y& [4 y5 T% V  S& g' u  b7 P
3.如何让类中的某些方法无法在类的外部被访问?
! v; l8 @: z) G3 t
  y/ y) C% {# sA.把类声明为private' |+ L- z8 V, K9 O
B.把方法声明为private4 Z2 s  D1 |# s7 P0 U7 p$ c
C.无法实现
: K" @9 P9 s; x- VD.编写合适的重载方法(overloading method)3 }% v, I; G6 t9 ]( x
/ Y, h/ F: u8 @. c) V4 a. X" t

$ Q1 G# H& N9 u$ j! ?; l4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
8 k* U0 A! r. P& }( |* M  P6 \6 e5 u2 {  W% Q' O5 j
A.MVC模式
+ j1 S! s& }% V( tB.抽象工厂模式(Abstract factory)9 Y% o1 Y6 v. p
C.单件模式(Singleton)( z1 [( ]- a) @4 {/ D8 K1 |- Q
D.代理模式(Proxy)
. I8 r: n! z2 hE.状态模式(State)
. a! D6 x- g& A. f
% y, Y- X8 h, o3 V4 w/ I( R# n1 N8 a
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
# d* x4 {) x+ s* C6 `3 F
% U/ {" M4 E! u5 J6 ~6 C2 ^A.1个6 ~7 U; B9 y% N0 d6 B# `
B.2个
0 ^+ l" |; a$ i9 |9 B% hC.取决于系统资源
$ t  D' @- ?8 Z$ z- p( T0 _6 y/ }D.3个) ~4 p' S; z& c" r/ x
E.想要几个有几个; N5 j! q6 k+ a9 O& N+ d

% J( `7 g; {; @4 i) r/ F6 G6 J5 Z3 z. {
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.多重继承
, L- Q2 f  t. v, A1 HB.接口, e) K4 x6 J6 ]* _1 L5 {
C.抽象方法4 A& w8 A2 V% H1 z
D.Private方法, q3 n: ^8 M, ^1 w
E.函数重载(function overloading)  W( A  X) Q  @( l3 w. H& i

+ B5 a3 i- ^6 s! Y: ~1 A  \3 q7 |! N
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
7 ]! n7 x! h( p% Y9 z8 Q
' F- \! c: C' r. [' iA.__construct
) ~% B: @2 c# I" qB.initialize& K0 I0 w0 g9 @7 \9 o6 w
C.testclass
! f; r; i9 w# }6 YD.__testclass9 l. U5 ]- P8 |% ]$ R+ O- d
E.只有PHP5才支持构造函数
  a8 b! ^- U* v6 m! x* [  o( h6 C3 z, T' h; b

4 v4 }' Y2 K. o, W! @8.一个类如何覆盖默认的序列化机制?
' l  r. \, u5 r
- e7 G: X  n9 s& ?0 F6 ZA.使用__shutdown和__startup方法$ N8 F/ r# C- J* l3 a
B.调用register_shutdown_function()函数
2 f6 Q- h& U  N) f  v' A7 IC.使用__sleep()和__wakeup()方法
9 @/ S1 Q. K1 _D.无法覆盖默认序列化机制
/ l; ?- I- f. N0 aE.使用ob_start()将类放入输出缓冲中+ V8 |* Z: c6 U; ?" L0 x
( L/ @. O: G- R

7 X7 Y. `: P4 R; z; M9.以下哪些面向对象的概念无法在PHP4中实现?
3 l3 X9 f9 ^( h" b) t
7 _6 I1 }% g8 ^@抽象类
4 N& H0 r+ Y4 o@Final类
( ~7 G2 {+ {" @3 q, Q4 L@Public、private、protected(PPP)方法* F, X9 X# ?: v+ P/ K: D
@接口) z# i8 ^! M- Y
; ?' l1 E3 p2 n# W6 L
A.抽象类6 u1 `) H# J; J6 e7 V
B.PPP方法, }! Q6 d* l9 F" i
C.PPP方法和接口1 L  W/ c4 y) x" _  J% c' _
D.以上所有都不可用
6 k" @. |  v& D5 l) BE.以上所有都可用7 G* O9 ?' C" P( U( G% {
, j% W# |3 A( c) y% U/ r; R

7 ?) j4 o9 P: Q% M; K9 z- }0 K! R10.如何在类的内部调用mymethod方法?3 z3 Z6 z7 u$ y" b1 j- t- x  x& A; l( @

; A' V" y" `! X+ e6 S8 s" SA.$self=>mymethod();% `) r0 v& F) _& a/ L& [9 C. D
B.$this->mymethod();' T  C7 t# ~; ]* O
C.$current->mymethod();
' L1 d, X: H) F8 xD.$this::mymethod(): u  Y- C$ Q" B4 W6 D; X4 h- U+ f
E.以上都不对
! G% N' z8 c7 W1 W4 A9 b' Q, @" n2 c' B- u3 {% Z4 K: H1 v- r8 S

- [9 ]9 ~2 X/ J( X! r11.以下脚本输出什么?

  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
; @% U. ]# \/ F2 [& t9 |$ }B.Null
! u: b# k$ ^, A7 v% F7 OC.Empty
6 `) A; u. M. _. _: AD.什么都没有$ q) C1 Y" F7 U5 c9 F$ x
E.一个错误
  ~8 Q+ y6 t5 \% c7 I/ y) Y+ G/ Y) g( m! x& n2 l; y/ y

% E/ j7 p4 u3 W12.以下脚本输出什么?

  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.105 S$ E1 U& G7 J* ~5 N% O
B.5
! i6 \4 [% K( GC.2
/ e$ n, q% Q8 j" O( w9 D7 [) KD.Null
/ _, v4 t) ~% \2 r; EE.什么都没有; Z4 _+ k1 q, }$ f7 |0 K
; |3 o4 X2 l! h$ b; Z& {, B" R

( _3 A5 l& d; V. p5 x' _, 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
( `. h5 R8 l4 w# {- CB.10
* C; v+ x* q: q/ GC.什么都没有
; L. B1 W4 k4 B6 LD.构造函数将报错
) P# F3 u3 f; t2 B" ]E.510
! J  u' Y- @' H3 U1 a6 E3 {  \
' Y* [1 B. |* V9 ^/ |
2 z1 s' H( G* X/ }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函数必须返回一个值. [7 L% K# E# e- Y
B.reduce_fraction函数必须接受一个整型值
- c7 Y& f  i+ W4 V2 K  TC.gcd函数有问题+ X; l/ s2 |( o
D.必须通过引用的方式传递$eight_tenths对象: e" B# C. N4 M: Z8 e
E.对象的实例不能传递给方法以外的其他结构。8 d/ J: j7 c; P) Y5 a  F
! q, S2 q' F0 ~5 P8 E+ ?

, `& d& H+ a' Q15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法% E' L" _6 S+ Y( X6 J" t4 @
B.生成myclass的实例并调用mymethod方法+ i$ |2 T( c4 A) y
C.产生一个语法错误6 B1 h  k# \! t" {! O- B
D.默认myclass类最后被创建出的实例并调用mymethod()$ h5 }& x! R8 W/ T, ]4 I5 q" M
E.调用名为myclass::mymethod()的函数
! x, ?: n! X. v& C$ H
4 [/ @7 z5 I; B* K" \3 X4 v
5 S- i: V! }6 n2 E2 b( ?2 }16.PHP中有静态类变量吗?  b5 d: a! e' H! g8 _. L
: U( P# X+ p& D" w& V- m
A.有* |: a0 _: G" w- U) y
B.没有; y1 o% j% x  L8 W
9 |4 F; F" L+ T; S1 k* Y; g! |
& [  M% {4 c' p( t$ V
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
$ m" _) j* W, G  c$ Y: i: sB.2
& j3 p4 x% ?8 e( z" Y# uC.一个错误,因为没有定义a::$myvar
' v' i- z! Q. ]. F0 H, XD.一个警告,因为没有定义a::$myvar
+ n1 ^' M" R0 O  d3 fE.什么都没有
8 S; \$ V/ h; o. O; j" g
1 U* B  j* U5 ~4 ?. A/ f4 t5 e$ w( e8 D6 F4 {
18.如何即时加载一个类?
0 g1 v8 M) t# F3 J9 B5 Y6 I! b+ Z
4 y: w' w& r( w4 z! UA.使用__autoload魔术函数
5 \1 E0 a$ r: ?# |" p4 j- sB.把它们定义为forward类
0 W6 Y. Y+ T# O. u: h1 {& VC.实现一个特殊的错误处理手段
2 O  g0 f2 y" f* S! }D.不可能2 L# p3 @& v; G0 g' y; l
E.用有条件限制的include来包含它们
1 [* h; ~# Z- `: M- O  D% g; P  A- t: t

' G$ D* g" P4 e+ _2 s! K- _19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
- _* {9 x- ~6 W* g! `" h
; E" Q, Y7 o) x2 x$ f( n    答案:__________5 A% u; N8 S$ Q2 w+ j5 o' }* ]

- k& K/ \7 H& u# b/ t5 M+ e7 v
9 g( P/ i5 v( V% E20.以下脚本输出什么?

  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
& B+ W% q9 j# q/ J2 t! Q, eB.一个错误
# T, f; A9 G  D5 TC.一个警告
' u: l! B3 ?+ j. G5 W9 S9 aD.什么都没有9 [2 L3 E6 k+ e% Y! i. I! o
1 O  J9 b& e( i% L8 J7 z% h  B
; b" D) F; L8 \* @) M5 E+ W' [2 d
5 E+ k  r- f" @8 r0 y
答案速查; Y3 F7 p  h" V% X4 k
1.类: y1 q; T# {0 |
2.BCD
" M/ ~. v2 H& A* C3.C
! `# a" @, D1 u) ~4 i* n4.C0 f8 K: m: [( e/ P7 j! N# {
5.A5 S) ~, M& J) B" d/ h7 T" O5 c
6.C  g( Y7 {! [9 Q/ d! O4 k
7.C5 _# z7 i( P/ C$ ~4 k
8.C
  Q6 s% s) T6 v5 V% o# g9.D
/ s: K! D9 b9 T10.B
2 X$ Z; V7 U" K4 I' F' l, [11.D
+ A5 W3 Y4 @$ u12.B/ F9 m4 Z4 x  l
13.A3 E6 `+ l  T0 J0 Y: M% D7 W/ I
14.D
4 a$ ~0 I, n" l% o6 L4 I15.A
% i6 q( s0 p+ _! l% R16.B9 V8 F4 R! j1 v/ G* k# _
17.A
& B8 W$ t2 s3 \- J+ d18.D9 c8 Z% D1 E/ W1 ~2 J5 r
19.设计模式: U) C* S) e/ ^* u0 @
20.D2 n& Q) u  w  N; k
3 U8 r) F. K5 I- t- e2 \

( l) k! z4 w- U
) g, w  h( H1 L# O: v$ K+ G; w答案详解% i: m7 c/ P' C1 q3 N( s
( o( _0 [7 u9 W) A- z1 d
1.类是对象的蓝图(对象是类的实例)。
& r& Z7 Z4 _" z' L4 P
" y6 h" r# g0 G* m# G" p! ]3 J5 O2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
7 [9 g+ |0 o: z# N1 u$ o% Y/ c
: m% V$ U, t4 C6 b3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
% o" r, e* p1 d5 ^3 p
( \; N/ \  m2 Z* {1 {2 z4.单件模式可以限制一个类被实例化的次数。2 y* T! u9 r3 h

+ P3 n; Y. s4 f3 H0 p* b4 t  C5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
- h! `( I. X2 g  D/ N8 q" Z3 M
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
$ T  Y) B7 `2 \
8 v, z. @" z3 |* r) B7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
: t6 @; z7 U: R1 J
* h' m4 w; \# X; x8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
* j4 I1 c! \) [3 b1 d# @5 e0 P2 f1 z: c- b1 V3 g, T. t+ ~" o
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。/ ]2 T/ D  }* h! c% B
7 l+ f, W; R( N$ T5 @5 f
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
# K" h9 R$ N, M/ s' N- c% I" a2 o4 u# ~2 L: u2 h" Y+ _
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。4 q) h  R; J$ L

7 u6 |8 D5 f" X! s6 V- i1 q12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。7 W* W9 h0 h7 b+ E

( _9 z5 U4 J! r* J' e13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。4 {: p4 `, z" m5 G
7 z( _; o1 n- f( n6 j7 c" C" M3 E
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
5 y/ y/ ?8 _" X$ g9 s  K  \回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:  |' F6 y- L+ e5 B
    function reduce_fraction(&$fraction)" S0 s  W2 M6 _& i$ w6 s/ Z0 I+ Z
答案是D。  L/ c$ i2 L8 E$ T) b2 ~
! t$ g* P# H0 P( V0 R
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。' b6 E( y. z8 O" [
% O6 s! U  ^8 I  E7 a! \- B- U
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
7 x  p  k9 }5 P+ x
  b8 N+ d3 U; `4 d# I7 a9 |17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
1 v8 u2 |/ }" W* Q/ J
3 a& n8 K. I, i9 {18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
, [% R, O, Z+ U  k& _8 d
- L: i( U4 f. k# Z. H4 L* h19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
, y, n+ O+ T& p% [$ L# O7 G$ h* a
+ u3 r* V# m% t1 a% H  u20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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