返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
, ]' ~2 X* M4 g  d9 a/ a1 K7 MPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
  K$ ]$ k; o/ z7 `: C+ y, x本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
' o9 D& |  h& x, V- O+ V
' U  y( C% X* b% |% u* h* x问题% N. A; ^- d  S* O. @% Z

& a' `9 l( ^8 T% g/ e* U$ c1.对象的蓝图是什么?
9 I& e( k4 {/ V) J" a
( k$ G7 S5 y8 m* {答案:____________
/ m  O. K. y/ G" c, u7 |/ l. ]! e: M
) j& w* l* e1 U9 s- p, r- e
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 ~, _5 J: OB.b1 k' i; Q4 u6 k/ i: I
C.a  N. y6 Y. }& O1 H0 d
D.d
0 W2 x6 ^$ J; `7 eE.e/ f. `8 E- x7 f7 T* E" j
* V5 K0 K" y3 N( c. w

$ H# t6 j6 G) T9 Q  w3.如何让类中的某些方法无法在类的外部被访问?9 S, {7 O0 ]' Z& d
% {5 J' I/ _* h6 S  J
A.把类声明为private
1 l5 L$ Z5 \" P. N- B4 T0 x! iB.把方法声明为private
0 x8 v  ^0 G/ @! A. V# gC.无法实现
8 g  R' j# H. s# cD.编写合适的重载方法(overloading method)$ A/ p8 X+ ^& T9 y1 P" o4 ^6 o

! e& o- r; M) g8 i# s5 o# X& s; V+ `) P0 o
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) n. @! N4 N" X2 E9 x
5 L: P2 d% x' S" S4 `9 `6 M
A.MVC模式" V9 L) E: v- P" B' X
B.抽象工厂模式(Abstract factory)$ X# s( I1 ~% w; Q' w7 k9 K/ G& m
C.单件模式(Singleton)
' ^3 i; g4 `7 {3 rD.代理模式(Proxy)( n7 I& \2 ?' h! `+ I- z9 I
E.状态模式(State)
. c8 U6 h  e5 ~$ k# S9 M* f/ Z7 E5 t& u7 h5 H" T! O/ K

( A0 I. K3 m! f& C5 V5 D: x5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?) n0 ?- }, X- i5 |4 c. q7 K
: i. P2 i3 [# y- c; j% c
A.1个
& \2 Z/ @; h) s1 FB.2个- V9 ~2 N. V. `! n( h5 o
C.取决于系统资源
: a: t+ S6 X; i4 J0 K0 RD.3个! R7 |/ p) I1 Z
E.想要几个有几个+ W% U1 |# s3 c" D

9 S4 Q' v+ O, n8 u
" B( |: n1 _8 F2 h+ G6.以下脚本近似的表示了一种在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.多重继承2 z/ ~' O$ U- U) R- W3 v" V  l( {" R
B.接口' {1 ~5 K- |$ F4 Q8 _
C.抽象方法/ l& w- ]3 I0 \) ~1 I/ j0 w5 B
D.Private方法
, S# g5 J5 V3 {0 X' u4 hE.函数重载(function overloading)
! f: ]! E3 h- W, B: y/ A$ @) K& T( K3 s' m) w, Q3 ]

6 p& O6 d% U9 q5 x7.假设定义了一个testclass类,它的构造函数的函数名是什么?
# |, I. p1 g' C1 Q% u, f
/ t: A2 F0 T- ?3 g0 oA.__construct
6 j& q2 l5 M3 v. m$ JB.initialize
( }8 \) i+ Y/ NC.testclass
! u; l& Z9 i- A/ h9 O$ G1 WD.__testclass6 g! w# P  I/ }- l  N; |
E.只有PHP5才支持构造函数* {. ~$ m2 [  a5 E$ l! {

" o; P: k4 p1 Q- `
0 f0 h' w* N3 ^8.一个类如何覆盖默认的序列化机制?
# O9 [) U: x( V  ~" j  @4 k* h; Q+ d3 [0 Y: A
A.使用__shutdown和__startup方法( o. [* U7 @+ T8 N, o$ q$ p/ k
B.调用register_shutdown_function()函数
6 U! H+ p8 @: k0 N: GC.使用__sleep()和__wakeup()方法( l0 N. u1 `+ i' R
D.无法覆盖默认序列化机制: I4 ]! f( }. m' v2 ^- p) r
E.使用ob_start()将类放入输出缓冲中
( O3 d: A8 m# x* D. h& X1 q1 l/ o+ D; b7 {
4 H1 t0 g7 {2 [( X) D: j$ J, v
9.以下哪些面向对象的概念无法在PHP4中实现?
! B& K; I% h# N' o- }& Q
0 Z, ^9 @0 z% q5 F4 k) D4 e@抽象类7 _' z5 |' a4 i! V! b- P
@Final类
$ Q( Y/ y1 w. h@Public、private、protected(PPP)方法
1 u/ H& v6 A. Y# Z* N' ?@接口& \8 U# s# X, h" U4 I
  H, @/ P' [3 y9 t
A.抽象类
/ D$ }7 G7 |; e' j) P8 J) v: q! o& kB.PPP方法* {$ U  ^+ c% N, D
C.PPP方法和接口
% H$ W/ V0 B& c& ~D.以上所有都不可用8 R7 z/ }, x) ]! |; m
E.以上所有都可用) x; K* [4 _" I8 z
9 K" U' O- u% D+ ~$ V
, P6 B9 z( I) H: \
10.如何在类的内部调用mymethod方法?
, t) ]. q' M! U' |/ H+ P& f* t
) g7 X8 [1 _; H$ _6 S- OA.$self=>mymethod();0 Q. T$ Z7 e1 c+ O
B.$this->mymethod();- i7 Q( l% i3 Q. j* {' J1 {
C.$current->mymethod();
7 F  M8 n" _; V1 k& VD.$this::mymethod()
# s% O6 a9 W! E2 W6 z7 Q/ F+ C3 Y1 uE.以上都不对) N0 G8 D8 H+ F* `
- Q  M4 p" H/ E8 M4 a& [7 D$ a; ~

. P& q5 r/ T* e! T- F" W5 ~3 E11.以下脚本输出什么?

  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
4 I& @/ |5 g2 f+ }2 s4 {B.Null
6 J; ]" u) S% IC.Empty% M3 @) T7 P0 b& f) S
D.什么都没有
) R# `' @& U; u7 _% dE.一个错误  Z; Q% h7 }7 F. E5 `

( I( I2 g% c( i/ B+ Z( }
# z9 O; I* T3 O4 i  R7 X& g, z; o3 X- P12.以下脚本输出什么?

  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
% w! H/ C" {; E0 y" S3 V% c. r' v, OB.5  A9 @; {7 h, o) U; X
C.2
2 p2 _  |" s8 p- l  |5 bD.Null
6 L$ R) G; d  _0 X. T: RE.什么都没有
2 ?! m% H& z4 \" v  {5 j/ `
6 H" b# Z3 }8 `" G' Y3 p- W+ n
+ S. }/ e5 d0 h) o* o" @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
0 W- X! b! h/ Q* XB.10
# M5 p$ w* r; y" B& PC.什么都没有5 B+ I* K2 |' ~
D.构造函数将报错
( i5 {- x0 b4 gE.510# p6 u* T. A+ N

+ u$ V# t! O* I- H: E1 S# n' z) d
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函数必须返回一个值# V; [8 @( f; m+ N
B.reduce_fraction函数必须接受一个整型值
* h- I6 z. Z7 s: |  w5 ?C.gcd函数有问题
7 g) x- r- T; h$ ]* u' X7 `D.必须通过引用的方式传递$eight_tenths对象, U4 v# V( ~- R) N" l+ `4 x' l
E.对象的实例不能传递给方法以外的其他结构。" a: F: K. Q+ {
& n# o8 Z1 F9 X  W4 k9 X

' c2 I: o& x& d0 D: \; k15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法8 \! N& n: \+ A' k# n7 c8 p( d8 J
B.生成myclass的实例并调用mymethod方法; B. s5 D2 Z, E# \
C.产生一个语法错误& C0 ?" S" t- [9 ]8 i
D.默认myclass类最后被创建出的实例并调用mymethod()
( d. [/ [4 d, a$ L) bE.调用名为myclass::mymethod()的函数! G; s- v. R1 ?. b3 A
" f/ Y) z+ U2 l; A% b3 `/ q7 ?
" [2 f$ X6 ~/ n9 ^
16.PHP中有静态类变量吗?
! t2 e1 M' \8 q; O0 D  v( y; |3 ]" C+ }- r' y7 ]. _; L5 `
A.有; Y- a: ^- e( g7 Z& s
B.没有% g" ]- K1 ~. S# q4 {. ]# q
3 q8 u: Q5 I8 l
" w4 n) U1 i! i4 S
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
3 G/ ~$ m, N) ~7 g+ E, L8 S2 YB.2
3 u6 n5 ]& i: o( P9 x+ p$ KC.一个错误,因为没有定义a::$myvar
* Q5 V7 O0 W7 t  o* K$ |6 XD.一个警告,因为没有定义a::$myvar! r7 ^- H/ M. Y- |. E
E.什么都没有! `& q) V9 y3 k7 u
' O. w: k7 w2 U) y6 t

, a/ D* G/ P4 X1 q18.如何即时加载一个类?) |2 Y3 r% l6 _2 D7 m+ s  o% M8 H) j
; k! Q( ^* d" |- I
A.使用__autoload魔术函数6 s9 H, _  |5 p* m' a3 P
B.把它们定义为forward类3 A6 }. I- e' e' Z
C.实现一个特殊的错误处理手段5 G( G3 y$ \6 p) u
D.不可能
" e, q. ]8 z- k% K+ lE.用有条件限制的include来包含它们1 t4 t$ [  S+ z6 a" ]2 t

1 _2 P6 _4 O; \) ?
1 Y+ E7 e% E' [* M# O: e19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?3 K* Z4 s5 w: o& h- o4 A- H/ P) ~

