返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
8 R# o: M3 F9 Z# y: U, nPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
+ U4 x7 ?- O' ?# k5 m5 a# Q) s本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
( z! D/ B6 l3 P8 n4 `* \
# F3 i( B2 A5 I  P# C4 [. d5 k3 Z. K问题
: w8 v: n' r1 f" t0 x5 E$ t2 O2 }
- b5 Z/ A4 y! T8 \4 p1 G& m1.对象的蓝图是什么?9 X9 V9 @/ H  l4 D+ s& P. ^

0 \; n3 ?, {5 V答案:____________
3 k4 f6 E; h  P, s9 d
9 t" e/ q. \8 h7 f
& x2 X) j4 @' g2 X: |' o% J2.以下代码执行后,数组$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/ x' X6 l: G, \1 o. D$ l
B.b
+ x' k5 ^6 n# C! V8 [' S4 xC.a
$ s: y  C2 k2 r: \, b$ FD.d
  p+ l& @- F, J% w+ JE.e
# O1 Z/ L) c$ _3 ~( E6 j1 c
& {' T9 {5 n  ^  k4 z  s; ~5 r0 r$ e3 Q. C6 b' [( q
3.如何让类中的某些方法无法在类的外部被访问?
  j; R& L! f$ o+ y
) l2 }" f& k' t! j5 `; v5 I1 AA.把类声明为private& |6 M$ V' ~, h! S$ }. E
B.把方法声明为private
3 b+ ]5 Z0 t/ Z9 wC.无法实现$ i0 _3 t% _  n: {8 i
D.编写合适的重载方法(overloading method)
; p; N$ P( Z& h! N# `1 D+ }( ]: B( z( c7 e8 Z
' E+ e. `; [# j. ^7 ~$ F5 G
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) w9 J* i5 P/ R- ]

9 V8 V4 {$ d% fA.MVC模式
8 z& `+ b& Y  K' B9 \B.抽象工厂模式(Abstract factory)
2 t4 j0 {  w+ F3 ?C.单件模式(Singleton)
" b1 }: U" y. @; }D.代理模式(Proxy)
+ Y! s8 I1 H$ q7 jE.状态模式(State)$ m7 T) q: f# T; V$ k
+ m$ m# P' l6 }9 E# j, U. ~
. n0 w5 T+ H  o: ?! I
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
, l3 i% f& K4 P/ c; O% F6 r: l
% t% W+ i1 l+ j3 R9 ?* nA.1个6 y9 E+ l! D" b/ t8 J, k
B.2个! e0 |6 c5 l1 y% \
C.取决于系统资源
' L+ l6 }/ @3 C; k+ y) aD.3个
- g8 c0 d) C9 S' @2 SE.想要几个有几个
8 v5 D. G. ?0 M3 v5 Y0 ]" i
3 l+ ?- M9 N/ C+ n. R1 ~+ r5 E$ N, T  h" Q4 I$ p4 ^5 ~* S5 p
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.多重继承
: @2 k* J4 e7 W/ H) L, F( Z3 HB.接口
% A2 m/ n+ A  gC.抽象方法
8 m7 w% \0 Z% o" V* }: W0 I! LD.Private方法$ X% c0 k* S! o5 ^# `
E.函数重载(function overloading)
- @6 h+ a/ b/ ?8 [* C0 [3 x% ^" F- I& q4 ]9 ^: o9 P$ |

, Z+ l. {# w8 |5 Z7.假设定义了一个testclass类,它的构造函数的函数名是什么?3 o# B, p, @: \8 h. B4 Z
1 I' f% V) @" e5 b- k
A.__construct
, [  K- i2 b# b- w' e# L( a( DB.initialize
1 K9 C4 {4 b+ e) b2 L7 z0 P! F0 {C.testclass2 b/ Z* P- V4 o9 d) L" k
D.__testclass* w4 C0 ~! r% z
E.只有PHP5才支持构造函数
! u& ~3 A: w7 E7 @9 |: M, t
5 W- E; b1 Y6 o) W7 S! |+ h+ Y5 Y& ~; t) i$ Z* y
8.一个类如何覆盖默认的序列化机制?
$ {6 b/ _) w2 m( f1 [$ j3 y* C$ X* o
A.使用__shutdown和__startup方法
# R, \& r; N0 e1 |7 g$ @B.调用register_shutdown_function()函数2 U2 b# c+ s9 W: J# F  K' B/ P
C.使用__sleep()和__wakeup()方法5 d* C) V* ~7 c# ]% r; b4 j$ H
D.无法覆盖默认序列化机制
, `9 g( s7 a. b1 b. f6 qE.使用ob_start()将类放入输出缓冲中5 `8 B4 D6 X! }9 {
! Q/ w' J  H9 T4 F' p8 M; h8 f

) m' w6 O7 E$ l5 |$ u9 j( ]% F' Z9.以下哪些面向对象的概念无法在PHP4中实现?3 \4 Q. i5 q' Q- S. F& D

0 ^# Q7 O$ Z  y2 i3 J- F@抽象类2 ?; f6 W+ e- M7 O& U
@Final类
0 a% U/ G, f  y: J@Public、private、protected(PPP)方法) Z6 f8 {  b6 i4 l* m# Y. C5 V
@接口
/ a! h( h$ D& L7 D% k
1 Y$ ]/ C. `6 h9 IA.抽象类
# B. {% o9 b  ~8 O; k- `) `7 D& xB.PPP方法, p8 B! k# |8 J: o  o( L1 K% U
C.PPP方法和接口. i, v* [9 `! u5 t1 a* D) q) Z
D.以上所有都不可用
# x+ x# E% C! Z, yE.以上所有都可用5 |6 {2 T) a+ E
7 C+ z" S% C7 q+ K

