返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
! k7 M% e) P- `PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。& b$ X/ e* x' ^: W
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
# T  U, I1 T- s7 x! y) y
8 d8 ^2 b' K. j问题
  E( ]: ^8 b" r1 x. r  X8 d1 z% z+ Z5 R* T) C8 P# Q
1.对象的蓝图是什么?' x0 G2 K/ R4 D0 ]
/ x) r7 @# k$ M2 k* q
答案:____________: r$ G2 ~2 e6 I$ P2 n% K% l4 o% M$ x
' @) a) r# t% D
) e* n2 n; h9 J& U; Z. Y
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; v4 ^/ q3 [, Q9 Q7 k3 n
B.b- _$ q8 l* k6 S/ n; d: n
C.a( q# ?8 l2 `& p* C$ s/ {; N0 G
D.d
* S( n: W4 Q+ ]; w) _4 ^3 IE.e
! |( v: i) z8 f
- `5 m4 e' i0 E* m" L8 B/ `$ n. L( h# z9 ], u9 N* v
3.如何让类中的某些方法无法在类的外部被访问?
" U. K6 G- N2 b4 v9 ]8 e5 h# k: F1 N% y
A.把类声明为private
. I7 x" K8 W' k6 Q+ {0 r6 F; ^B.把方法声明为private4 v( R& s. H# q. y
C.无法实现$ ~# v: f' c, I" \! l, c
D.编写合适的重载方法(overloading method)4 D7 ?! R. J6 V" M) S6 K  ?

; c% n8 k8 W  p) c
1 a% c% W8 x- d- i! D4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
( v) J+ n5 W1 n) k1 F9 u
- {* W5 A0 L1 Q: r3 jA.MVC模式
( h, A/ @- y- ~% ]* v0 F0 i, }B.抽象工厂模式(Abstract factory)) v( }( z2 v. `7 M. |4 R& m6 t1 c
C.单件模式(Singleton)  I1 E: a5 }0 ^) ^, L
D.代理模式(Proxy)
6 O  Y8 s. v* t0 _; B4 wE.状态模式(State)
0 V$ x$ F1 N2 G7 _7 V4 j, ]$ o8 p- e+ k9 m

6 `6 G( ^( g7 \5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?. H9 L; ^' ?: E% q
7 b) Q% V: v% G4 E% _4 D! x  o
A.1个2 Y- O4 I8 K% I- X; S8 W
B.2个
) W8 i0 U6 ^7 [' K' A: X: rC.取决于系统资源
; L" S1 }+ _( ]7 @! R; }1 ]D.3个1 c/ L- D% }. J4 \
E.想要几个有几个3 m1 @5 e$ t% ^, x

; m* L# k. I% Z, \
+ v# K7 c( ~  r; `6 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.多重继承
0 P# n3 o2 }6 D: u2 NB.接口( d* ]$ g* R* F4 s' ^$ E+ {
C.抽象方法
3 B" G7 A6 l6 k, O- ~D.Private方法
& u5 o1 z" S  [* xE.函数重载(function overloading)9 B+ K/ p; `6 T
+ T+ S0 s5 a# w, o- Y8 o2 a* V
9 A4 i, q- X) V- Y6 w+ r
7.假设定义了一个testclass类,它的构造函数的函数名是什么?1 |, K; U& i% Y6 r" _& d4 I
+ _3 N' o' A' Q, W. O$ U
A.__construct8 t: I( [& |) q/ i% b" l
B.initialize3 K! N- p/ f, e6 J
C.testclass
0 F# l; A: n& G/ n* P) vD.__testclass& ?& h- f- }4 [% ~
E.只有PHP5才支持构造函数
6 z% R( q! ]0 ~( N$ S/ V5 l& R8 O/ ]

2 L) E& Y% G) t( j2 n8.一个类如何覆盖默认的序列化机制?) ^7 o" H& t* P7 h4 m
4 R7 U; D. S; l% q* y7 B- C# C
A.使用__shutdown和__startup方法
  f+ J5 a, {$ k+ d8 pB.调用register_shutdown_function()函数2 V& h' c3 S/ q0 x) g+ J
C.使用__sleep()和__wakeup()方法
9 f; ^* q  t* N" YD.无法覆盖默认序列化机制
5 `, O( c5 z: l8 ?E.使用ob_start()将类放入输出缓冲中
/ w( @6 F2 q3 c& s3 `+ \$ v( C9 K* E/ h' V1 j; `

+ e: N& F4 H  C. X9 [9.以下哪些面向对象的概念无法在PHP4中实现?
: {& F0 |) {* h# {  c, d3 ]$ ]% [$ w
@抽象类9 H* g4 i' _0 b, N% Y5 j
@Final类
/ L) z( w5 Y9 M@Public、private、protected(PPP)方法
8 [7 g2 Q7 |- ~@接口4 Z; r! N6 Z' h0 r9 W( G
: u. B- Z  ^! a. M6 u
A.抽象类
9 Z) I$ d# q! l" s( |: Y$ jB.PPP方法' L: j0 C0 A5 W% I' B, ?
C.PPP方法和接口
, ^) b0 b9 {- N2 j9 |* w. }/ ID.以上所有都不可用) k6 {1 `, y! a- X- B  @; M# p
E.以上所有都可用/ y9 c( V) ~9 z; p2 A# T. I8 ~% _
+ d: a8 m" Y) \3 s
  `+ H5 [. _( n0 r' b
10.如何在类的内部调用mymethod方法?
) H2 F' W2 _  i" L, B" M$ y4 o4 ^+ \; J: N* D* m
A.$self=>mymethod();# V; a( N& S$ X" D3 _
B.$this->mymethod();8 K( f: T& E  x3 h7 g
C.$current->mymethod();4 [0 u2 i/ N0 Z9 `
D.$this::mymethod(). x4 r* P6 X  s7 |- \
E.以上都不对- G( W, i( @. n, N; F
6 S5 `3 R. n" `6 P0 E. G; p( u5 {
% U0 d% k& y" Z0 m$ t9 v% g7 y+ i
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
/ c- ^# Y1 I9 U# I" i+ GB.Null
- C! r: R" Z" ?) AC.Empty
2 g2 D# ?/ E& O* l4 h% RD.什么都没有5 `$ _' H/ j; ]' U1 c% U# J
E.一个错误4 Z7 w7 T1 i+ B. r1 |* E+ R

! x% s; z# o6 M  n1 f
: f) S" C* B8 |. o, `) o12.以下脚本输出什么?

  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.101 {+ O6 S* G& {1 N, a8 z- N- k
B.55 d$ L9 o& i' m3 ?) h
C.2/ k' a9 k0 C) {0 C$ e+ Q$ M2 s
D.Null
# i. F6 ?3 T5 b6 A8 O$ _E.什么都没有
8 H7 g) \% Y8 L/ Z
. l" o! o; m- J7 D( W  X3 n- n  t" m4 v1 h1 |: l0 y
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- z( D' K; [  ?! }& Y7 y* J( I
B.10
6 B4 e0 X/ ?- k. o2 M8 MC.什么都没有. _: w& o+ P3 w- |
D.构造函数将报错
2 X6 i# G# L% x1 xE.510
2 j) z8 @7 v1 B% i, G8 y1 N+ M3 g; q# U/ x) t, ^

9 j/ l7 u4 M6 T- g0 ~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函数必须返回一个值
* ]  W# [, a/ ]5 b# l9 NB.reduce_fraction函数必须接受一个整型值" c. _1 `+ D9 E" d" g" w4 A6 z
C.gcd函数有问题2 R! S/ ^9 a- [0 l9 l
D.必须通过引用的方式传递$eight_tenths对象- T- P4 }$ O" b; U/ g) u2 k
E.对象的实例不能传递给方法以外的其他结构。4 i. s" R# z2 Y, E
, o& B& W$ Z' s: F4 s
: b+ c* W1 @! ]" P6 E' g( K
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
6 x( Y/ a7 x. p$ {7 D6 rB.生成myclass的实例并调用mymethod方法4 @- W2 g/ y8 a( E% `
C.产生一个语法错误
) A% u& P5 j+ @( t- q; L' UD.默认myclass类最后被创建出的实例并调用mymethod(), G5 c' x- @, p% w2 w. K
E.调用名为myclass::mymethod()的函数2 x. K0 @$ g  p3 l5 e* k! r

0 n- |' X- a; l+ c3 F' U5 {/ y4 w$ Y* h- D
16.PHP中有静态类变量吗?
: D: V: s- Q: |" E
: Q( J0 k/ u) H' CA.有
- {2 ~1 V4 e, V- G! e- RB.没有
0 F# Q# Q  _# H, z$ h9 Z; P) @
1 \$ ]4 H+ X' x7 N2 u
  F  ?% K6 D/ A+ p3 _0 k$ F17.以下脚本输出什么?

  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
- e7 W2 _& \" F) B' {* JB.27 ^( }* o3 I( G6 C! m2 z
C.一个错误,因为没有定义a::$myvar1 _1 W/ b/ z4 B4 p" |' O+ _5 b
D.一个警告,因为没有定义a::$myvar
0 G  f/ o9 H3 n3 j0 G% f3 bE.什么都没有
' ^& M6 A6 E7 w2 N2 d2 ~+ g" I, o+ [6 V) N

# f+ o, X- U/ f" l( [; d18.如何即时加载一个类?
; r, |* m4 _; i  o0 B
- d9 c2 f$ z2 e# JA.使用__autoload魔术函数6 l) G/ Y* e! l: T
B.把它们定义为forward类
6 ~; p8 `+ |; |7 h: L' Q$ @C.实现一个特殊的错误处理手段$ |( x9 f- D0 U( e- K/ Z4 D2 y
D.不可能
( t: e- _4 ]8 I0 uE.用有条件限制的include来包含它们
6 \( d* \+ G$ p: Z/ y
- s- l* I0 y  L3 W" W5 O, y& l
& |/ b2 [( ]& `% L' s, p; Q19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?. M! L3 |! K+ [$ r/ r) x. J

* {# f' w5 d6 N0 {: v' }; M    答案:__________
8 ^/ ~: H/ O. T! D2 P) ^+ p4 h7 b9 z
) ~$ {  }0 B3 Y0 e
* O  u; O: E& s20.以下脚本输出什么?

  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
4 i. g+ f( A. d% {; K; z" ~B.一个错误
% g  q8 U) S* `C.一个警告
! f% w- [. ?1 M0 u! AD.什么都没有
7 o( j  a: O4 _) Y: m7 Z6 J$ k. W) p) ?. d+ M
1 ?: }% |( c$ V1 a1 M' r7 R( h

# n! R! H; K/ _  I9 B' n答案速查
: h' x( l# a2 O0 M% ~1 t1.类( r2 U% M* K' d! j# v
2.BCD
! c3 S' g% J! V' t+ {3.C
) {4 t* s: E4 X( P. H0 q5 b4.C$ f$ u& s% e" ]5 P' H: i7 q+ W
5.A! [; D1 [- f! [0 |. _
6.C' \9 e3 _4 I& l9 `5 v
7.C3 d! l/ {8 ]: o. y! G- i
8.C
0 c& A4 m- r, l5 S0 E; `- r* g9.D
; u+ a0 j0 X7 J/ p10.B
8 R3 Z* m: `7 s) n: V$ h8 ~11.D
- [# X- H8 W  K! p  b  E12.B
. I1 V3 m! E0 j13.A: [/ ~4 x& H& w
14.D
4 p) z# r: L/ l% w" B15.A. ?  M/ J$ M% U
16.B
' M% y8 O1 f; l3 ~8 |. R* Z17.A7 T; F  z% w/ i. k0 Y9 k) h
18.D* I, S/ y- ]# s
19.设计模式. Y+ u0 x9 ~/ C$ X2 }& r
20.D% P/ Q% R) y+ B! B; Q2 U

4 H0 D' J. a8 @9 W) o6 P- q6 O
$ U# t8 F& s& Q9 m( N, e8 d5 d
& a. _( O- g( L! _3 I答案详解5 K- r( d4 r! h" N" |. x

8 B  p) U0 L! Z/ q1.类是对象的蓝图(对象是类的实例)。
/ q" z. h2 M/ Q! S
2 k4 i0 u, R& q* h3 }( s0 h2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
: Y1 \1 J$ K/ X! X  x% [
0 E/ c  `2 w3 f$ W. F5 u3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。9 G# p4 ?  ^$ V: E: t' T9 u; Z. d
3 P/ O7 O5 }3 v( E" ]
4.单件模式可以限制一个类被实例化的次数。
" l" d. m- q7 d+ e1 s$ [- R, i% r# y* s
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。; Y: W# J6 P8 J2 H( E6 Q/ ]2 j
/ A- x: H8 G  J- ^) m4 ?
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。. m. @3 p8 I" j& a
6 ?$ L* q6 Q  b
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。, x) W( [: |4 p4 y

0 j: S0 v# W; W9 F6 S" ]% i/ U) W8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。7 w4 p: c5 y: T+ t3 q( I

) c( ^- l" `. k; e- }9.PHP4中没有题目选项里所列的任何一个概念。答案是D。' |9 @& C6 A/ |

0 |  b$ c) H5 D* u2 C3 @- y10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。0 R) S( r7 k/ F! `" {& l
5 E2 K" O! m  U
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
" u( k1 L# l7 X4 L" l5 k: L9 j$ K# w. V- J5 p
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。0 z# E; a* Y& e) ^/ I9 b
: P) @& v8 {! I
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。2 E6 _. ?: v, t1 J' y
  ~) w9 y6 {1 @. M0 ]; e
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
$ Q- C1 P9 X. O回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:/ U7 ]$ ~0 N8 F: W; {8 W3 B( T
    function reduce_fraction(&$fraction)7 G  b2 B: _9 i7 ]1 W8 N. {# T5 A
答案是D。4 X% c" c2 q! g% E, i- e+ I( g4 K' B
' ]1 J$ U1 e1 |9 e- _1 u# w3 d  d- [
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 [+ e; g" z) B) J' \) o4 y$ N; C4 {: R4 T. U7 H4 {
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
1 f5 H) X' r$ M) p* ?9 Q7 Q, c( I
% b7 s2 t) z! X' \5 u, l1 ?17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。# [  d/ i5 i5 f: U- Q5 i
  v2 Q' V4 U# X! @# a3 s
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
# y. n! E1 y3 O5 l; d5 A
6 ?5 E2 W1 K/ R' K8 C/ ~19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。9 y# J% O" `& ~+ z+ G

% m, }" A/ {9 h6 ~1 q( a20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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