. Q! F* r+ v" _5 S  J; B* D5 b    答案:__________. t/ x$ _5 I7 j0 E" E
7 L+ B% Z* [9 `+ w) ?
( v' A( M# i* |% e+ e" C
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
% r( T. l3 I0 i' R+ h) A' ^B.一个错误# O8 ?% G0 k. f1 z+ I( D4 ?' u' Q
C.一个警告9 H% E' Y" K2 Z8 i
D.什么都没有
) q$ m% y. ]& z5 }  k3 ]& ~( c
* K* g8 V# L; e- b
6 B/ n8 h' k2 o5 ]; C
. Q+ N$ _; G" V* J$ O& O- ?答案速查
5 R- N$ }4 Q9 {' y" V: f1.类7 L1 e5 x) q3 |& I5 T# b9 |
2.BCD
- }: y/ h, x- Y" K3 V! h3.C: t1 r" `. V% @7 n
4.C
6 @6 H8 H4 ~; q& e) w0 I! o6 H5.A2 U6 ]. l2 ?4 m+ D0 l0 Q% y9 k2 ~
6.C1 K" b' t! S! b, e/ ~5 W  e
7.C3 b- L9 ]5 y' @
8.C3 ^* j) b( {* x
9.D* A, r3 ?) X" z3 w% b
10.B
6 b; H* w# O0 O. F+ k; q. m/ C11.D- a7 d  |% \7 ~
12.B
( g2 h1 l, f/ z4 ]4 ?/ w13.A
! ]3 V/ z5 b- `' M: i* C' u  c14.D% s5 }& w" k, E  L# r" }
15.A' Z& e4 [! k' B6 A2 }
16.B
9 u. G, Q) t/ T. q) r' ?* I17.A. k1 h( O  s5 ]1 w1 Y6 ^1 q1 v
18.D: A$ W1 Q$ ]& n) O4 j
19.设计模式
  v1 h% ~  d4 D$ k( G  B$ F20.D' K8 [4 p3 e1 q; b* Z* c  H: a/ L

( m0 Y# P* [9 N5 J, s5 h0 m$ v6 O8 v3 u5 L4 G" [  l9 \
. }1 T9 _7 l2 j+ \4 W
答案详解
) M# z5 z6 }. S9 n, @4 R9 N( D/ ~9 p- L8 N$ z6 c* G5 _* R( ~. V, k
1.类是对象的蓝图(对象是类的实例)。
& a9 Q; h2 n4 a0 ^- ]
# k* m' V# \) H0 ]2 r, Z2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。) E% K2 C9 E! z. g* k" |

- x5 `& F% m6 g' t3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。  E, G* c# I3 O. M+ D3 V0 l