$ {3 i9 Y2 W0 g" }/ l, S0 t10.如何在类的内部调用mymethod方法?
# v# W9 X$ V) C! I5 i# _: j
2 ]$ Z" ?1 m/ N; PA.$self=>mymethod();
3 c. K9 O' R7 X/ b  ~- `" K2 f2 xB.$this->mymethod();
8 v; K( v" [/ S6 ]C.$current->mymethod();! P; K% ?, R8 x% f
D.$this::mymethod()
% f) ?+ ?2 V' p- x4 hE.以上都不对0 W& \) d# X  B/ j) h& [

" a9 g; W( z# a3 @
8 }; y+ ~) G1 n% z5 z* p1 V0 n' v+ o# l11.以下脚本输出什么?

  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: H' {1 T5 M3 {: c
B.Null
% {% |+ Q* D. A1 t# d# DC.Empty2 R% D6 X3 s6 D7 A2 g  n
D.什么都没有2 P; v6 R( I7 O1 d( `3 c
E.一个错误
6 Z5 ]/ p9 O  n) T8 t) R" Z7 T" [. V( K6 Q- x1 j2 p
* M" f8 \& p! x
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( [+ D- S8 a5 V( c- y  Y1 B
B.55 i) {% F' B6 i# K! \/ T
C.2
6 B. t& K% |7 ?+ n. C, p9 ED.Null
2 y$ i# }9 g/ E* D9 r" OE.什么都没有0 N* U* x$ P) P! K

' O0 }" {$ a9 k, S" j. p, z  b5 _' k5 {: j3 c. n) E' ^
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
- o' V5 K' o& K2 |( r* e. P! @, S. vB.10
; g8 A+ E4 i8 c9 s5 i( J7 aC.什么都没有
0 z1 _) h1 E6 c  E7 p2 _( KD.构造函数将报错/ e0 \) _+ ?( \: Y/ \
E.5100 Y  I# `% j$ x, b, Y" n+ U" o
4 w1 N2 `3 S" k. h  d
/ y: G" {! r9 i1 n+ p. ^" @; T
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函数必须返回一个值
8 m7 Z9 o+ u2 J, C# Q1 XB.reduce_fraction函数必须接受一个整型值$ n( |" g* I1 }& G9 y4 L1 x
C.gcd函数有问题
$ }% q) E6 O6 X4 c: q0 E' FD.必须通过引用的方式传递$eight_tenths对象
8 z" g# y& a, y" WE.对象的实例不能传递给方法以外的其他结构。: O& C" d2 M3 {* A- K, K4 \; ^: ?
! r% P" z' @( T( }$ \$ K: \
) ~! _/ X1 j% k/ |
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
/ M- b4 a" n' N, S, k! }# Z* FB.生成myclass的实例并调用mymethod方法( d& q: `$ X" L0 @4 H
C.产生一个语法错误
; S1 N  M" h$ p, lD.默认myclass类最后被创建出的实例并调用mymethod(); ?7 q* ~' Y8 `: ~- b5 ~
E.调用名为myclass::mymethod()的函数4 W/ J, t, y6 U. ?; r8 C( `

; c( r2 n5 \2 l+ |
3 U8 P  o; I0 N2 `. f16.PHP中有静态类变量吗?5 A3 T2 i( Z; [5 @. |

, s, k" Y9 X- |2 U. ]A.有) O& {& H* a, j
B.没有6 M  Z; k8 E9 x/ r- o' A, y

) c2 z8 t) u6 e. H
: i+ J- {6 N! o4 z" _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
* V, W" M" W# QB.2
. R$ ^' B& k  r9 E1 YC.一个错误,因为没有定义a::$myvar9 N% B* z/ Q/ i1 R$ Y
D.一个警告,因为没有定义a::$myvar7 u1 f9 u$ |7 s. s3 ~! ?
E.什么都没有
$ K' e2 p8 L. \1 @7 g4 m- P/ m! g' p8 }
3 u! f; i& A, M) Y
18.如何即时加载一个类?
  s% D9 X2 @+ u1 b9 e! ~+ ]5 x, z4 o% m" A7 H) b% [6 \/ j
A.使用__autoload魔术函数$ _# Q; k, p" V* m7 u( P  ^/ t
B.把它们定义为forward类
% m: Z% h! t' G6 s' k% A1 eC.实现一个特殊的错误处理手段$ E) J1 b" p+ s$ I9 Y6 H: o  E
D.不可能1 U5 E( K' `# }5 {; D, Q
E.用有条件限制的include来包含它们
/ o" W. ~" Y1 q) e$ O; _5 R, U1 H
8 T' G# s" T3 Y0 ?2 F% @; p+ \
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
& q, @) p" n* H7 r+ f9 k, \
; J' D0 x& M% a+ Y. e9 I    答案:__________$ q1 i7 W9 n- J8 I
8 p* `* M* R* B2 y1 z

+ P, E0 P# Z* n20.以下脚本输出什么?

  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 called8 \2 N0 i% ~! f- V
B.一个错误; g. j4 [9 z# E( g+ q
C.一个警告
) k4 d- d6 l1 O, d: N* ~' O) C! D6 wD.什么都没有5 J3 M" A- B: d+ }+ w

# [& \: I0 {% `2 b" u
7 k3 K3 |+ W/ q! }& _  }7 w1 f3 P6 ]- \2 F' Y  Z" ]. ]' s
答案速查
# i3 t( u, s9 y. i0 ~1.类
3 y1 }0 r4 D1 O2.BCD
% J( N$ ~( Y2 F3.C8 g- ~$ g+ B8 ~! E0 [* K
4.C7 T2 r6 b! b) q+ Y. }
5.A
! I. J6 @$ O' ]4 a6.C
; ~( I' v' a5 ]) o. Y7.C
. m# P; p2 P: ?8.C
$ r1 @2 a7 f3 M1 q$ ?+ Z9.D
; J7 z& O+ o7 B4 u10.B
+ q! Q" b1 f( [11.D
& o5 c$ C' a( w& f# U2 l6 s12.B
/ ~" `7 U. `2 G% b+ v13.A
! v; |; o: E8 V( l/ H14.D/ v8 r4 d" y0 a5 K
15.A6 H/ V1 F8 |" C2 S- }) q
16.B
; Q" ^5 A' i$ A! E( v; J, |17.A
$ z+ Z4 C- E- y* Y- a! i1 a8 E18.D* |$ B4 H* Q0 v  Q% Y
19.设计模式
6 e' U5 @; M* j1 d20.D
2 W( N6 w+ o9 Q$ Z2 ~- O" F1 j
4 U6 c& ~. H6 ]& n2 T
6 P0 D6 j4 s4 L$ P# L& O
& x8 o4 D. I$ }2 E; g' j2 U答案详解  S- o# |# G$ Q3 i5 a3 F' W

