返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。0 K( Y) Q( ]' o1 J
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
- P7 Q; W, Z5 w- x本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。9 R$ O' D  ~7 j0 w) Y! b

7 t% s! y/ j7 L2 b问题* u7 S  B+ b" S$ y# l
4 x8 w; d6 U& j  y; h' S+ O
1.对象的蓝图是什么?0 n# _. ]/ {2 u" g0 P

8 ]  _! U. M, b  G4 v5 i; `答案:____________# v3 R6 n4 }' p3 a% b
; b, z- o  W/ @+ l( g
0 Z5 l  b3 O8 D4 \$ @$ b
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  X9 C9 o1 `/ a. Y' i9 B% z
B.b) b2 i$ U8 v1 L1 b. T# C$ S% x
C.a
' m6 `/ v6 v# Y7 q2 F& W# ZD.d
5 X1 W2 d6 u5 v) d( n! KE.e
( s7 |# q) o1 {* e8 d; J2 r+ b( z1 D/ D4 c

/ ]$ ^0 `6 \7 m" M) @+ `+ f8 Y3.如何让类中的某些方法无法在类的外部被访问?
- i, L- p4 K0 W- {0 t+ w$ @  [
: X0 E  }1 \" X( PA.把类声明为private' i; E( |/ k' ~% W
B.把方法声明为private
/ O5 n; e. A$ ^2 l% mC.无法实现; f0 E( X6 \' ~! ?% K9 c, V- B& p
D.编写合适的重载方法(overloading method)
7 i, b7 _9 u9 j, q, i6 t
& F0 h' q+ \2 b# H6 ~' N7 N
1 J+ z1 x0 T& ^1 V' L6 e- o! E! f4.哪种OOP设计模式能让类在整个脚本里只实例化一次?% Z+ {3 Q6 Q* z7 ?

9 F$ L3 u( S* r- a& aA.MVC模式# d% u2 I2 x. f& m  ]
B.抽象工厂模式(Abstract factory)8 P4 Q# T* m* x- f4 K* R
C.单件模式(Singleton)# O; z* `4 T  U# t" ^
D.代理模式(Proxy)
" O$ H4 n% f8 B  q. kE.状态模式(State). a9 q5 y! N* J1 X& ]' Y) O
% Y' B8 O9 p% g; t9 p( a$ a
# ~+ V3 x) D5 M2 }
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
/ C( h$ B8 S4 V; n& c6 n+ V
8 y) G% ~* V3 X+ c3 `* O& @, |% }A.1个
7 _8 M/ ~" W  ~7 VB.2个& v# O1 L# K$ D) L
C.取决于系统资源
7 l" z( j! H( F" O! pD.3个
0 ~1 H  A' x# l+ F8 l+ QE.想要几个有几个
. v6 W: \" m  ~7 {! L2 B! S3 i* e6 I  M! e" m  k0 s
  A' a+ E( p6 G$ j* M
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.多重继承6 N) B1 g* v5 l' K9 a
B.接口& G/ N  R) x' b6 w7 B
C.抽象方法
- h8 s. R# b! B9 |# f: E6 fD.Private方法
/ t+ I6 |9 L" r% a* j8 QE.函数重载(function overloading)" |- T) f" ]# g, E% j0 `2 N

0 a1 X" e+ ~8 H! A
; ~1 b. {% A6 e6 z4 _- g4 A7.假设定义了一个testclass类,它的构造函数的函数名是什么?9 }7 v/ z) O& u
% W8 Q2 @, `9 M
A.__construct& x# w0 s% W( a7 m! u. e
B.initialize
( w+ U3 ~8 a& }! eC.testclass
, v% O5 ^. F! s7 nD.__testclass  m3 r$ X2 S! q: J; h- u5 w" _6 }
E.只有PHP5才支持构造函数
! c) v0 Q" B: U* R6 L
; i2 N9 x; C( z+ v* T
! X% T5 P6 `4 J- r6 X4 a! E7 p8.一个类如何覆盖默认的序列化机制?0 e' m) e0 W$ v5 e
7 Q$ i( A0 c0 u# A
A.使用__shutdown和__startup方法
1 y9 u% v: B) u, f9 YB.调用register_shutdown_function()函数9 L8 I4 D/ s3 _) z
C.使用__sleep()和__wakeup()方法% o5 J) a5 v" k0 H
D.无法覆盖默认序列化机制) ?3 c9 ]7 x. c$ F1 P" [; m0 g/ X3 \
E.使用ob_start()将类放入输出缓冲中
% l7 g8 d6 \6 v! Q* G- g
. \: R+ i" r0 |- ^/ S! \" R
# P8 s; M/ s; T$ H8 @9.以下哪些面向对象的概念无法在PHP4中实现?: v2 ~' _% s$ D/ d' d" K
$ r$ G8 f) S) b3 q
@抽象类. ]% ^0 X; E: ?) f- w
@Final类+ a. s0 ]0 C/ w; Z1 p# |1 _5 {
@Public、private、protected(PPP)方法/ e" T6 x" |2 ^; B- Y! a: s6 T, _. D  g
@接口! s7 e/ ]# r( {$ ~( I; L