0 O5 N/ I% H% b+ u: Y4.单件模式可以限制一个类被实例化的次数。
. @$ b6 M) J6 Z; O: G) U) R: `( [3 J/ q1 t) U6 e
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
6 l6 N% D  J; d- J# q1 k4 ~* J' Q7 d: W! n2 @
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。* W' z; x8 P: }6 {5 N
' P. [0 h- k4 H4 s7 Z; D" c/ ~
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。5 _# r/ p1 m" g, h/ b

# f4 N+ V, Q) o6 e; \8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。, x/ B. K. m6 |) I) N: e. i8 \
: q0 b. k$ o' I. N9 A
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
/ l) [3 m  u# r6 g1 X9 M
2 O/ z5 S* K: }1 g. Q% K- N10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
/ Z+ M; G; ~2 f$ V4 f& H& V' N6 F& l: _5 }
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。* l4 F! ?5 z3 `: a, E2 G6 a' a1 W% e

/ O, C: {/ D! |4 M; E& s: p12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
& @4 o! P* v# L! C
0 P; z2 u3 t. z1 @9 S) X3 f9 C; U# ]13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。7 [: _: e9 m* a6 q) o. V

2 x; l' Q& l; o/ g" v14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
: O( y  K" i' }, ?. [5 Z回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
' E6 X$ b$ F: C    function reduce_fraction(&$fraction)) T' v- q( Z0 n3 V; V$ }/ _0 K+ C
答案是D。
  N" P& C" |2 z. s/ d& k
9 u. {, }+ g1 E1 S15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
7 ^, m0 E# X: p& m- p$ v9 V% o. W4 s/ [$ d$ e
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
) ?9 A" V: \% e4 k4 ~! v! Y, v: _& m% }9 ]9 C6 F. P
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。6 v: O& x; K" T" H3 g& x  Y
  f+ q! M3 U( o3 Y+ j* x. F1 h/ S$ h
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。8 y; @4 b4 G3 C: g7 l

: X5 E$ g% ^/ N# \1 z19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。4 j9 M, g- y3 N. C

6 |, p; g1 s3 g) I& P20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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