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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
+ V& E. b2 h4 o" M! m/ }, |, PPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。$ e" L; @8 U6 V8 j5 x
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
7 m7 m" Y" ^4 Y; ?, ], _/ n- m; B  b$ {- J& L1 ]& C! |
问题
: g/ `" s( F  R4 S
4 t' F7 G- S' E! Y' Y5 A1.对象的蓝图是什么?, y9 B4 ^0 g" h0 B, U7 s
$ ?/ C! f& M! v, Z
答案:____________, c# g: b3 ]% P+ ]3 g5 v
3 s6 Q7 _" N$ V3 b2 J8 x; S

: O$ e' x$ T9 j- D2 a) V2.以下代码执行后,数组$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& T- `: E- X( q# F3 l% T% w
B.b% B1 D- B& \& b, K' n% a" u# u5 ~
C.a
1 Q% J/ k* N5 ~9 Y/ h" R3 d$ S# ~D.d: h$ n& d! W5 J
E.e
. T+ h6 p! c! H* l! O9 X0 y5 x! O: n
$ {* h* g' L& _, Y/ \2 N
( ]; A+ f  [& R# g3.如何让类中的某些方法无法在类的外部被访问?# a/ ?- _: b+ J# u& e6 E

) p* T5 }  S( T: D9 x  f2 PA.把类声明为private1 g7 f: C& a3 s- T, k1 x
B.把方法声明为private
- J) S  d9 u! B8 R7 fC.无法实现7 K6 y1 x. }7 o! ~
D.编写合适的重载方法(overloading method)  n& x5 I& p% w, V

# b1 s5 Q* `5 d! l+ g4 ]0 u0 X9 L) e9 O( D0 K
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) K: O3 G! @6 q: i/ A

