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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
5 O9 S9 [, R& h% C! B( @PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。0 y$ T& v+ T4 e& N1 A2 G! Z+ A
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。4 q( i! u: O) Q8 T
  {) j0 [% Y3 o4 t9 d- q
问题( T( n" Q9 D( W- ~  U; b/ n6 K

# M) ^, J! K3 p1.对象的蓝图是什么?
' y8 U' K3 K' P
4 ^6 N) |% I+ i+ b" Q答案:____________
# \! I' u: t6 B. h, c' P" G' g) C, y5 R

  G' u9 b5 Q. E3 L3 y2.以下代码执行后,数组$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
0 ~5 ^! N5 }/ H( _! u6 j/ j$ ?B.b$ y8 ~* s9 k, c6 _, A
C.a6 z, [" \" c0 X
D.d8 `' c/ V- R: T) S7 T9 d- x
E.e
: o- R1 n6 j- @% Y- K; {& @, g; ]
6 ^3 E- v/ r) g) k3 ^% T5 L: t$ h
) c# ?% ~9 z. w% g% ]3.如何让类中的某些方法无法在类的外部被访问?9 s! R  s) K8 X3 d' z
$ s4 S3 l  }+ \* q; y2 O
A.把类声明为private% N: F8 R% B1 L) a
B.把方法声明为private
4 |( W1 N7 l/ M/ P0 a+ z6 U  t# PC.无法实现
* |' Z3 Q0 c6 O, Z- DD.编写合适的重载方法(overloading method)
3 Q9 j0 n2 i% `$ Q, \. l& o8 l3 E( Q0 y4 `/ A# D, B
9 z& b& \5 H5 T8 L+ t
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?6 T- ?; x, Y( j0 q! W9 t. v6 o
$ \, D. @) ]+ {
A.MVC模式- T- s! X0 Z, t
B.抽象工厂模式(Abstract factory)
4 u* e4 K8 w0 |& [+ Y3 sC.单件模式(Singleton)
8 F7 Z% |! t. u0 K) D/ l4 RD.代理模式(Proxy)) ~, Q+ T' F2 B& k3 {$ H  B
E.状态模式(State)% P6 R- x$ d! I6 p; ~. R0 k
( b) x) c+ h+ L3 G4 \/ j% c) l
/ {  r' v* b; N) e
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?; l$ Y* K2 A" m' J# g
: c+ ~7 R4 U' [% @
A.1个
( N0 m% e( l' H) H  FB.2个
- o8 T, ]+ ]/ k- I/ sC.取决于系统资源* y5 k% N7 T6 j9 T# z  v! B, w  y, {2 s
D.3个
) {3 U3 o& y! k' qE.想要几个有几个2 |8 _# j# Q0 l9 Z0 l4 ~1 X3 z6 W" N4 f

8 D: H- B+ _4 K2 b
. S7 _) h3 C0 y: ?+ k% }4 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.多重继承3 O" I& L6 W2 q: `* f# i- V$ N
B.接口
+ ~- g5 V! t* dC.抽象方法6 I& w1 o. p& ]7 w. C. r9 r) C8 S
D.Private方法
0 ]* Y1 c2 h' i% FE.函数重载(function overloading)( ~6 n0 W! Z: i1 `, T9 P4 a
) W& x$ X  K; Q- v$ I, c8 Z) @, s

% [* G# g. D7 y6 O4 u7.假设定义了一个testclass类,它的构造函数的函数名是什么?' S% m/ W5 p  E: L9 |
% N) A+ c% t& C7 j! M% _" i& H
A.__construct) z8 k/ S6 B/ |1 z  U3 w0 D
B.initialize
- D' I& g1 f. `$ b7 M) M. |C.testclass
5 f" `8 P) }# FD.__testclass% S! Q2 l; T9 j9 L
E.只有PHP5才支持构造函数" w3 B2 _+ p& Y3 T; V# Q

