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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
. G0 e) X5 t1 V! E; GPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。, S6 a# D' K8 C
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
3 h7 O. e- Q6 ]
' z7 M* D* n' G8 N问题
( D$ o5 A/ g! \4 x: u
! [$ C  G/ H  z  S1.对象的蓝图是什么?
) [  w! h$ ~/ B3 k$ b+ y% N
" D9 ]# i4 p1 w. Q3 M6 v; o  C9 T答案:____________
; n! J9 k" Y1 E  Y' T$ C7 S5 J& M# N5 W. _# I0 O3 L4 Y  w

" ], Q/ ~( T- p: H- h  J8 m) |; D1 p2.以下代码执行后,数组$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
4 h* y4 G3 |2 N; A0 J; fB.b  _) G! d# G! B7 Y: G
C.a- I* Q/ y; d! ^/ ~
D.d. g6 w! k0 a* i- y
E.e/ K# J( h6 e$ W, ?; \, o5 j

  W/ N/ `$ F" C$ b! i! C
9 _7 N1 f% J: P- h# V2 y3.如何让类中的某些方法无法在类的外部被访问?  p. A9 j+ e; ~# t5 t+ w

% [; {# A- C8 V' HA.把类声明为private
3 v6 [) @- l8 x& ]7 L# TB.把方法声明为private" s, L4 v) G* Y; M# W- W* a- E7 e' A
C.无法实现
9 g2 `) }6 \$ Z5 |: m) U5 YD.编写合适的重载方法(overloading method)" N. R! k) s" P7 W% |2 c" C  z- s

