返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。7 N2 r6 j; }# ?6 ^
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
- Q1 N  d2 I" s& s( O& V) h% p本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
. o8 p; V& o+ E0 Z
) P# {: L9 M, t9 S0 g问题2 N% u$ |/ i6 b: o; h6 @4 m- B

  R9 `6 F- K% i6 c4 ^1.对象的蓝图是什么?
* r- a" N1 O4 ]' o: g: S4 l: x( i1 G" R# d
答案:____________
) ]( \7 l  K; O  [$ y! C" k! q2 i' ~$ u. y
; V( x; n7 s7 b6 z5 x3 Z5 X; H
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
; e4 i( {' A9 P* g, V) C" fB.b: ^' f# \! W8 D
C.a/ O6 ^% S# `) {- o
D.d& }, _7 c; r: ~6 G2 Y4 h9 A
E.e
8 x4 I5 l5 s# m0 T5 Q5 n9 B
0 }, X* H5 Q$ l) t1 L4 [3 m1 g- I1 w, D# B, T
3.如何让类中的某些方法无法在类的外部被访问?
. ^& S( e2 y( ~3 e  @! f  S, r# Q' J& C7 s) [1 l
A.把类声明为private( g5 r/ s# K. B1 G  z
B.把方法声明为private- O8 L. b7 s8 J( \& Y
C.无法实现7 Z5 f; s+ V" h! ?' l
D.编写合适的重载方法(overloading method)3 [! [$ s! s6 d7 e/ J
. Z4 _, o! S) \9 k8 F

5 a0 r+ t+ s. Q; ]. S1 h4.哪种OOP设计模式能让类在整个脚本里只实例化一次?8 N3 `) b; v( e: ?

1 |4 L  e7 E- e$ u, ZA.MVC模式$ Q" J- s+ `4 O# F! b' {1 Z
B.抽象工厂模式(Abstract factory)" i3 R- a, ]8 L: l+ ^7 v
C.单件模式(Singleton)1 ]0 D' @& G4 ]! B0 ^
D.代理模式(Proxy)
- I! f+ p) p! b6 S0 xE.状态模式(State)
) V2 O+ b. }5 A3 N& U4 Y; [9 ?. @( Y" r( N

3 P) w1 s# a9 @+ P5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?0 ?, w. o4 _$ U! F4 B, `) L
/ M' l2 w" x& m, u( X
A.1个
# |% H4 W+ F3 \6 d- G+ C5 n" ?B.2个
* s! [6 F2 ?' _+ o6 g6 v, ^C.取决于系统资源
$ ^* j% M+ {2 e  d5 w: }D.3个
) g* }" Y% e- G/ J8 B6 Q- H$ dE.想要几个有几个+ q6 t* Y* B) e5 ?

* ?0 h1 B# p' `3 I* @
- a$ ~# ~% b* C0 P/ }6 v( t" n6.以下脚本近似的表示了一种在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.多重继承4 o) y9 D% `: l  b/ u% O
B.接口
* m- X) W. {2 D8 k- S6 Z  M( rC.抽象方法
( s* [7 v* w8 b& ^1 bD.Private方法
# }0 i2 H* E/ a' v" X' n: i8 AE.函数重载(function overloading)
# A& P4 n! ^( t7 z9 I  {$ I0 r* @; C3 k! M* e% j8 b
8 W2 [( j) N8 ^% k
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
! ?5 X4 a# A. W. J5 k* j' W. I4 r8 \) s7 G4 [: ]: j. a
A.__construct
9 U/ H0 t) B# p- C5 HB.initialize1 t! B# P; e$ f3 R$ T  r. B
C.testclass0 E& R* `3 ?1 l4 ^
D.__testclass
' a8 I/ T4 ^, U+ q; _- aE.只有PHP5才支持构造函数
; n4 J2 G  K8 Z1 s+ F. ^5 O
2 f% e0 ~/ D+ C7 a2 J6 \) F% a; J# G3 L. y4 Y6 t
8.一个类如何覆盖默认的序列化机制?- A- N. J7 u# T8 F

& p4 ^5 Z) |8 e, _9 x3 JA.使用__shutdown和__startup方法
& V, w% [$ A' U2 w! h3 l/ SB.调用register_shutdown_function()函数
2 ^7 N  ^- p0 v" L7 E6 {C.使用__sleep()和__wakeup()方法
+ Q: m4 D5 f7 T7 z7 t% KD.无法覆盖默认序列化机制" J; _  D% D2 v& Q& r! V4 q+ r$ s
E.使用ob_start()将类放入输出缓冲中' X1 B/ s, v; t+ u8 L: `3 C

& w4 {( L# n$ w2 g3 s
" x- u& Z8 d3 {8 A5 ^& O/ h9.以下哪些面向对象的概念无法在PHP4中实现?
- Y2 n& d' ?, O/ w
+ R1 Q9 H# H0 b- g" W5 l2 `@抽象类0 l4 D0 r4 m8 |& b0 a
@Final类- o- m( Z) q  D& q
@Public、private、protected(PPP)方法  C, O' O9 c8 q0 a% c3 {4 f! c; T
@接口
8 T( v* c; S! V# x: n  ^: I( ^$ T: F+ A" i& J) y
A.抽象类2 S' X5 o) ~3 t( D
B.PPP方法" y- g; x1 f4 \! t1 l" x6 a
C.PPP方法和接口/ N  v: P5 F) C) B
D.以上所有都不可用
1 F. b( N1 G% g4 p# s1 J) [E.以上所有都可用9 v5 l+ ^& k% l- u; W% J
  I2 @0 a7 o  a) O
1 d( r5 r' j8 E1 S0 D4 N
10.如何在类的内部调用mymethod方法?6 E+ I! u( G5 [) u  D- W8 P/ E" M; j

! r; A5 U7 m3 G' kA.$self=>mymethod();2 `4 i# i8 N  l( V4 ]
B.$this->mymethod();3 }( `' G% M8 d- p8 E/ ?1 M: H
C.$current->mymethod();6 F& Y% Z9 \5 C  Y8 }, R7 v  N
D.$this::mymethod(), `0 K- B, \4 S# ]8 y
E.以上都不对
0 r$ m3 ?! c! q& G+ z7 ~2 U6 i- |- _$ G7 J/ v1 z( a
$ L  M3 f- t2 J2 m
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- a# c) L9 h: q- s' e
B.Null" r% L1 o+ l" a5 x3 P! v2 ~
C.Empty
9 j7 L3 \0 {1 L3 R$ `D.什么都没有
: j/ L% h5 Z* d. }. G  g; QE.一个错误
0 [9 ~, E8 ^! r  H! r/ p: k! U! w) b# K2 a' M
5 w9 Z8 b: ~0 p( T2 s! n5 |
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
4 Z6 E. ]* J  ~/ _8 hB.55 q# y0 @5 X$ U, f% z
C.2& e1 X! s' L) i5 Y
D.Null4 ]  H& p" y6 {/ a
E.什么都没有
7 P- _( ^- m4 ?- Q
) W% R' |' v! D8 g
" \4 l5 W  Y0 g$ V/ C13.以下脚本输出什么?

  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+ |8 r0 W" e6 B5 M8 R2 zB.10
( U4 I' K! `( j- [8 d( b5 wC.什么都没有# Q: U! B6 D, D$ |  c. U
D.构造函数将报错3 Z/ M! c- A8 r. {, q2 K  Z
E.510
. L# b1 a1 A2 V5 j& N& J
/ ~7 Q5 v, r3 [' d( p5 G1 X$ r9 l2 u) B2 S& A
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函数必须返回一个值/ o& T- m* R$ E1 ~5 n( U) Z
B.reduce_fraction函数必须接受一个整型值
: y# p9 D& U+ j7 A+ \C.gcd函数有问题. c% ]- T. G+ v. C+ {
D.必须通过引用的方式传递$eight_tenths对象
6 j! o0 y7 P# y0 z$ M& vE.对象的实例不能传递给方法以外的其他结构。3 E. ?1 I) `, K
3 s# M  H7 J. C+ L' r
4 a" \8 Y1 F& K) q  s' j
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
$ p6 J% K, f7 m" E! E$ J4 HB.生成myclass的实例并调用mymethod方法
# A" l. h: a0 e( v; L! e) m& v( dC.产生一个语法错误0 G5 V$ c' n; O6 ~% X4 w* i% d
D.默认myclass类最后被创建出的实例并调用mymethod()
1 v% Y, `5 \) K" A$ ?E.调用名为myclass::mymethod()的函数
5 k4 u4 F9 u- C/ V1 y; t1 {! U
6 P2 P6 h- D6 t' U* U9 C8 X! F4 H( F7 T
16.PHP中有静态类变量吗?- m4 F/ h3 o- l8 }& J% E0 h

7 N4 M& K) ]0 U: m1 r% L6 l+ o" BA.有$ A. f+ Z. J7 _
B.没有
' z9 R7 q) M4 D/ Z: \" s) x! f1 l0 Y/ d$ C* a. W9 [: P

; u4 b# G0 ?+ _; C8 D: p17.以下脚本输出什么?

  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
  W) s; G6 W+ `9 ~B.2
4 C8 Z0 B. F' o* CC.一个错误,因为没有定义a::$myvar* J; u! [$ d/ A5 |" L$ ^$ u
D.一个警告,因为没有定义a::$myvar
* ]  i# z0 y  [E.什么都没有
6 d1 U4 A  Y$ Z- K' X0 J' i" x3 K" ?) T& P6 d

0 ^/ T& P/ U7 g# p2 v; h3 S. F18.如何即时加载一个类?
& l# F; w) U/ o& J5 z: A! u* R0 k! S5 M! @  B0 ?  E0 E3 `
A.使用__autoload魔术函数& v0 \. B) V% ^# i
B.把它们定义为forward类! Z6 j2 b2 O0 O0 s3 ?# i
C.实现一个特殊的错误处理手段% X8 h% y1 V/ H
D.不可能1 D, k6 c3 x( t# n# d' [8 [, r
E.用有条件限制的include来包含它们# j; W8 Z4 N9 X: ]

: E' I* [: ~6 J9 X
# g( g! z% l* q; O: \19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
, V0 ]" V' P5 F7 Q; ~' q+ R9 g) S7 @' ^
    答案:__________% r% S0 r; h; }3 u$ Q

* z" H- d# S+ K3 j! ^
) X* i0 Y2 K0 ]' F/ \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
& z: C* h% n: ?( L( ~1 ]' i' [1 ~- OB.一个错误0 P4 B* R/ Z( c$ ]( |0 [
C.一个警告) k: h; O& G$ `& c, z3 H$ H8 c
D.什么都没有
* R9 D. D! U  v) v( ]# c1 w0 s% H1 F; `

; s1 z  n, Z. B/ h8 G  _( j. d& H
& S+ U9 d! ]4 j答案速查
" S( u# _& b9 l  t$ W$ @6 M& U1.类) g& d" E0 o/ V5 f5 h
2.BCD* x6 p, i1 w2 H) n/ q) e
3.C7 _& J' `6 [* A8 n
4.C
3 Q6 r' f8 k/ A0 x! g- ^9 Q5.A
2 ~$ E1 I' S$ B+ r: {- G0 V6.C% n8 \1 C3 H/ Z7 S) K) E* p( G
7.C
" J# {9 ~; K9 y0 O0 X1 d3 x8.C" A4 m, [" A9 {' W% J/ t2 {
9.D
: Q# Z( O" {% i1 D10.B* N! g$ ^" G/ d% D
11.D! p" {: M* a( r7 R* D( ^; k
12.B
, U& i! g* O  J8 U: i6 G/ Y13.A, V: |- W8 e7 n9 }4 R
14.D
5 r# K7 J0 @% F15.A
8 g# N8 y* n& G: O5 `; Y: Y* g  q16.B( x/ [1 j; h+ y
17.A: `7 ]. x9 k' ~4 ?
18.D
) l8 U) |) j8 R. Y, P% |7 |  i19.设计模式# l+ E9 G4 t( g# b, a
20.D" W/ n1 n7 R* |8 ?7 P' w) I7 P
2 B  X0 [( Z( t2 I5 H4 {

; C$ b  T" @7 L$ K1 h7 u8 P$ }" r1 B, X, a5 o( E
答案详解
+ W7 `7 M8 X. U# a2 n- h! n3 w- n# P' e* k
1.类是对象的蓝图(对象是类的实例)。
- V0 p  l9 {3 G4 ~; M4 l6 l
$ e* @3 f/ ~8 n2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。+ u8 r% W5 ?* N. e( z

( I4 d6 f( Z0 y7 }& s, w% O3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。& b  X+ u0 u- s5 B& |1 J4 K
4 j) l- c- n% y! y. r& {! v$ m: ?
4.单件模式可以限制一个类被实例化的次数。# h4 e2 y: t4 J+ {
' K3 L" b7 P7 x5 g* d3 Z3 C
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。! {) r8 g; \' c4 A$ J4 p. P
3 B; z2 t, q$ q, P7 T( U' F: G
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。" U+ H% z- b; a2 Y3 \& A

5 |6 _" R7 c- e+ \7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。$ ^. o3 Z+ u6 b! i4 x
3 h) c9 n. G. t9 h7 q* |; r/ U
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
& g% y" R& C( D7 U) J" V% Z& {2 ^% q/ S# X( |; \7 w. Y
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。4 l; u% V' E8 |' i( E& S" B
9 P4 p. Z0 N& C# W' c8 E
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。- V  @, A3 K0 j7 S, W- h% p

0 N6 L  N. a# M( B, X11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
. @) X* D; z5 g" _! W8 H, W1 R: d# n) a8 E! j# s
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
% H/ E# B% k, P3 C- r1 N# d5 U7 H" u
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
+ |( t9 q" }9 ~0 Z0 C: C' c& Y) x2 ~" v) E3 Z2 B+ w, D: N
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。( z7 g: S, y& [2 _
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
9 T7 m% E& A9 }1 l8 `- E+ s4 x    function reduce_fraction(&$fraction)
* D( D2 U. t; U# A答案是D。
: A/ i" \6 A7 Y; `5 j4 e  [7 ?3 S# c) ]
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
$ m$ h$ u' s$ K# N7 p# p# H& q3 Q5 @) i& C9 e8 h
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。! _7 V- s, g! ?/ U9 }. U. l( A
6 }7 p- m" t0 u4 y
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。! L2 [% y8 c1 G" x: C& V' N
) n, W0 }1 i2 v4 w& L) p
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。$ X5 Y; I( D( O0 t
/ K: G! ~7 T' R# b1 {
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。2 V& N6 `& |$ A( x' }, y% j

+ R  a, F& f$ c& c; y+ y20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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