, C+ h" d7 J) e! B3 G$ n# s$ |9 Q% {7 h/ @6 {
8.一个类如何覆盖默认的序列化机制?- Q: q$ Z* `: D% m( X2 m

+ ?* u0 M8 f% z% Y. LA.使用__shutdown和__startup方法
; ^' q. `8 M( x- N$ BB.调用register_shutdown_function()函数
+ A9 w+ \' o9 b7 eC.使用__sleep()和__wakeup()方法
) H. L: M* I+ w* @2 l5 T8 r( C# W( BD.无法覆盖默认序列化机制* T  q5 f) m6 @
E.使用ob_start()将类放入输出缓冲中
& n% V" d% A$ h) K' n* N+ A/ ?8 p: u9 b. q

7 j. w; ^- @. T8 x9 [7 f( v% A9.以下哪些面向对象的概念无法在PHP4中实现?+ L" e* S! a+ ]6 K: a/ G
( P) G) A7 b! _2 a2 p4 N
@抽象类  K# h7 ]1 L" A; W
@Final类
! u- L9 W) H. W" o  @@Public、private、protected(PPP)方法
: m0 ^8 `0 A. x@接口
* L+ E6 O9 ?7 }5 U8 J) w3 h/ b
+ m9 Y' E; W$ N0 h& {) M% zA.抽象类
( X7 u% _( o0 i9 V) y! T; N9 SB.PPP方法
3 A% W  L9 Y% Y3 d$ `, J" SC.PPP方法和接口
* R' S+ w! W: M5 nD.以上所有都不可用
6 v+ U+ p7 A0 Z! M) vE.以上所有都可用9 t6 J, N  R0 X1 k
2 j4 d9 ~2 P3 o1 F. o* c" |2 L
  i( c/ {' |! }2 Y* X4 _2 ~6 v' K' Z
10.如何在类的内部调用mymethod方法?6 o: X" i( i1 g$ b) _

* T+ Y, k/ @2 Q# `8 ?A.$self=>mymethod();
* N$ M( [; x+ O- dB.$this->mymethod();3 a6 `8 g7 a5 `: |" j$ f- B
C.$current->mymethod();8 S" T2 ?- _5 o) A8 W
D.$this::mymethod()
% R3 X1 h) c6 X& \4 f" q* rE.以上都不对; x! h9 i! v4 o( P3 A. U, }
/ P# h4 l( p4 i1 W6 `* ^5 \
4 W- Q5 G' ?7 e' ?2 A2 ^3 j) b
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 G4 U; u$ V; s& {
B.Null
. X4 `( p+ Y) W2 ^, z  i- \" t) m4 @- ]C.Empty+ l5 H& C. f/ S; v
D.什么都没有
$ [6 z: W+ u7 A7 x# b1 N3 r; E; NE.一个错误
: Q% M# P& z0 c: Y1 ^3 c0 o
$ A  U3 f4 f$ z( _( k! K# g5 M' p; j7 n) i; C7 V* W: z
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! O$ i8 C/ t" \
B.51 O4 o' X2 e3 Q
C.26 U# b/ E1 q/ m, p8 i5 `+ V
D.Null
/ |; j+ p  P( _% `E.什么都没有
, Q3 c$ R- q( S# V+ p$ d; D7 P7 d" Q% I+ B" b! [

! V/ R: P" d) @+ y3 L7 ~7 g13.以下脚本输出什么?

  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- M# L  D" u, g  P& [/ ?
B.10# n& t) y$ ?% B1 q; r! ]2 B
C.什么都没有
& y8 }5 d3 s9 b" F  P/ l4 y. SD.构造函数将报错
+ v1 U3 S: W: u/ z4 r; |8 @E.5108 k( w9 ^4 y  u' Y
* O+ j/ v" q3 c+ A5 ]. ]
( l1 W$ t4 U. H2 X1 }
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函数必须返回一个值/ Z3 N' {- ~5 {) [6 E
B.reduce_fraction函数必须接受一个整型值* w( z7 U) a: v9 _
C.gcd函数有问题7 H7 N7 S7 }: G
D.必须通过引用的方式传递$eight_tenths对象  `2 Y% e: {9 l
E.对象的实例不能传递给方法以外的其他结构。# X% B% T3 O5 R' n$ s

4 f* `% ^: T1 K) y$ s1 n, Q! p! f# [
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
, t. J$ A8 k. f. ~B.生成myclass的实例并调用mymethod方法
8 b1 g! p5 J2 s# I$ @% yC.产生一个语法错误
  F. @* V3 ]8 N5 C6 eD.默认myclass类最后被创建出的实例并调用mymethod()' V" [& l+ S* ?  {* J
E.调用名为myclass::mymethod()的函数  f; {5 H' W) o7 H! ]5 X8 ~! o3 r

$ n0 {) g0 _4 U/ A: ~( W4 n
" a" R5 v+ I6 r& ]1 n16.PHP中有静态类变量吗?: y; |% }8 e' M5 X; f$ _- J

' b5 Z% |4 s8 @" S, K3 CA.有
& f$ o# O6 K0 W. L+ hB.没有
. g4 X" T/ s: y: \7 R
3 d' P4 D) p1 P, x  R# N* j6 ]2 s) K/ H) p2 G0 i* [) X* f
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( u  K5 y" c& h+ L$ F; E
B.2; z6 W* _4 e* ?
C.一个错误,因为没有定义a::$myvar  @0 p- I, s8 C9 r' {& c% d! O
D.一个警告,因为没有定义a::$myvar# R( s% U/ `9 F. Q
E.什么都没有
4 f: p6 R' e$ m: m/ s3 |$ x
& H  m/ M" |5 F1 A0 n; t1 O. E# n8 m& v
18.如何即时加载一个类?
4 R* J4 B% i: A  O! l- t/ b- x0 C7 Q9 `% N4 I* {
A.使用__autoload魔术函数
: h, u1 q7 J! b0 SB.把它们定义为forward类  w% o, b# ?' @2 Z5 L) V
C.实现一个特殊的错误处理手段: n  W- h' U8 I7 A0 O
D.不可能
% h4 @3 m. y' b- Y% ]' T( LE.用有条件限制的include来包含它们
6 t" V' Y% }  y; B: b% T
- E  @  v. \0 F( O2 J% {0 g& Q
, r' |; e/ G6 b) [1 z: Z19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
$ O% E# c* d7 k9 T- H
& m" w0 y4 Z- D: s$ a9 f) V    答案:__________
9 s9 R% P3 \% g& ~: W# k
& ]6 J/ k& a% B1 x) ]6 Z; o* \* T
! D: N; _5 F# N! O9 P& q20.以下脚本输出什么?

  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
& ]% x) a+ a' uB.一个错误
7 a# w' N2 s# J4 \  P. cC.一个警告2 _  ^( ?# f7 M
D.什么都没有- h- k) M6 |" {1 \
% H3 Q) Z& }- l
- V0 d, ]- {- K* P
, u# y% v9 ~( }1 w9 ?7 m
答案速查7 c+ L6 k2 K) e( [6 H3 Q
1.类
' L1 N3 q3 W; _8 v$ W8 d  {' j9 @2.BCD
* \& K4 z0 [. J! S3.C3 v; `" r( ^' U) W. H4 t
4.C  R, ]* W) t4 d1 F
5.A
, a/ b7 e+ X1 c$ C$ ~7 W; D0 L6.C1 C1 d7 Q( J0 ?; }1 O6 w1 N8 E
7.C( W5 b% U& P+ y; E5 ~
8.C
+ A$ x% W/ V/ W; n3 Q5 O9 G9.D3 g$ h7 G# f" Q
10.B$ ?' v( J% b( S* c8 F3 _3 K
11.D
5 B& u& H, u6 W4 G$ W# }' d! Z6 z2 Y: f: a12.B
  v! R* _/ E1 t0 c& O13.A: Y! r5 T/ _3 ~
14.D, M# a( b( T0 n7 Y* }) D
15.A
2 X/ k/ K' K) `16.B$ _: X0 h2 D" r( ^/ U7 K; h6 |
17.A
& T* g' a% s. m$ @18.D$ A( H. u: [- U  [
19.设计模式! E% h, t& f; U- s+ o
20.D
  F, K% R( }+ ?  f% P& ~
  j5 ^& K' N! f
4 @/ n/ o- p5 e+ h' T. S' H* ~, h: q6 z( |: ^
答案详解% t: M  l1 E1 Y( A4 }4 w9 ^7 z
1 R8 \% j, x% m! X$ b2 i/ V* N; J3 N
1.类是对象的蓝图(对象是类的实例)。
/ i; ?) C' X& T* H! b
2 D' G4 R' o5 c% e, G) n, Y2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
/ {1 M; n, p2 O+ |" @
% y* V# u1 H5 H2 U  X7 m# [3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。0 w2 y8 D4 _) O$ R8 M
5 E7 M  Q8 y; n3 I
4.单件模式可以限制一个类被实例化的次数。- B$ `1 }1 j. L" K9 h0 V+ D

! s" L' x9 G5 e5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。8 ?8 c# t$ x+ v) N' t& g& Z: V
% a; ]9 w* N+ R# i0 p" ~3 ]4 q
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
$ J5 q3 ?0 }4 C. t! L5 e) d: s3 H: s/ ~! `7 U" H! u( Z+ E
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。# S) Y3 D0 e6 B1 j" U4 B
5 O, R& m* w; q8 }1 u4 c6 O; T
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. j; R$ x2 f2 [8 z2 ~% ]. q
0 P! T$ Q: {! B
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
( q, a# F6 E. T3 D" s( ~: I
. @% R9 K, H0 l" A7 K1 W10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
* E2 t$ T! x& ^) Y; s4 S# s4 o$ H" Y( C, o2 ?6 f6 X/ X
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。. w8 ]8 g% q, ~6 Q
. ^/ ?6 m" v4 G2 ?  c: H
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。) c; l* A1 n9 z4 g
+ ]# y% O0 P  s7 U( {
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
# X$ D! f& m5 I8 D4 o* V' w( }+ i" a: f# i: I
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
& M( A- \$ @3 `. w7 g. r回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:% l1 G1 v0 ~3 g6 f. [5 Y* m' |6 g
    function reduce_fraction(&$fraction)
6 ]7 V. H0 h% ?% i; |5 b. z; s0 I答案是D。
( h4 D# {, d4 P8 {- S& Q4 G3 }, ~5 q, b
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
; s' N' Y2 s, U5 w# J" O: z8 w9 f2 H' q% [4 @  L$ ?( j, ~' g/ w% D: D
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
# y5 P/ [( L' i. J4 I, p: _, o# u7 Y& ~* L0 T( E2 G; z5 ~
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
+ }1 y# d% B" {
' W, z6 W6 I" `; m4 Y18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
! x; \: {# i# O: w1 ^4 z5 b! u" P5 I5 q! j* c$ j3 _
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
# x8 _! o5 k- K( ?: u
. w  t! A: B# N: @$ j20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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