! H. _  K/ \7 p$ F* K5 r  f( q' h% U6 P$ k4 r: T& z
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?+ m- ?, n7 f: b! {" t
, E/ L; H/ @$ B
A.MVC模式; g$ z& S5 R2 N/ \
B.抽象工厂模式(Abstract factory)( x7 D* {/ R+ A' G" h7 M
C.单件模式(Singleton)
1 d. D* x2 V; T/ x7 n+ AD.代理模式(Proxy). a5 X) j; g: Z: [8 O: |
E.状态模式(State)* R* d3 r7 o8 s+ o3 u' T. z
: Z6 X$ `# ^+ k
( i+ L: d7 P2 i0 _8 ?9 L
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
% X  q$ c; U* V- p% Y5 h7 j( I4 {
9 ?* j; q3 s- J( @4 CA.1个  ?! J% M1 Q* z, m1 |' ~
B.2个
* D/ w* H. p1 K! rC.取决于系统资源0 Z0 O: m' b. ]* W" ]) _
D.3个
5 x$ |7 O3 r$ DE.想要几个有几个
1 K1 ]7 B. |* r* ~* L: g
4 V7 a+ H1 u. q( a8 G+ ~
5 l2 ?  E! @; s3 ]* W9 E) I0 p6.以下脚本近似的表示了一种在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 S  n! b7 Q/ L  L9 v/ ^3 V' ~
B.接口) f4 r; J$ o2 A/ ^) |7 ^5 [3 v/ q
C.抽象方法
; B8 z' r- N0 B8 Q1 X+ I* O: LD.Private方法- ?6 l9 A7 |  q2 K7 ]$ t, G5 c9 ^
E.函数重载(function overloading): S4 J8 z8 y& c1 |. S% z
: x) H, O/ s$ I# r3 Q$ U

2 }4 N: O$ U9 ^7.假设定义了一个testclass类,它的构造函数的函数名是什么?
- U2 ]1 O+ k0 O8 x- A  P) F$ K
6 T! g6 N6 K1 o) k& R/ |A.__construct. @$ l2 D7 w$ ?- e( d0 S7 n# M
B.initialize( B' _  g$ @5 b4 O
C.testclass0 I* e5 V" }/ |5 \4 L+ N
D.__testclass! a8 v) Y- K( r4 F$ W
E.只有PHP5才支持构造函数
9 ]/ \0 y( W% I/ Y1 V( l8 d+ I6 {/ j  y' _& W
2 d4 j# ?, h5 K
8.一个类如何覆盖默认的序列化机制?9 M5 }7 t, m+ {: {; ^0 O
0 x( x, E/ d. o# b
A.使用__shutdown和__startup方法, p, T2 Q; y  k, X* ^5 W) m7 o
B.调用register_shutdown_function()函数
6 A; ^+ \1 A, fC.使用__sleep()和__wakeup()方法0 J& w" _: J& d6 _  _5 R( Z
D.无法覆盖默认序列化机制
, B( N; \; H9 `: y: oE.使用ob_start()将类放入输出缓冲中# u6 z- X3 ^5 w. P
+ @7 i/ ^. y0 U5 ]* Q8 p) w' X1 _

; W, D& G# B2 ^7 @1 a9.以下哪些面向对象的概念无法在PHP4中实现?0 ^; x( s! I% j2 K; l$ c

/ ^9 C) ~" [% l: ~' y1 j@抽象类
3 ?; I* I/ G* I- q, t@Final类
6 I9 G3 a7 K3 x/ c4 T" k@Public、private、protected(PPP)方法3 |, Y# h* {% D6 O3 o" |6 G4 R
@接口9 d; E9 S/ I3 G' q* k) E

( m7 J1 B" X4 `# \1 ^# qA.抽象类
# Y: R: _9 C2 \B.PPP方法
, y3 r9 C+ c$ y2 g' c4 ~/ z' iC.PPP方法和接口
6 D' v7 T2 o* ]# d  eD.以上所有都不可用
9 a9 h9 r$ l$ L, o9 yE.以上所有都可用
1 r2 |/ V: W9 o( L" C2 s& i/ W, U1 V: V& p# R7 w+ c, C0 b

( j: E5 n1 N) g* f$ y10.如何在类的内部调用mymethod方法?
3 R% z" p) b- e( ?+ o! a% H( {' S+ w8 C' t6 D
A.$self=>mymethod();- ~, @) c+ N* o( ^
B.$this->mymethod();
4 w$ `: s9 h6 t& GC.$current->mymethod();; P# s; I( C* t- a$ E
D.$this::mymethod(); x. [3 W  r( M+ q" J+ h8 t
E.以上都不对
4 W6 v. @0 V+ c
9 A  {/ D. w4 q) _& o  z, j$ z% B" O: F
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
  W5 o$ c# H1 @7 N3 N0 DB.Null; b, M; i1 n, c
C.Empty
2 i/ w+ g, C8 C" I. e  SD.什么都没有/ M( f  ~% E$ P7 B/ k1 l
E.一个错误
! Y* [, W5 U+ o$ r. ^1 @) w3 {' \6 p9 \+ y- i7 a- t% q; |/ `
' }' E/ S0 e1 L7 ]$ F
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
* r3 y- Z+ ]4 K4 i2 O1 VB.5* g4 s( b0 ^# @. U8 x
C.23 Q" O  l7 \* W  Z
D.Null
/ b) X+ B% {! {) g5 @. `E.什么都没有0 y* L% B- t. J& b; {

+ r8 j& T, o, p* k% r1 R  |8 d% V
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
9 s+ r/ |. L" e: Q5 ~% QB.100 X0 L1 n( I7 |" L/ F- d9 y' j# j
C.什么都没有+ A& O  `' d& u# G8 F4 }0 V
D.构造函数将报错$ j1 X- ]- k8 t$ g, q/ a1 S4 V
E.510+ y; U: Y$ X9 t  Y1 F6 y! j& P3 a
% |& {& G& l+ A

* t9 r6 N; s1 }. r14.考虑如下一段代码,执行时,$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函数必须返回一个值
  M# z3 I2 E5 m5 wB.reduce_fraction函数必须接受一个整型值
( i: P$ y7 d: E3 V8 \% K" N" dC.gcd函数有问题
+ S4 X' p: R; S( A7 e# D' ND.必须通过引用的方式传递$eight_tenths对象# b. X: [3 Y4 R8 u
E.对象的实例不能传递给方法以外的其他结构。+ e$ @" S1 w, n5 ^9 P, N9 ~) I
2 b: P$ k( z# u+ L! }

. Q) P' H' [8 ^15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
; V5 O, h* M+ W1 @; FB.生成myclass的实例并调用mymethod方法
4 E8 f) H7 l! Y( r, `0 w' [C.产生一个语法错误! }7 J3 ^4 a6 U3 r
D.默认myclass类最后被创建出的实例并调用mymethod()
% A+ Z  P9 e4 A9 f8 `/ N% E/ cE.调用名为myclass::mymethod()的函数3 k8 j( n8 [2 u8 g9 I& Z( t+ |- W

3 O( N- u0 y0 n& u) L! [. \5 D
% [' _! F, G; K4 Q- H9 l16.PHP中有静态类变量吗?: {: g2 _/ |7 d0 ]: z) R
: x2 {9 w0 ~; ?& G5 {0 R7 v# N
A.有
1 l( i% y( l1 ?  G$ N  MB.没有& x. m" K5 w) K# _# h) z  o

! W( y( h% Y2 ~' `- [3 d
3 x7 ?) N+ C) M, }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
1 p1 A0 @1 _0 [, ]  M  x" a, v2 MB.2
, C2 ?% [4 J: Y8 l" I$ X* jC.一个错误,因为没有定义a::$myvar8 p* O4 K1 k) u
D.一个警告,因为没有定义a::$myvar' l$ z1 H3 H' @! H
E.什么都没有
8 X) Q6 G" o! o$ g! w2 Q( b% m' _& N3 D$ U! t5 \( {

' {% S& {( ?: e' m/ y, M18.如何即时加载一个类?
; f0 h( L* r# O& C! \9 P8 I9 h8 h% Q2 f& \- Z
A.使用__autoload魔术函数8 g, [& H- i& s3 s: I8 p
B.把它们定义为forward类' C1 F* U% I& Y- F5 Q9 s' f. w2 f
C.实现一个特殊的错误处理手段
- \" b2 E" B+ v6 D% QD.不可能
( q! h' B2 Z( B4 J9 V$ V- K7 B) _( dE.用有条件限制的include来包含它们+ [; u: ^. r7 G' F

3 c: l" K, y9 |5 c
6 i1 F, R; Y4 N4 q0 B9 v9 S19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?8 u' ?8 r( o( N" t
! M; n# x% V/ Q6 q0 X: p5 i& ?" o
    答案:__________
7 K. {4 m0 D% u! \' J2 c9 o2 x! L
2 \0 s/ Q- f, u& I9 L2 F; z
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
) w- W5 ~& B4 Y( @B.一个错误0 v; A  L* C) ~5 Z( g
C.一个警告3 l& ?. H8 O0 A3 \! ~) E
D.什么都没有
& G# }- i- t$ U* ?$ i9 N/ Q
  T  j4 c/ b! T% @2 `$ j* z: _, B$ p* T" T0 O
! ^6 Y% d2 ?( n, d
答案速查' s2 Y1 m( {, s. t- O
1.类
$ H7 d: ?4 t. |2.BCD4 }7 o; T$ }9 z( V8 m7 P
3.C
7 `$ {  w; y+ {* _+ V4.C
# g) \2 {6 E& Z. `; [( Y6 r  T1 `5.A* N  J0 I9 x/ ?
6.C
2 G+ ^5 n1 g" R" ^5 ]7.C, H( Y( J. U0 D% V- J+ H
8.C1 r; t& F9 ~0 o5 I6 g
9.D
- g7 ]6 _; \/ ]0 G  E2 z  E3 x10.B/ p+ P- _- b1 N0 {- `8 \  Z8 R
11.D
, S1 d1 k  U  J' B1 B, |12.B
  ^3 l6 a7 R( ^3 m  k0 L/ |+ w13.A& s& x/ v; d+ m/ J  p+ h
14.D, w# D# O* j7 w, D
15.A
5 G3 @+ r* e1 a16.B
! X- I! d3 E" s- [3 z0 x" [# k& v% `17.A0 M& k/ T, M; C
18.D+ h6 I  _, f; I# _8 U+ Q" m
19.设计模式# x1 t) ^6 i/ J6 R! ~
20.D1 _6 Q1 `) d7 D3 G; D; `

- O+ Z. \0 _8 O7 m8 C9 `" }1 y. K# Z  e2 J
& s; C0 f( _; z9 v
答案详解+ C0 P8 k1 K: C. ~3 s* a: t
' p/ C  D' V4 C! `
1.类是对象的蓝图(对象是类的实例)。+ [9 V6 Y9 G; w4 t
3 G7 U4 C& @$ L& _5 Y  [
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。5 x% \# a7 J3 d& R7 s

6 }, H4 a0 d, Z3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
, A- |7 ~' R4 q& z) R, b' u0 x! _/ y% q) O0 X& A  y
4.单件模式可以限制一个类被实例化的次数。
7 R3 j, T% h4 q' A+ o0 }
( @" Y6 g* X  D6 J2 w4 h5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。9 s8 H2 Z0 a2 a
8 y( \% h2 g1 q* P/ c) Z/ n* `
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。8 d4 v# N& M* l8 \( P0 J

/ M& ~5 ]) ~, a3 q7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。6 B' h; U6 _2 i+ F2 f, [

2 ^6 ^) A2 r  D1 W. M5 M5 [) ^$ m8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. v/ U- ^) I( x, }. C8 h2 {. p
% T# |0 a1 x* _) {5 t* F$ O- x
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
: R4 t9 ]3 L+ h; x$ U# J
! ?: A; h/ K3 [  }% J& I10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
5 h1 m6 E/ Q( ^) E* G7 |$ Z6 h
6 i4 q0 ?$ i3 ~0 W  ^5 j# Z11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。' _; ^& O+ U* T* Z0 b, |" t; y

3 n6 M0 p3 Z' X2 G12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
* o* d% r/ V2 z: r; K7 j; I2 i! ~/ a' S- G
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。7 H5 \1 k- D3 g2 Y% q
1 i/ ]: X7 ^1 S0 t
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。8 S: I1 @) a% `
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:% T/ w8 u, I+ }3 R" M/ L* N
    function reduce_fraction(&$fraction)
( w9 F, M9 D0 g4 T1 e$ S答案是D。9 E7 h3 K# F8 O. `- h
# P; N: ~  z1 b
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
& Z2 o, ~: X1 W0 O( t/ Z2 e6 l/ E; d4 q) E( c* P; ^
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。' v  R6 F1 h; Y

7 A  K2 I% q, a, U# t7 R9 r0 u! q17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
8 {) I3 n" ^4 V2 \0 E5 T
* |/ n1 w2 V$ a. L4 N+ r18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。4 J- U5 J* {+ [3 S0 |

* y; N! I4 e( d5 z19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
/ R  t& f5 q0 l4 y/ k* N
) N/ G1 G4 t! S' i20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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