$ q5 K5 g( e2 m/ [1 b. J; e3 BA.MVC模式
( r. d" _2 w/ {1 `8 cB.抽象工厂模式(Abstract factory)
3 p1 D8 {6 v$ G! [3 YC.单件模式(Singleton)3 k. y  U/ ^) n7 U
D.代理模式(Proxy)+ f  Y% g/ F  ?" g# T+ k; P
E.状态模式(State)" x9 l& b  g8 o

" D* E- f4 Q1 ]/ L4 t5 y+ G' |7 w* l1 j; B
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?" o* Z, S  \& A* ]! M
! p% W" K9 x7 m; f& [  Q4 s
A.1个7 W2 I9 H/ y8 \0 C, h6 k0 ?
B.2个7 y! C; g/ @6 k
C.取决于系统资源
6 {9 s  l4 n/ T( uD.3个1 v3 o# X' j) ~* ^
E.想要几个有几个+ }6 v: O3 b, f5 R9 \
! p# A( m" M+ ^/ K8 P& z+ r

7 D* K! }6 Y' b+ ]' y6 D9 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.多重继承
% X0 ?! r1 s% d7 u$ @B.接口
: l& @- a0 M$ nC.抽象方法
; Y" Y$ G' g. u- W( B- J7 ]D.Private方法
3 |1 b0 w" V- r% ~  i: ^E.函数重载(function overloading)' k* {# I5 G- a. O% @- T8 ?2 d

. \# g6 W8 Q. o, V% @  k  ?$ ~- O' d& ^/ w( D  u
7.假设定义了一个testclass类,它的构造函数的函数名是什么?$ M: U9 ]. z/ @! i, E$ |! g4 T
+ n! j( f/ c8 V
A.__construct
" m& Z6 K2 C3 H+ a6 ?2 _B.initialize
* o( @% H: |0 v5 V/ CC.testclass
8 a" |1 P9 M9 o: AD.__testclass; b7 ~5 i+ L; }
E.只有PHP5才支持构造函数
7 G! H( }4 {4 C' h2 ~
2 ~6 M3 C/ [/ W5 f& d; ?( e, ^. U: J8 C  E' ]) k6 o* k( M
8.一个类如何覆盖默认的序列化机制?* H5 N3 M. w& p
+ c% l4 }9 F5 S- c. ~- q
A.使用__shutdown和__startup方法) F/ f% x! w  W. p- f
B.调用register_shutdown_function()函数
* Y- W( q$ k! m5 t' FC.使用__sleep()和__wakeup()方法
8 a7 W4 E$ o4 y# U& {, Q8 tD.无法覆盖默认序列化机制
6 ]8 |- A1 V0 |) I( ~+ G8 iE.使用ob_start()将类放入输出缓冲中
- \9 D) f& T9 R0 D3 v) l4 Z0 h) C6 C4 T7 B+ }9 P4 ~7 {
0 _4 M8 g; a$ B' k8 ]
9.以下哪些面向对象的概念无法在PHP4中实现?, I# A2 a9 s. W7 P

; ]  {+ y8 z, b@抽象类; {. T. b2 O" _  R- P4 \2 [
@Final类2 z) h, h' C+ M, z( T6 G6 k
@Public、private、protected(PPP)方法+ x7 @, e4 [4 S9 `% ^
@接口
. t1 m0 L7 c3 O! h/ }$ h/ s. M0 f" I  `
A.抽象类2 e( j, e2 U4 t; B. e
B.PPP方法8 T; F. ]  f/ B+ P
C.PPP方法和接口
! `8 C6 |0 T/ a( h* q- h' x; @D.以上所有都不可用+ p; z2 W7 g* B2 B. y' x* s% _
E.以上所有都可用& S1 X! F) c" C+ k) G) ?
( m! I( s8 A- ~! u7 g' I8 z4 h$ U: h
/ @# h( g. d- U9 x
10.如何在类的内部调用mymethod方法?; I) G- m; A7 P% L

2 u) I& Y/ e; c2 U" d, H; a$ HA.$self=>mymethod();. `$ T: e$ v4 W
B.$this->mymethod();
. E7 ~% y0 z' b, x6 }% tC.$current->mymethod();
# R3 k# _1 Y3 V. T* Q. G6 zD.$this::mymethod()
& y0 Y7 G2 A& A: d" VE.以上都不对
+ V' I+ {5 W) a$ s
1 @) N( V7 w8 J; T
* x6 u" h% x" T# o1 e% P- D11.以下脚本输出什么?

  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
% W# `6 [* k+ c( kB.Null  @) z. N) }+ P* _
C.Empty5 I5 \, s; j, G$ l6 A1 q5 ?/ ^
D.什么都没有
% N( I% A! }7 R6 s4 qE.一个错误! o- T" ]  |" K( n. k

/ U0 S& Z4 A& H  T7 ?# S5 v
2 L3 U+ y2 n% C* u7 `8 y) {) N12.以下脚本输出什么?

  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.106 J2 }$ z. y7 c: t0 T  e, P
B.5
4 U! ^0 ]" ~9 I% Q0 i1 ]3 `# q1 IC.2& Y3 n% n0 x1 D, z! t* C+ Y% y6 g/ L
D.Null. t; j/ R2 g0 C7 g1 F
E.什么都没有9 G" n' `0 U7 M. p1 ?

- p) k; v* F6 F9 k
- C3 ?; O, V4 n' y# n, u13.以下脚本输出什么?

  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 h5 q4 L& e2 dB.10
- J1 F- l7 C7 ]C.什么都没有) O7 `3 U0 B7 q5 M: z7 C: u; W; I9 M
D.构造函数将报错
0 Y( h+ I4 ^9 |0 i* g% EE.510& c# S$ X; b( n0 ?$ P! c5 V. `

5 A8 ?& `" m2 C9 }- q
3 f- D  ~7 w8 @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函数必须返回一个值$ L9 d! h. w" A$ z5 T$ k1 G
B.reduce_fraction函数必须接受一个整型值
' y7 U9 ?7 \- U8 zC.gcd函数有问题
! T7 u% C2 V+ p' R0 I  BD.必须通过引用的方式传递$eight_tenths对象5 i& T( \2 t" z( w% o7 v) J0 Q
E.对象的实例不能传递给方法以外的其他结构。
4 j; I; {9 j: U" u. q  X* p' W9 @9 P' o: r6 ]/ W
  `3 J' A2 w( P. ?- _: u" w/ M0 q
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法; w* c& Z: \' {4 x! y# @8 C& t; X+ {
B.生成myclass的实例并调用mymethod方法
# L" q# j3 Q4 H# gC.产生一个语法错误1 f$ v7 K5 f1 Q9 h
D.默认myclass类最后被创建出的实例并调用mymethod()
3 ]# D* O* Y& [- R: C# ?7 Y6 T( ME.调用名为myclass::mymethod()的函数( a, O2 k5 o1 ~7 f: Q% O  m+ \

2 T5 ~4 `1 K: K: j3 d6 _& K; J; Q7 z; q1 Q1 f* O5 p% B
16.PHP中有静态类变量吗?
* M, _# }, z. S- ~3 J% Z4 h: o- i* ~+ z& v" _7 \% F) [% v- @
A.有
) u- f) I6 E1 G! ?+ yB.没有
7 e* l8 Q/ g; n: L  A3 C
" g4 ^, r, \1 f# L( b! ?& ?, ^/ n, _
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+ F9 A1 m; \& D; F+ x
B.2: o  K- J7 n: H& }
C.一个错误,因为没有定义a::$myvar
, |$ G, S1 q/ I: ^( z& S/ jD.一个警告,因为没有定义a::$myvar6 y* x, f9 W: n1 q
E.什么都没有  I- B- a/ @* q6 h& {3 a  C- d7 @
5 F  ~, a( N7 P' [9 d

0 O+ O/ @# N( d1 t' z4 @* {18.如何即时加载一个类?
) x6 \8 k' H. P' y7 ?3 r- g+ ?$ }. w) Z
A.使用__autoload魔术函数
% C; S. k4 z& C& _5 NB.把它们定义为forward类
- I) s$ |0 ~5 h  aC.实现一个特殊的错误处理手段5 m4 Z; I, V. Y) \! ~
D.不可能2 }0 a' V. v+ ]. D/ t9 L$ c( R
E.用有条件限制的include来包含它们8 y' x& v9 W: Z
  G) D  q8 ]  n- E) Z

- s1 _+ |7 S5 u# i# Z5 ]/ V4 c19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
  R: o4 T% U* s" C2 \# A
$ ^" O8 ~$ ]4 {0 O( Y  K    答案:__________1 ]4 ?; n! U$ ]* X" w) V4 d6 |' x8 i  g

1 K9 ], F; a7 h
7 E, G8 M, R& k. j* A0 }6 Y2 g6 X20.以下脚本输出什么?

  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: F' H* t) M8 P% j- l
B.一个错误$ H& g9 A9 S4 W# {
C.一个警告5 }4 A2 K! m5 w. d, Z9 D- x
D.什么都没有: N2 u' `8 V2 D- T0 D

( g( Y2 P9 L; z+ T4 Q! a& R. ]6 m4 i1 Z
! L: n0 i1 L: q! K7 d$ o- u- b& `+ _
答案速查
! T8 ]0 X8 {, z9 q: J7 A5 t1 S- n1.类% G' \9 y% Q: O. I' x# R1 M
2.BCD0 Z/ U% Y+ N3 J& m" W1 h, S! H( X1 M0 G% V' i
3.C
! q+ o& I4 ^: f4.C' i4 ~& m- B# F, Z6 r8 d
5.A
! {' K' ]5 ?- g2 x6.C
- r3 D0 [, H9 X7 B1 M+ p6 ~7.C* O$ Q) S+ k( E" j4 R* Z
8.C
. r8 q# S# [9 T! o9.D( r% O; \; P5 i/ I( x. h
10.B
% _! S" L7 l: H) U. j) \5 \* W11.D- f9 g' m. l9 w+ q
12.B
& t, t- G/ I( ?: _$ s% g/ d13.A
* B% H5 F; I+ B$ f14.D8 b- `8 R1 }) r! _" H6 J# B+ a  O
15.A
. v9 A9 }) y+ z5 j" d4 H16.B( X- c; V# y, E, e! X* R
17.A
1 Y9 ~: n" o& V& H18.D
) ^" [) Z: Z( P% n0 q  v5 c19.设计模式# G" b  H* P! X1 R' u( [
20.D) p! q% V5 G* K" K6 ~  F
4 U& U- K2 X  Z( M! J
2 z4 p3 i2 w5 |- @% D6 |
8 l# Y* b+ d5 i4 p
答案详解
8 l: q2 a4 ~; O
% M0 Q7 W% y1 w4 z/ o+ Y' A( Z7 y1.类是对象的蓝图(对象是类的实例)。
( |! j2 I. W4 d# c, a! u8 [
* z& k! `' Z& B5 U8 X5 J* G" V2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
& w0 t* t% Q- X1 n6 m: q- P& ?5 M/ l9 h* I4 ]* u1 S
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
; X2 K5 z6 L/ s5 ?+ S; [1 U5 c
6 Z0 u+ ~; Y3 `7 F, k: \4.单件模式可以限制一个类被实例化的次数。' K$ O5 u0 Q. b, D
8 F8 A+ I& r, v* ~3 h1 c
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。  Q* o" z2 I  {0 D$ c/ p# `9 e/ N

7 t* f0 r- N4 m) J- U3 w& p6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。0 L9 S. s( g! f
1 ^; b0 Q) @6 B, s, M
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
7 R: E+ k; P, e
; O) H1 k" E6 c1 _5 U' n$ H8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。4 ?8 {+ H8 o/ `1 d7 Z+ ^
) V/ L+ a; k/ h1 Q: n2 O
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
! m5 G( i6 a4 M3 j. g$ z; u0 P  ?: m1 n/ B4 j- o$ a- \  u
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。  Y& X- [' J$ Z3 h
2 J+ f# A$ q( C% w0 L2 y
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。, z& h# x, Z% D& T7 x% J' _

2 M3 q, j5 a3 M2 O8 U  _12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
* ^. H% B2 h& E: O1 ?% D( z
4 C2 a6 d) M! [9 {8 t13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。: m* E  r( P- W% @+ X" T
7 Q& C4 U: ?8 H6 l+ \
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
. `: x8 b+ H% }回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
: ]" z, V  @. r' S+ q5 F6 n    function reduce_fraction(&$fraction); N) v) Q3 C1 [& X: y; U9 r5 v
答案是D。7 r$ ~4 k6 |8 t+ F2 P

" d$ ?8 v3 G. w15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
/ G5 v% @1 Y: B0 ~8 i2 S4 J! l4 v4 d2 c* \: k+ a( s
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。" h) w" ]0 S" A& I

  F0 ^# R3 Q, {/ F: I  K17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
" }" V( o1 H2 [: ?: |' n2 n5 F+ I7 _# y- W+ L3 r
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。, `  l$ x- K9 |* d- a$ [% a
- _3 v8 M% F: S
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
- Q# d( t- u6 P. e, @- H) y, [* B2 A; a7 E6 w
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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