Board logo

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

作者: admin    时间: 2008-4-4 02:24     标题: [Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。: l1 p  V! s$ h3 t+ }5 b
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
( u( ^/ k( W8 j. U2 t- S0 R7 p本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。- q& A' Y7 H( @. E( \

( C% V" S; i7 H9 r问题
- D; C! w3 F7 ~& f/ Q) J" S) x: B3 @  u" S$ T
1.对象的蓝图是什么?4 z, i) {+ {  O

/ W: z$ k" |: [" q/ g答案:____________
% v4 t+ B4 e( h& \- ?9 ^9 ]8 \5 h  R5 G/ U: ]: I$ Z$ \  @4 w

0 `5 g8 d8 G3 E/ z, S- p2.以下代码执行后,数组$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
1 H0 e* [; J3 Z/ e" RB.b2 C2 J& e0 O* I
C.a( S3 v4 H, L/ K4 q3 f
D.d. l) A/ I+ I6 G! B% P$ Q+ k2 Z
E.e
2 y! D9 S* T: @& |
( D; ~& E6 H" z3 t$ [: A: E, n2 F* q% j" i. ^
3.如何让类中的某些方法无法在类的外部被访问?" z1 C$ J/ g& T6 \0 T2 l. V/ i7 H

& {; a# V1 W- |, [6 b* i+ m2 L3 w* LA.把类声明为private
7 s+ o' H2 S1 D3 X+ EB.把方法声明为private
% G5 [3 C  r  h# HC.无法实现+ [; _7 f; w+ v/ g- U, w
D.编写合适的重载方法(overloading method)
+ ], N" [: z9 d8 n; c. a1 b1 ^# ^: T9 |0 Z8 p
7 {" B" `% [0 x* `) ~+ A0 F
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
+ S, t! \" s4 {' N" C# P. r* g+ q: n& }9 ^! P" z
A.MVC模式
, m9 G, x' H6 C2 ]B.抽象工厂模式(Abstract factory)% Q/ X9 t* K- k3 R( g
C.单件模式(Singleton)
+ j2 E4 o' I+ h+ MD.代理模式(Proxy), m( V/ R1 f$ N$ [; I# g
E.状态模式(State)
4 }6 v9 n; `! V8 [6 v" t" w* w, R5 @4 F/ M3 G8 r8 U
$ a2 n  s; N# j  t4 `
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
  ~7 w: V" _; [) b0 u0 Y! t6 Z, Z# |' T! @$ b& e) p
A.1个
0 d- z2 {' G. s3 VB.2个
; K7 ^5 C2 Y7 y* `2 e# xC.取决于系统资源
. L! z. t7 }: @7 N2 mD.3个$ q" u5 u8 j7 K; O  ^) j
E.想要几个有几个3 |" \' A- F, m4 ~' T  ~6 d! z  p; S
! _+ }# p. K, L& U
) w) g# P6 \; Z, N% n
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.多重继承& t8 ]$ b4 T# \, t/ I
B.接口
' |5 \  V1 |3 X4 l1 lC.抽象方法
$ S+ B2 J, A2 U8 [" A( `D.Private方法6 n0 Z2 r6 o$ J4 Z% H* m
E.函数重载(function overloading)! k' o4 `- {/ Z" X- U. P) U& R

2 c; P, `7 D8 [9 l0 I, i3 U% T) [
7.假设定义了一个testclass类,它的构造函数的函数名是什么?9 G* A" l- o1 Z% X% B

8 O6 P% j# l0 N! F& K; I8 |/ K2 c! `A.__construct9 k7 ], i& k7 R, k4 n7 z  d7 x/ Q
B.initialize
' G! ~! A* o1 ~( gC.testclass! D9 ^$ U' \; u( B' x. Q
D.__testclass0 g! Z0 X/ h4 W; S
E.只有PHP5才支持构造函数" O8 d+ b, O/ Q6 u' \( B
, W1 N* a. q: [. M

5 i% h# N/ o/ O( }" t6 e: K  P8.一个类如何覆盖默认的序列化机制?
! u% a  U8 ]2 }/ o! S& [0 V* e' S5 A9 H: ]
A.使用__shutdown和__startup方法
: g& I4 Y+ L  t; a% m& g8 D& GB.调用register_shutdown_function()函数
8 Q% X* J2 R, |1 ]; ~( @C.使用__sleep()和__wakeup()方法
! q& D( G1 U& Q9 g3 @D.无法覆盖默认序列化机制, f  H' i  l6 R3 I
E.使用ob_start()将类放入输出缓冲中& p7 S: _7 f& E3 i) ?

4 r$ O% F2 ^1 D% C9 I; S* }$ g, Y
  O% J7 H  h6 w# P/ j+ o% ~9.以下哪些面向对象的概念无法在PHP4中实现?
9 x( t# J! I( c; s: T7 j
. x, ]6 x3 S5 z@抽象类9 b1 d0 v8 E, q# R# ~+ J
@Final类- H# Y" g3 l, h8 I/ G9 D
@Public、private、protected(PPP)方法
: `. h7 ~1 `9 I8 W@接口; q/ C6 S3 X, ~; D  N
2 K& |' m' ^. D" @7 |  @9 C' s3 }
A.抽象类% H! M' u& v  H6 T% K6 t) ~, `6 R+ C
B.PPP方法3 |/ B- v( u: C& J" I" G5 t
C.PPP方法和接口
  J/ h& A9 L% u* m6 lD.以上所有都不可用' ?$ K, e* B" S
E.以上所有都可用& k1 B/ {3 u, j

: A. d- ?7 ]+ w6 b1 L4 N; Y6 w  O7 e4 O
10.如何在类的内部调用mymethod方法?
& [2 r2 K1 z! `: R* i; s+ K
! F) |8 d- E. i5 ^" G% ^A.$self=>mymethod();8 H! c; O$ ?  y3 G% G4 t$ T
B.$this->mymethod();
* n, \. Z; V" K7 k9 y- s; }6 uC.$current->mymethod();3 [! Z/ L% {% [: y
D.$this::mymethod()
4 F; L. ~7 ]$ ME.以上都不对
# g! V+ X9 z  X* D: k! S3 v% g7 s
, y- S5 S5 L- g+ D
+ Y  c! H% b# ?4 l  `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
5 c5 U- F4 B: Y+ v* fB.Null/ Q9 \  q% t  _3 S# m
C.Empty' J1 p' e' E5 F: Y
D.什么都没有. x1 u" N  W2 W; y
E.一个错误" T  ~" }, u3 p& P8 h/ g

! |8 |$ N4 L& A% I6 ^- a! f& s) b( N  o2 \
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
1 [4 }3 I( O0 Q/ J) WB.5
5 w& n% V  r% bC.23 L, \. {# h' r( y! X; Q
D.Null
6 k* z# H. d* D9 i# FE.什么都没有
% A, M9 f+ F: K4 Y! G& ~
7 s! a8 G! y, i. G2 i& B
4 C, t' G5 P  L! a! y13.以下脚本输出什么?

  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: p5 m# Z5 |! Y: \% p1 k$ B4 a
B.10
% m1 R% f& Y6 o* P. g7 \C.什么都没有
0 ^* f2 F! r8 a: j( Q7 P# `( vD.构造函数将报错
/ J: u8 w/ T4 i. B* G* ]/ R. ME.510
' n, R* p) p. o, A& h
; J1 R( U3 t) O
( X( k2 m# U  ~% `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函数必须返回一个值
, f+ |% f4 K. }. UB.reduce_fraction函数必须接受一个整型值& \! ]9 ?* O; V: E5 B& c3 ]: J
C.gcd函数有问题- X/ q" U- }3 k. ~9 V, Y
D.必须通过引用的方式传递$eight_tenths对象4 t8 n, d7 r# U/ b7 F+ l
E.对象的实例不能传递给方法以外的其他结构。- [* _0 C! z- M0 a

; T) Q6 N# u( e
2 e9 L9 B+ r. w8 ^7 y3 |4 B; L0 m15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法) M5 o1 K+ V; f; m! Z* @! S1 _; [% l
B.生成myclass的实例并调用mymethod方法
* L! y* C; l4 ]C.产生一个语法错误6 S  `6 t8 C+ {! P/ C
D.默认myclass类最后被创建出的实例并调用mymethod()
5 l8 F8 }$ ^5 s1 vE.调用名为myclass::mymethod()的函数
( t/ V( t" u% m8 A. n' \, t: h' l( e: [% t3 Z3 [, A

: \. I  o& W1 c5 |8 Q# W9 y1 A* R- n16.PHP中有静态类变量吗?8 P: q3 l9 P& j+ E& a. S
8 }* ^: o" O4 D6 r. z  v( `
A.有+ ~+ G" V8 y; p. r
B.没有
2 b* b0 h. d% k4 \, f
) g6 N3 i9 k  F9 u- H6 b+ z$ X  `( s$ |' d! o. m0 Z) A
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.11 a: e) \- t: W3 x  M. ^
B.2! u& S0 D' B3 O
C.一个错误,因为没有定义a::$myvar
# G* Q* x: A$ F, `D.一个警告,因为没有定义a::$myvar
, W4 u$ B) y5 `E.什么都没有
& U% Z8 Q$ a) S0 r- X) _$ s! V8 C) i  |, D

0 \5 U# ?; n, z7 k2 `7 c' u18.如何即时加载一个类?
. J9 k  B5 ?! L9 g$ U
, k: z) |; x* ~: w7 `  ZA.使用__autoload魔术函数
' ~  {/ p" X! N' Z4 V/ t) F8 Z0 wB.把它们定义为forward类
: b2 A/ n/ U) W  Z6 yC.实现一个特殊的错误处理手段* h0 `& l/ [+ v+ }7 @9 N9 m
D.不可能
3 B8 f$ c, ]$ b$ U* zE.用有条件限制的include来包含它们- S& z! o( v; V1 f

: J  @( u0 \: O+ I
6 q  v" K+ h# \; O% ^5 z7 j19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?: F* I" w5 O+ {. J3 n( `) q$ Y$ C* b

' m; y7 b, S7 R' l9 X1 \* }! c    答案:__________
$ n: h, G2 Z8 R" m% r/ T% `$ S+ F$ ?0 V! Q* K" j. M0 Y

* ^, ?- `! P2 k20.以下脚本输出什么?

  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
+ K, h' V7 a9 {+ d: I1 {4 a, {2 fB.一个错误2 E* R  H' b4 a  f
C.一个警告* Q: ]2 {! w& p
D.什么都没有5 X- i8 t% Y" }( F* B" ^

7 c8 t) x+ U5 f. ]9 y+ d/ h, U. q4 S* e- z, k9 G* e6 Q$ k% A

& A; r6 w8 ~- L! w答案速查. V/ G& T" l6 K5 q
1.类' B  X0 _  L" k) x2 o4 U! ?
2.BCD. i4 w; j) z# t5 }
3.C
, J9 Q& l! M5 Y4 }  n5 [$ T4.C
! q# u& V7 }" F$ `. ^. Y* v5.A
: t  z; O1 H- c2 I" A4 T( f0 ]6.C
# ^4 Y( j; L( R# I& v7.C
% S4 @5 w7 v; {! O2 r; n8.C9 N4 h9 V! O3 B) ~# ]! O
9.D
! Z8 u; d; ?- |7 G* L10.B
" L2 O1 }: E0 N. b5 w11.D
8 y( K( M1 w6 p4 e12.B
9 w. A( t/ Z" `4 _" _3 Y* W13.A+ n2 S" f* q9 |' Z% o. L
14.D
6 K9 ]/ d+ T. {! v3 \1 Q* U! P15.A
) q0 `/ y8 @, l8 R3 `8 s, m16.B. [# Q3 X* m+ B; v; j% R# G- T
17.A) ~5 i" k, C. h  [4 Z+ Q
18.D
) W9 i0 `8 n: C6 Q" g# X7 ]19.设计模式
0 }, s  n3 z' b$ b# L/ [  L: C20.D" n4 F: m+ |3 m8 C
  h1 A+ h/ H7 e* O% x" y
$ O1 j9 N9 U3 s

" W+ l, x1 [# k: D答案详解0 f5 @* y; g* O% e
9 q* P, K0 M2 D5 z" T
1.类是对象的蓝图(对象是类的实例)。
. {5 q/ }2 r3 J. w+ t
, M6 ]0 K/ Y# ~- O  r/ V. T2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。# a6 J  l9 ~; P/ ]5 g# T" F

; q% I( k& D( ]3 _! J" Q3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
) [% T# s6 q/ @. @' b2 i3 q& m, Q$ o# v( k* t/ M4 c
4.单件模式可以限制一个类被实例化的次数。2 c" N& v  A4 A

# |) @& M* [6 c% W( r5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
; ^, A1 [1 P+ K3 t8 E
/ `1 e2 r% f* W: n) x) w, ]6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。4 f+ M5 ], o7 F$ Z/ S0 G) s( f
* q' S, A" s( j: v  w
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
" c  Z* H4 J! W2 ~8 o; H/ [; \( s
) ?" e( u' s' d$ y) [3 b2 L5 \8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。% h9 Y& Q5 p0 }

# T& A4 w7 Y$ v2 @+ _" b) K! f9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
- V3 H1 [9 ^" \6 L0 s* _) Z$ @( N
; N1 l( x& L/ ?$ G1 k5 q10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。' ^- F8 f" n8 o: E8 u
( Y- F/ V# R: Q  M, A
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。' s3 _4 _# C3 `) U' N) U, g# i' ]

6 l. S/ G2 ^4 I. o12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。0 m0 s+ g5 t+ h1 {
5 F6 r: l& O. U5 |& x* B3 q  J% o
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。. O3 D" C: y. Z/ O
- X5 ^' {# r) ?- R8 H0 Z% ~& l
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
7 p4 D* Z7 p# [0 _+ f& A1 p0 S) Y' w回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:" \, |. O  u3 X0 y* g0 r1 v6 i+ a: O
    function reduce_fraction(&$fraction)& a7 C" j& c! Y
答案是D。0 y  C6 c. \, }" o" ?

1 D8 V/ ?9 k; c5 _15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
: ^5 v( Q2 E0 a7 j- q; T  G: x6 R- `
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。4 L0 p: i7 r, u% Q. F! x

4 v6 T4 o5 p2 q* Q# g" ]17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。: P) }. W: G1 L

3 `7 p# j; S( _) b& ^# R18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
4 M/ T0 H5 v  Z( N% ^: Z  \2 F5 @- X# U2 `
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
% u0 ~! C' A) Q1 V3 }+ d- a$ x2 U( o; @% T9 S( W& f
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。




欢迎光临 捌玖网络工作室 (http://89w.org/) Powered by Discuz! 7.2