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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。! B; H: I8 r4 b
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。4 b$ a3 P0 F% b1 z# t
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。% I; Y0 h1 ^6 D1 X

0 p) R& d6 e5 Z问题
1 f" X! n1 n" `0 y8 d, [+ ]( v: m, `
1.对象的蓝图是什么?$ V2 c+ t; m1 ?1 t
8 U) y  F+ c( ^; g" r0 H0 ?& B5 u
答案:____________
: D/ n. O% E4 E! |
# q: I4 a. V; Z" C0 X. r. w, B1 ^" K% V) y5 @9 F' [. U; }8 {
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) F3 U9 y$ |3 E6 D* Y# f( p$ f
B.b1 ?1 V; o) B# c2 Q
C.a3 X# @' u' ^, P" Z
D.d) g) F) |+ \4 T5 F: [0 E
E.e
8 R. n/ w9 u. q7 C& c4 I( ]7 k; u, _) X5 E$ N7 R3 q! j

7 v9 r' K1 i, o% P# @, o# K8 Y3.如何让类中的某些方法无法在类的外部被访问?
3 z3 E( Y1 ^/ [  @" I3 A+ G- l; T4 p0 N& I0 H# y- L
A.把类声明为private
  y- z- h0 y9 h7 N% Z7 OB.把方法声明为private- S$ I% l5 \3 H; P* E
C.无法实现
1 ~8 P  J  {6 g# MD.编写合适的重载方法(overloading method)5 {8 j; `, _- e4 v* ^( u6 Q; i
5 {  l: x) ?8 j' ~* F
6 j- J) C& k/ i' b, n
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?6 k1 {5 f: u& j# L/ W9 Y, ^

' v4 x8 H9 B: l. u6 hA.MVC模式7 y  P# ^3 e' m9 S, x% v  h9 g
B.抽象工厂模式(Abstract factory)
9 }7 g1 I1 t8 O* u% t2 fC.单件模式(Singleton)
% k: ?4 h% L1 h' I& A0 i: r! XD.代理模式(Proxy)
; U" q' _; `2 H4 E' A& {2 f/ J8 uE.状态模式(State)- a9 y7 g5 e# N+ o

% A1 u0 y5 y) _' S2 ]8 G8 K  ]$ [0 g( \  z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
1 c0 s7 c' K. b* B3 n2 W, S+ m2 ^1 s8 h3 G4 a7 c" D, ?
A.1个
7 Q7 I3 q4 [# L! P/ o) MB.2个
& w' R8 F$ c/ B7 `# F4 sC.取决于系统资源
2 D7 e2 x2 `6 n/ G0 JD.3个
2 w. A9 Z, m0 K. D# M$ T# ]E.想要几个有几个
0 t1 e! O1 L: `! c; t
" _8 m: [, D+ P3 f8 Q/ d- s  M( ?5 Y6 M6 i( Y
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.多重继承
  C9 m/ B2 \8 B9 lB.接口
( K$ Y: i: H5 l6 a$ {* g% \% H9 U. ~C.抽象方法" B  @5 I- p* ]5 Z: W. Z
D.Private方法0 f3 h% S$ F+ ?  _- Z
E.函数重载(function overloading)
( p9 T1 o; Q( T" g: R# }; B& F8 B# a, m6 y- Y( F( V1 y' t

; a4 ~* z% j) t7.假设定义了一个testclass类,它的构造函数的函数名是什么?
, ^2 P3 u$ u2 K& r3 G
! C  k( s3 A7 `A.__construct
; r" B) b! }& `: O0 rB.initialize
/ a" F0 A9 _8 h2 a& h: P8 JC.testclass
1 P; p% X* j- ?' P6 s$ hD.__testclass7 r% X" l# s3 V. n3 B$ b2 z& ~: j- Y
E.只有PHP5才支持构造函数% j7 k. [/ q: w! n3 f! a- c$ H+ r
% c# ^! d% m8 D- N: q2 f
0 x' l9 i* u1 H( E# u5 Y
8.一个类如何覆盖默认的序列化机制?8 O! _5 p& T; m) _  j

( a, }6 S' ~% A: _A.使用__shutdown和__startup方法
9 \$ C8 d7 _! y1 s9 YB.调用register_shutdown_function()函数
: F3 v/ B7 X( x$ v7 gC.使用__sleep()和__wakeup()方法
. t0 j; K$ }/ v) WD.无法覆盖默认序列化机制
- _; j" T1 f$ H" K  d6 ^6 ZE.使用ob_start()将类放入输出缓冲中( H5 {9 Y& \: `6 N
$ ^$ S* m* a7 r7 G
: m7 e% w! ?& a9 P% }9 A6 D" g! f
9.以下哪些面向对象的概念无法在PHP4中实现?
) W2 ?$ L  |2 w/ n/ V3 z1 ?
- W; F( Z5 z' W1 P' q+ O4 T( O; V@抽象类" L; Z/ l& Z* Z8 F' U+ a6 d) Y
@Final类3 R0 ?: L6 I0 _+ A- x2 _$ ]
@Public、private、protected(PPP)方法! q! p4 C. g9 O1 F( j$ B$ `
@接口- {$ v9 n8 q6 S4 y3 {

! y" r0 @# s$ x. ^5 n3 MA.抽象类
9 P* h4 E" n8 Z9 NB.PPP方法9 \: g6 O6 h; I9 _) C  H+ [
C.PPP方法和接口
0 h4 E- l1 Y3 g2 l+ I, RD.以上所有都不可用
/ x, _* ~- j/ ^6 @+ j  A5 q; wE.以上所有都可用3 G1 R6 r+ f4 l8 ~
2 H! d; E6 F  `+ m. ?

9 [& b4 J3 p* h9 x10.如何在类的内部调用mymethod方法?
: A+ e3 e! l' s( U0 Z2 m8 r' z- ?) E+ n$ y
A.$self=>mymethod();  x( O. W3 c1 n- X1 }! S" u
B.$this->mymethod();
# A* j9 q" D% aC.$current->mymethod();
! s, i6 @$ o8 O+ T) ED.$this::mymethod()
! C" A  i1 ]0 a- I  d* i% oE.以上都不对8 R% }5 c& C; W# e2 S, w5 ^/ D
5 W5 f  G; ?6 T( ?+ ^
$ u. U5 f% U8 s& x$ k, ~% a6 Y+ r6 _
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) S! K# c* q3 r, }+ _" Z
B.Null
1 d: f: h  t4 g2 ~* S3 vC.Empty
- O7 p) {1 l- O" E+ ]* UD.什么都没有
2 i1 Z: |  \: v# ]- @5 VE.一个错误
5 X6 V& r: \5 t0 d& u# C, p3 n9 n( v
$ y8 G7 ~. e8 `) U  s7 H
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
2 b; v5 C) M: e" H# Q  oB.5
6 L7 a* s1 }! j' H0 L( L4 `; nC.2$ Y! R# T% j5 i1 u. Z
D.Null
! ~& s" e% k  W8 sE.什么都没有; r  C9 g/ v8 p1 P" D' T

$ l2 b/ }; x: E& K& @
; h9 c4 `- I: Z* @3 `6 j% 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
+ O, J) h% y  H* zB.100 m# i& a  S' f( K& g
C.什么都没有2 `5 r7 B: E+ \
D.构造函数将报错5 p6 s3 i" i* H' J7 u# Z
E.510+ `( Z0 s( `5 w0 v8 q5 p  I- z
, o. `  V# J4 H5 i8 k2 [+ h  ?& c2 z

- ?4 N8 I7 \  g- g% G; w6 j( l14.考虑如下一段代码,执行时,$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函数必须返回一个值; V3 {" x0 d' ]
B.reduce_fraction函数必须接受一个整型值
+ [. g- Z* F1 u" nC.gcd函数有问题
, _+ e  `0 Y' {) C1 Y$ ]4 x8 qD.必须通过引用的方式传递$eight_tenths对象
) d, y6 o  _8 y- LE.对象的实例不能传递给方法以外的其他结构。9 {% ~. n% [# p/ }
2 p" K# A& M4 d" K
0 v, A7 W! w- T4 K2 R. Z4 j; W  c
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
' Z% V# ^: H- R* k, [& X+ `B.生成myclass的实例并调用mymethod方法
% x" y% P. s' ~+ cC.产生一个语法错误( X  T, c+ A3 q1 n' }$ u9 D
D.默认myclass类最后被创建出的实例并调用mymethod()
5 E- q5 m  c- f0 ?$ L2 f; @E.调用名为myclass::mymethod()的函数/ I9 t$ G2 T9 O( k* ~2 w
( B" H+ p. u5 s( ?$ u3 ]

2 B, _: Q  m& p5 g$ J16.PHP中有静态类变量吗?! a' z# o) ]6 S
. x( Q3 n. p8 I+ s% h
A.有
! E" T" @) |$ A& @$ c4 EB.没有
: x" R3 [! k% d2 N; t
; `2 q$ a5 {$ n5 \
: y, |) Z* m! O! {, }& X17.以下脚本输出什么?

  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- F* R3 R4 r# m6 R
B.28 P' y3 v# C1 K+ C
C.一个错误,因为没有定义a::$myvar" C% k" `1 k$ _' X& H1 d
D.一个警告,因为没有定义a::$myvar" p) p; Z5 B% W9 W
E.什么都没有% r1 W: N; O# h) e- C5 x( n
1 O  Z1 [& O* T- f) L

3 n- y' e% f6 f2 a: `# d18.如何即时加载一个类?" C3 J( H2 x9 W# R- U: Y0 m

$ R) j) s, s- q. F6 vA.使用__autoload魔术函数
: d7 G! }) M# [$ G! wB.把它们定义为forward类! E0 y! S$ v1 }! H! l
C.实现一个特殊的错误处理手段
# C( q7 e' X* c  ^( |D.不可能
9 X" R$ l: p  d4 I/ r6 F1 oE.用有条件限制的include来包含它们
' l7 M% I, z# [9 S; ~" {  e/ ~4 @

" i& A. y: ?+ q' R7 ~19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 D' b! m, S! [! W
* m. E' x: S8 h3 ?3 q! |    答案:__________
, |: `% I- R& |5 J1 c$ j5 N9 c, ?7 I- t7 X! w
4 [  o, w( x! J) h7 Z' p/ y
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- Y2 v2 R4 v: }& [
B.一个错误0 v! q4 ?: V7 d) R) j
C.一个警告$ P6 b% {1 X8 G: a
D.什么都没有( Y/ L$ K& w& H# v7 M$ M

) |) b1 t- X. q/ T/ C+ @  W; c/ `6 v2 T6 n0 u
9 N- |. E  p/ l8 G; h- t
答案速查
1 S. P* g) `+ ]' F- Z- a1.类+ p. h& h4 k$ Z4 t5 d9 r4 V
2.BCD2 U/ |( {, `; Y- h8 z
3.C6 j: d3 X0 Z& B  F9 g" o! T7 y, _
4.C& |4 @; t1 K7 w' M3 Z/ p9 v1 o
5.A. f" U' x7 o  K, b6 s1 r1 v
6.C) k) f: {1 }* _( P4 R# {
7.C
1 }0 ?1 r( ^( z; V" e8.C9 d( u/ r; w0 j: [! \
9.D0 o6 K% ~! Y3 O8 |, K. V" b
10.B! _+ f. |3 [  U( b3 v0 H4 a
11.D
8 _, @5 U+ R! c& S; Y12.B
# g/ K0 i3 l& U* l: s- P2 a6 ]+ L13.A
2 J  C, w1 M* K1 K8 [14.D  x# l* v! `6 g) H" }- s6 F
15.A
9 s8 V5 y" O3 P1 X8 K1 I16.B
4 {* v2 l# N1 Q' U% W* C17.A+ p% D: W# t$ S% ]  _' @! o. U
18.D
5 b8 p9 a/ ^4 E( h% T19.设计模式
7 [/ W/ @" Z% F5 d: s20.D
5 I# Z: a+ m- k3 j+ [. A3 e6 y8 h) h9 m' j* a1 j
6 L1 Y3 W8 n: ^1 Q  \5 x
! _8 W* N* @9 [2 j
答案详解: W. z& [2 M- _8 ]4 \% I7 r" L  M
! p) t& F) g# k: b4 `
1.类是对象的蓝图(对象是类的实例)。- e0 U9 v0 R1 T! r8 Y
3 P( G( [: G. ?1 ^
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。5 r( i" y0 M% y1 f

- V# w; v2 N! a3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。: W( h. S6 f7 w1 F' x4 q
5 ~# @5 B  v8 ~6 T
4.单件模式可以限制一个类被实例化的次数。
' b4 s* g5 h  ?1 H3 j5 _* t- F, |2 j- S) v; i! X
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。" r; x6 y, F3 s7 L

1 A/ @( B7 ?! f. O0 t6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
" [1 m5 W! O9 C! F: e7 ^
. `4 K/ }! L# i  _: i/ x7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
- v) V; U+ P: H% w2 P9 h( P# i2 c+ ^! y% ~( f
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
; R' V+ C* }  U: h+ {# Q  x: Q
4 [4 g9 D0 ]! |3 u4 i! W) ]; W9.PHP4中没有题目选项里所列的任何一个概念。答案是D。/ m) {' {0 J1 r. R: C5 e  L

/ M9 V3 e- d0 }10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
7 g4 W2 ~% W$ B. X! P- `8 _
! `( g0 V( O' R0 X0 X. D. ~. @11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。% d" `" Q, I& A- l. F$ z6 ?! V) d" n

; L$ N2 R  U6 Z. d  I12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
+ p( C  w7 D8 ^3 R' \* W) ^0 q6 G; {! G' P) p8 o
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
5 P; A( g6 L; {5 o" Z3 D4 B  V' ~2 r  a
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。7 t  |7 a0 }0 W$ i
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
7 H; _; J; n$ p1 ?) ~    function reduce_fraction(&$fraction)
7 Y  k. ^: |( N# V( v答案是D。3 }  S) I0 b3 H, T

2 D) ~' F, }3 e$ {15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 n0 e& D6 ~0 [8 Y  F& U2 f- h; t9 q6 g( J+ V5 ?0 j- ^- }* ^
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
) o7 a0 J$ ?9 h) n# `+ w9 S- X& \4 K. {
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
4 ~2 ]* B' n1 |9 p" }8 Y% r
- e; u2 B. Q# u9 `0 S7 Q4 w18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。8 d* _6 H2 R! D/ Q

, }( r/ o" Y$ S0 t" L' j( m; m19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。, P; j' |0 W$ U. x; G: c
7 H# o. Q) e4 ?- ]9 }% b
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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