0 d1 c1 C8 B+ w; s8 h0 f- e- \1.类是对象的蓝图(对象是类的实例)。. p4 v/ u8 j9 \' u$ ]6 k9 j. |2 f
+ N' N1 z; Z6 S5 l$ K9 A# p1 r
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
) s+ h) k; P  P4 f' k$ _" d5 {! q% B8 Q5 [. j. i- E) j
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
3 I9 l9 X( |! U' u9 [
& [6 X  s: \% X$ K+ {4.单件模式可以限制一个类被实例化的次数。
& M# F7 J6 ~, a) \8 }
; ?6 D7 h7 S' E$ G7 g$ `; V( n5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
2 G9 y: _/ u' x# j
' `8 ~" t$ P7 k6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& H; Q/ a5 Q9 {6 w1 S& A+ R$ t: b+ ?; d( _  h
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。1 w  N" m, Z! V6 G8 M
5 C9 B& e# s" ?7 z- M
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。- ^' g* j+ l4 ^6 J+ z
/ m8 d5 y: f) @
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
. Z6 l$ S7 Q7 m4 j' M) b
, {' g0 ?$ D- H& B' h3 G) h10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
% s% G4 w1 y# P& N: `
/ n) n* @1 a1 y* e# f( v11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。9 I5 V! p8 S7 D5 o, D( s3 l& g
8 H+ I. J+ \: x$ l
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。) m  W( q6 w+ d
) p' I: E( q3 ^
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
$ b" g* |7 U. T1 ?/ V7 c; _5 D  ^8 m0 ^( ~
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。; l4 Q) Z# s/ w0 S8 L6 }
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:9 B1 j% y' Y4 _" h
    function reduce_fraction(&$fraction)) u. F% @+ |5 G9 R1 U8 D7 ]$ l+ }
答案是D。
5 V3 j4 j* ?1 H( ^6 z5 Y( r. K3 k6 G" ^( ?, @& ~
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。  J* J; _( ~* d8 N. D
2 L% ^- J7 h1 V+ W* X3 L
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。2 z! Z, i' Y  c3 R

( F! v) A7 m& T1 ?17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。+ y+ C1 x# D' `$ |
: J7 ]* k- n+ M4 a  Y# [
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
$ B4 z9 i/ {& ~2 x" ]( {1 A' E) W4 Z- `. c  h9 d2 P
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
6 R' C  }- I' ^9 q4 q' ]3 u/ q/ k2 l+ O, W0 f
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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