返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
1 k7 O# ?5 F3 B& Z8 O& Z$ {3 L" \0 QPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。- w/ _1 k' G. }, l9 g
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
$ h% a% [5 D9 X% j3 V( M0 V' K1 c) R7 ]" V7 P/ _& a. g$ R7 A! |) r
问题$ j* d0 E4 o* J/ e  i& T

+ @! J, `/ R, k/ r; L1.对象的蓝图是什么?
3 [1 W( f8 j! H1 @3 ~" v- N- S1 P+ N" |. I1 Q  T2 I2 ]- C
答案:____________3 c& Y6 v6 b$ A  j$ I; t
) S; o- ?8 v8 o1 L4 s! n
( m6 b% `! Z% @6 |9 V7 o
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
& [9 o0 }4 A  ?, O' qB.b% n) {3 n8 J/ r$ V( j" B+ |8 ]
C.a
! O6 [9 S3 P2 G! t& t. q& kD.d* G/ g$ V  W5 x; }( e' A
E.e
* u2 z' l$ V3 O. u( k8 G* [  C1 t: w- t: q

% v; f) x' P$ |3 e" C  L9 S/ G3.如何让类中的某些方法无法在类的外部被访问?0 o, \5 }3 n/ p  G: g3 _1 [

' v3 `9 D: O( e  ~1 X' \! @A.把类声明为private4 Y9 O2 C- l& z" j
B.把方法声明为private
1 M2 O( W& W$ P! iC.无法实现
# g% i/ j0 d' pD.编写合适的重载方法(overloading method)
5 E' Y( Q( X) s8 {' c( z: o
6 @! a9 G, h* t* x  j0 {6 l) G$ x$ Y  m1 x
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?  S$ h. M# Z  W6 n; D

2 Z. A6 c$ o# kA.MVC模式; y# q# @7 `8 h5 y. A$ |
B.抽象工厂模式(Abstract factory); W4 A, J3 B6 X0 `9 b4 D# P9 u) H$ j
C.单件模式(Singleton)
2 ^; G1 }! L9 B1 ND.代理模式(Proxy)+ C* z- h" \; l/ g
E.状态模式(State)+ L4 e+ p  G! i' a# H, ]; |8 r
& W$ x8 X$ F: a% Z0 b6 A
$ ?8 p* i; m' U! ?  ^
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?' G3 s% g! T8 |& w$ i& Q0 r
/ t" _' A* N* A
A.1个( c& L, `' C1 U* ~6 l
B.2个
6 [3 ~0 |; b$ a  f/ i2 c0 o0 dC.取决于系统资源
4 B! Q6 H8 X. l: [. _. Z% nD.3个. h* K& O, J7 y" w* [" I% F
E.想要几个有几个
/ z3 g4 P3 M! |
( @$ y: A% A' x" p" y, |
5 W# G# R" T6 k8 o$ K6.以下脚本近似的表示了一种在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.多重继承8 w8 s: Z2 ~. {) ]7 b8 w
B.接口% }, Y! X; g, G8 A
C.抽象方法4 P- Y- p7 x: e6 L
D.Private方法
" b6 A5 \" o' Y' o  HE.函数重载(function overloading)$ B. }5 ?' @+ A4 z6 L7 L8 Z1 e

. s. J4 j- f5 [& w- i9 P; n+ _  R  R7 c& z  Z) F
7.假设定义了一个testclass类,它的构造函数的函数名是什么?  H5 }6 P7 ]  E2 a5 _. ?9 g. U
! i' D9 n4 O8 i( B9 v
A.__construct
$ t7 ~3 s# j6 q* `. cB.initialize$ u5 d/ E2 Q( d" N: f
C.testclass' O; I4 n: h5 C" q
D.__testclass
. O- d6 }" _/ ^E.只有PHP5才支持构造函数: a( G) ]- }- x2 w

9 c# q% u$ E$ b
# W+ Q- b- W, k! q8.一个类如何覆盖默认的序列化机制?% N* l" V3 n9 g/ S/ S# m

  `1 \% Q4 g& u. N6 H+ ^A.使用__shutdown和__startup方法( ~6 a" V' K& \
B.调用register_shutdown_function()函数4 ]& }: v2 {# Z6 _: J$ g, T3 N
C.使用__sleep()和__wakeup()方法) C/ s0 Y8 ^, a. e
D.无法覆盖默认序列化机制' Q  Y- q4 @. L6 J# |4 @# j: _; z
E.使用ob_start()将类放入输出缓冲中
, K# g5 Y+ [( H/ q" d- }  C* X5 g) f+ n  |
2 E. {% Y& a/ x# B
9.以下哪些面向对象的概念无法在PHP4中实现?# f' D! a) {' Y# @
. t8 [3 P. O8 L. P
@抽象类
1 }' b0 ?! `8 {% w" |. d! A( p@Final类
6 U' H4 I9 t" r/ I. N$ L@Public、private、protected(PPP)方法
, V7 b* A( J5 U+ y, M; J/ s@接口9 S$ q/ r  G; b8 }: L

% S9 u7 u+ D) s/ H2 E+ f2 N1 pA.抽象类  n+ Q0 O" H! [# ^) C4 |' E1 C
B.PPP方法
  k" J6 K, t8 S' R0 mC.PPP方法和接口9 d4 A: H% _9 Z* Q( q1 b0 J, h
D.以上所有都不可用
$ t5 ?  r/ P# hE.以上所有都可用! Y: |: T/ [& ?% x* `) L

! Q: A( P  R9 o
: i, k) [# b. f; |" L10.如何在类的内部调用mymethod方法?
/ S, y% u* ]0 N2 e" L" h# T" @
8 f( ~, h' @) h2 QA.$self=>mymethod();
$ g; x# J- u6 \: M/ X! g9 EB.$this->mymethod();
4 ~* k) s8 `0 ?2 A$ ?C.$current->mymethod();
( O8 _5 f! N& BD.$this::mymethod()
. h& x) b$ h2 |+ J  d+ LE.以上都不对$ q* Q9 _: ~5 n* c) g) B
/ g2 Z9 c0 F  D( C7 O* b
0 W5 H' |5 }; C
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% o( X9 H3 ~. Q! I
B.Null
. N$ \2 u1 l( @C.Empty
3 V: y% P* g  ~& Q& Q* fD.什么都没有! z5 b5 f+ V2 S, D% q; d
E.一个错误
7 C  ?* E" C) n6 {  J# K1 A0 g! f! |
6 K8 W, e4 X- ?( B+ ]  b; N
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" T0 P& k, S+ U, z
B.5
4 r* _  g; e- a0 ^/ ?/ e  MC.23 C& {! L& z! Z; o  W5 G
D.Null
4 a4 U5 x9 J  yE.什么都没有9 K8 F# P! |5 q

3 m' Q8 y: [& c# S, S' j- |: G$ p% l3 `. }  m
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.51 Z* ]% W7 K& j0 L6 H1 Q7 L! |$ c- z
B.10
6 R7 S; [6 F* P& B3 NC.什么都没有# g6 l$ K. D) c+ J' C) v$ w
D.构造函数将报错
# {6 }! r2 l4 W& J; z* DE.510" r. z9 n) }2 ]" y) n

7 M( r1 i- W& {. G2 C
1 G1 X5 n1 @0 O  ]; t3 m6 U* a! z14.考虑如下一段代码,执行时,$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函数必须返回一个值* C% I- T8 R. }
B.reduce_fraction函数必须接受一个整型值0 ~4 d! V9 ]( l1 Y, G" x" R
C.gcd函数有问题1 @+ R. h6 O1 X' d% x+ R/ I3 \; I# }
D.必须通过引用的方式传递$eight_tenths对象, c6 X- C; _( P5 W9 j
E.对象的实例不能传递给方法以外的其他结构。/ m( n! I2 {* G, ?" C
1 g& [* U4 g( i- D; \5 i  H) I

' B$ G3 g8 n, H: @- [9 V' c6 V2 X% v15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
; Z: E+ L$ Q* r0 n# l6 Q" h9 kB.生成myclass的实例并调用mymethod方法& d0 c" ]' w9 C/ b* b3 R$ N! N0 Y. ]
C.产生一个语法错误
; s2 k5 m4 @% [# BD.默认myclass类最后被创建出的实例并调用mymethod()! n! _# M6 K+ D9 j
E.调用名为myclass::mymethod()的函数- `/ k! t3 d0 |# P5 p* q

' {+ h8 N6 G1 M5 i
# u0 m3 V* R2 O& q6 z  a1 N16.PHP中有静态类变量吗?( A. u! U5 \- P" `0 N

* I( {3 y' b7 F2 E- U1 P6 E6 xA.有
6 B6 r6 y4 T- m7 vB.没有
3 d$ F# p" B' @/ ]% z  k
* K: u) l3 l) i- C4 R* p$ }9 X
) W- A- z- J9 O+ p4 @- c17.以下脚本输出什么?

  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
6 Y- Y9 O& g( X/ s  z+ R. S) rB.2" J1 h( ?9 X( k+ }5 b
C.一个错误,因为没有定义a::$myvar
( C3 Z" Q; ~9 t; A# DD.一个警告,因为没有定义a::$myvar
; i* M1 ]/ h' ~3 a2 U0 `0 L4 k( j2 }E.什么都没有! ]/ P* c; V8 N4 a2 V+ F

/ T6 q0 O) d" B4 w0 D4 u0 ~/ U4 l9 f5 }6 w) U# u2 {
18.如何即时加载一个类?
! [: h( u( t. D* J/ s: D; O. t2 @1 _8 Z' [+ ~; N) b5 }  |! h
A.使用__autoload魔术函数# N' z$ X0 R: {" f' f, e- B9 i
B.把它们定义为forward类. }4 @  {0 r; C; M2 B, q) S; n
C.实现一个特殊的错误处理手段
$ u# ]; n$ q8 U$ A. [D.不可能
1 D+ L- t3 E$ e9 v6 e0 }E.用有条件限制的include来包含它们" b' {8 }+ O. M% p, r; L" O

/ j# t0 x% {" C, C6 q( t% Z3 M; p
# {$ P# q4 }' {19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
- {0 G2 G) d& [: M( _
) C, G. {- `8 Q8 Q+ ]    答案:__________
  X9 X' c2 f: z: A" ?6 k* s( G  L4 j0 ^- I
/ q, f" ]! w* g2 w% j: `
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 called0 ^+ Z+ R7 V( z7 j. J
B.一个错误
- |, I; U# r' x0 L% i2 w, \C.一个警告
7 i) r& H7 J, B, {( z# z: k+ FD.什么都没有# O; I& a' t4 v, ?) r' |( G& }
  Q5 g4 A5 S8 Z) O/ ^* }

; {- z# T2 i' ^" A% ?0 L* r
0 u& `3 d0 i# M4 w3 x答案速查% N1 z. ^: M. _! ]
1.类4 z7 @. J+ M& b* _8 N
2.BCD: C6 Y" d6 _0 i
3.C1 C0 m% |- N/ f7 {0 H! S. A
4.C; n7 i* R  H6 r0 n7 ]% G( a4 x
5.A, p' e4 ?; d8 R& e# }
6.C  U2 }; n0 V/ |
7.C
. g; L+ c6 K1 ]' \5 o8.C7 _0 K1 A# ^0 V
9.D8 F; {# `; P4 D8 \4 ^
10.B
! {. j* t: k1 R" }6 y7 ^& h11.D; g1 D# V% c! |2 _6 H9 l1 ^6 d
12.B' s  v( ?- _" h. ^% D
13.A
/ F& G; v: K9 m% {2 \3 d14.D; ?, _" R$ ^" X* w" ^2 |
15.A! U0 c, H2 U( ^" |1 x' B4 `
16.B4 F2 E$ t: t) X, A* o4 P6 L
17.A- [9 w6 t" p" X
18.D
7 ?! H! }. z$ l+ t) Q) z* x19.设计模式- V. x. k+ T8 P+ k
20.D
! |( M' y! N+ ]( S: p  j& R0 L8 |8 X# ]* u; z) z7 Q
2 m, n$ Y4 ]3 L! h

  F% E* j' }. q: B答案详解
8 B( ?& m( i" z1 ~- {5 \; w- H: \1 F* R
1.类是对象的蓝图(对象是类的实例)。
  V' O* }% z' _" m  O: d4 m- A& x
- w* _0 _$ ?" M# T& m' F9 `2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。/ i5 B; `0 t/ G' u0 O0 [- ~
6 a0 B$ P+ A" Y4 q& u) B3 R4 i1 z
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。2 i" f+ }: d8 S6 e- f0 X7 X
& a7 w# O+ r8 O  u/ R
4.单件模式可以限制一个类被实例化的次数。" f: R0 }9 M( m; a2 ~1 M, o

5 q7 q7 D) q) F4 q5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。7 ~9 F* M5 O1 i

5 w) Z$ y, L  e, X3 U5 T- Z5 a6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。) Q, d$ m' z& l( g* S

! _* m6 K) `& u: E  E7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。" e# J& x2 a( g5 q4 E
4 U2 b% y3 O! I! d: U
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。8 J! a& b5 Y+ B$ K
+ H% b0 A4 _* Z6 j/ c
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。1 g: G8 H" H4 M( Z6 H# t

# o8 O6 D/ |$ P' ^. F10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
" g2 G- H9 O! ~* {) e- L
  f. k  |$ k5 J11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。5 H# ~* {& r: Y; }" n4 f, i
1 ?+ U: A7 x& Y  U; F
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
' W- `3 w5 q0 S+ e: \& A3 D& k0 o6 J
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。) M: W( N* g) O9 O8 P  t7 [8 W

5 `/ Y" q5 b  Y3 o14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
% N; @! {: P4 t0 Y回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:0 |/ Y/ V$ o. F; n5 p. O2 S3 p$ e
    function reduce_fraction(&$fraction)
/ J; O5 _. f+ k( Y答案是D。
, D7 s% p9 O$ R6 x
2 ?% r5 h6 a1 p0 D7 M15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。7 |1 A' p1 a! ]; l: M
, D, ], v4 o/ _2 D( m
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。  J$ [) h4 q' a* S- K
2 V6 L) b5 m1 \* i: @2 @9 A( y
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。% O$ c) |3 b2 X7 T6 Y9 N; M

5 S, |5 l# L2 @$ E2 r18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
, d3 E0 M7 [0 l- N# b& a9 ^9 W7 {/ d6 e( B) V3 c, Y
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。) M# r, c+ N3 o
: A9 h' @( o9 Q. R5 e
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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