- Q8 ?* t. X- D. XA.抽象类
, @9 k1 h' j8 t7 K. cB.PPP方法" A9 v6 \4 u! g9 u
C.PPP方法和接口
, m! q: c! L2 Y: g7 `. \* oD.以上所有都不可用* Q. B4 t- k/ v5 d' T7 j& |
E.以上所有都可用
$ m- K( u$ D$ k. R
  `  T7 a! a6 c0 A+ G2 V, @, ^+ _7 u  s/ }! y( U3 i" C6 F0 z
10.如何在类的内部调用mymethod方法?% p: W& g% i5 l# |- R& i& ^
5 C4 q# i( k$ j7 E
A.$self=>mymethod();" R, M; e" w1 C$ y- q
B.$this->mymethod();
- S% c7 U# t4 G4 UC.$current->mymethod();6 G# h* G& {; r1 ~- n5 m+ `
D.$this::mymethod(); l9 y' W3 t8 D4 P5 {/ n' |1 ~6 _. L
E.以上都不对
: g( Y' a' v. `5 s( E' I
* M( }1 n& ^8 T* ?- y# b9 C, W; _3 _) b' M. O
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.106 I1 f8 w6 d' b0 B, e* N% W
B.Null
1 T" ?- m2 p/ o: C7 T3 q! S/ \9 ~4 iC.Empty
+ m# Z" @" k& x- r' Y! b6 LD.什么都没有3 F7 j* y2 v+ N
E.一个错误  x) k0 i& e. _$ O
  r5 P, Z9 m1 _+ f

2 h0 ]. b7 J+ @" }! _12.以下脚本输出什么?

  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+ f; \. g( C" ?9 t# e
B.55 Z) U4 S; X- r. G$ g
C.2
2 |7 f1 A1 T& A5 DD.Null* T$ v! i1 k; i. w: \
E.什么都没有1 C* x2 s8 m/ [6 K5 ^; r' A& M. c

0 T4 m  l- A5 b% t. G+ y3 R- F9 \/ O7 f
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" V' N0 D& F. Y. r* [8 b% o
B.10
3 e2 W  K# f9 Q; F8 G$ }: fC.什么都没有
  v8 G# }; g# aD.构造函数将报错/ F' j1 x! v4 ]& N. I! {+ J, Q
E.5107 L* x7 f  R4 V5 j! m
- L. C2 |. y5 ~' N- E* r* y: u0 f

  w7 Q/ W8 s; p3 D14.考虑如下一段代码,执行时,$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函数必须返回一个值
* L& C! O! d1 W- \% ?; Y, _9 vB.reduce_fraction函数必须接受一个整型值
* X6 r! ?4 k& v# mC.gcd函数有问题/ f( X7 v) g' v" ]; [
D.必须通过引用的方式传递$eight_tenths对象
6 ?/ C4 g7 z$ W! p, g! \E.对象的实例不能传递给方法以外的其他结构。4 S' ^# k: x# _% r& b" w# j3 C7 ?
  D' ]4 x; }8 M  ~0 @
- d/ `4 o" D4 x( m, j5 |
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
' l% X: b5 }, E- |B.生成myclass的实例并调用mymethod方法
& q/ [7 ~4 D: uC.产生一个语法错误& }7 E& C5 L* E  p/ n
D.默认myclass类最后被创建出的实例并调用mymethod()
; B! q3 P. U% uE.调用名为myclass::mymethod()的函数
6 ?' _2 ^* g$ G1 k" i9 I/ O, o3 r4 z. u) ?0 \7 I

, T8 H- \3 z, ~16.PHP中有静态类变量吗?5 ~% I* L" Q8 S7 a! ^
" F5 q& h% `( I" V3 e  h
A.有9 |' y" A+ R0 o  l
B.没有
! ?3 q5 B  {' g* I# @4 Z! g  q- S/ Y: M  m
0 ~7 K; j* c2 V- ^% n) }
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 K, c2 ^  a1 m) F* }; v3 G$ e  O% Z
B.2
+ H- @7 j$ j+ q' ?6 w  ]C.一个错误,因为没有定义a::$myvar! t, @8 {; u: P& w) i' b
D.一个警告,因为没有定义a::$myvar
0 E- {0 L" U- D% s6 m0 tE.什么都没有4 }# A% W- q, t8 |, U
; r. \" U! d; J1 [* k" E
5 L5 W8 Z- {7 |5 S# U
18.如何即时加载一个类?1 x, M& a/ Z9 Y5 M  p
1 C$ p2 l- Q$ h
A.使用__autoload魔术函数3 M& Q/ T% d; E7 |) Z
B.把它们定义为forward类
8 a1 u$ j, Z; EC.实现一个特殊的错误处理手段
, F: t9 Y. ^6 A1 P3 |. FD.不可能
5 p1 S: m( ^; y. j/ _/ h8 DE.用有条件限制的include来包含它们
4 q8 n1 V7 z* V9 a" _2 v$ I1 g! Z6 K+ `, f
' |' e( j: x0 W
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
: O$ Q6 G3 e# C/ ]- @7 S& h4 z: w; V: X& A: j' @
    答案:__________
7 X/ {+ v) H+ F+ s: o  t4 l# P* l6 X' g8 l4 E

- b) E3 h5 Q6 s* 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+ b: D. z& R/ }8 f: I
B.一个错误4 z. R6 i- o7 O8 s. M5 j9 N
C.一个警告
. E2 f$ L, S4 E4 s' N5 q  v+ GD.什么都没有
3 [& @) s/ e8 g8 p4 u0 d$ r9 C! f4 x
& R+ i  C2 b! J* I

6 j5 }: }2 L& y, j, k9 `) P答案速查( W6 C7 p+ z. C( O5 R
1.类
4 B2 S; I% v9 g2.BCD2 x  w3 @) S0 T% X. K
3.C8 `. L- e) u5 Y2 f( X! G
4.C
+ _4 [3 s8 A, Y4 f5.A3 i; @4 L* z8 C0 W( }+ a; I
6.C9 L* y" |0 \5 B
7.C
  g9 r- L5 P/ F8.C
2 p9 \: `7 P/ a# t2 l9.D. B" }1 O7 `& X. E" |& F
10.B9 t& h& d1 e  S
11.D
) i! d, |9 y* @% N12.B1 i& P+ D. L# Y# m! D$ G
13.A" R) M3 M6 k; C! d* F
14.D
8 B, ^$ K- q: f15.A9 B6 I7 g& v/ L  X5 E- O
16.B
8 I8 r5 K5 W+ x% R  v6 e17.A9 [% Z) W: F8 f6 N4 J
18.D% f& b2 `9 V% F/ m
19.设计模式% {, [3 T) b( z+ ~5 e1 S' u
20.D
2 n: E+ f1 X/ ]* a
: ]( Y1 j  N2 A0 ^
. x$ w& M. [0 N0 h, C, x8 k/ x: Z, p$ K3 H4 B2 p
答案详解* h2 H$ }/ \! m/ z  O
5 ^) R% d$ ]; I
1.类是对象的蓝图(对象是类的实例)。5 K: Q- p, J0 @* j3 j0 T1 |
, e/ [% j+ E; [  v* T
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。# @. d6 a, O& \

# a7 c% v# @7 ~! \- N# b5 q3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
1 x' n' |+ I9 L: z! M$ _
0 W$ _" B1 K. y0 P4.单件模式可以限制一个类被实例化的次数。
- u- p+ A. w" ]* S+ H% p, B4 N, i+ J+ d, u9 ]
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。( V8 q3 P9 c( w2 V( L
2 s# G& g( f* w) _# t0 q
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
! X9 N  w4 W4 f. X3 X
9 h3 K1 w, }# h' _7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
. B( O* ?. ?4 A
0 X0 ]9 g3 N4 g6 K8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
  b$ ]- s) i3 X2 [1 U$ G8 s8 q
0 o2 E: h' u! w! t! N$ _9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
! _( F& z: K# M, \) [0 d
9 g- ^. J1 I3 k2 C% T% P7 q10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
. e. ^; J1 d' }5 y- J1 h7 q! Q* h' c( Q
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
" h. t( M; M; X. e6 o' X2 d. `! j' m9 S/ d3 E3 k" I8 v7 T1 T
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。+ R4 p4 l0 C! I% y( M
' r, j0 i' X' E' \. B* }, k* C
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
  E2 ]6 D7 I4 r- F1 X7 s' G! p% c# |
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。5 z4 r( q  c5 C, Q
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
/ I. T. ?" ]( m9 T' C% g    function reduce_fraction(&$fraction)
. M5 s& M9 B. ^: ~1 S答案是D。2 Z  O! |9 ~3 L" _

( z8 |9 o8 Z7 a0 H1 |15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
  {; K) }- u9 L1 i# v3 V
- \& y% r. b# @! e+ _16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
9 C  A8 k) J; ?) ?; i7 v- K
* ^) q; s1 ^2 y: ~17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。1 p9 t1 `/ a3 n
1 f. {$ D& t" K$ ~. x! L
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
9 ~+ k0 t2 I# Z5 p6 y* `
" w' w0 V% B; ~19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
  @7 `& u3 v# o! x" s3 U9 \+ i- j  `1 q4 X; ~
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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