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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
5 _. ?" `' s, e/ E- oPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。$ Q8 [0 Y% ?/ D% b/ r6 n4 P. u
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
) S: X  z  ^$ r0 z4 j
9 N- j4 F- F$ C. o6 A问题0 _/ X2 l0 S# R) U' J# f

- t; B) s, _8 N: l% q6 P1.对象的蓝图是什么?
; Z( ?$ ^5 `- R* R/ Z+ l5 O. s% F! N/ e; n# B+ C+ U& M
答案:____________
( F& {% p3 g) P& U) M7 q8 r* N% j# r6 C3 P
' o* J3 k, U, t2 ^$ b( G0 w
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.c2 l8 g5 M& ~& g( G* f: P5 T
B.b
% {) E) g; d, k* _C.a. Y  i! b8 j6 K7 _: X+ Q2 u, l
D.d
6 x' F- c/ i) n8 G1 IE.e
0 g% P8 E- d8 Z- _( e, S  [, Z; p2 K
1 Z; C9 `, @( j/ Q
3.如何让类中的某些方法无法在类的外部被访问?
4 q8 a1 s6 Q0 n, ^) K( F, T1 b; k! W4 y" Y) _; g
A.把类声明为private# ]5 U* l* l9 x% c1 j
B.把方法声明为private
9 t8 p; G, T( E! r" o9 p: gC.无法实现
- Y* c/ h$ I) E/ n; s$ n3 M( ~D.编写合适的重载方法(overloading method)
$ K! Z, e; i' ]( f  M  V8 \  r1 x9 M1 v+ v- S0 f
5 [3 q6 h  M3 N/ @
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) L; E1 E5 d. h9 ^0 Z: P

/ b. c: J. f* h* {4 _A.MVC模式
1 b) z* I' Z6 C* b) C. T) k2 `5 AB.抽象工厂模式(Abstract factory), F( W% T8 l6 k- Z5 y* t
C.单件模式(Singleton): g1 }9 K5 f! v
D.代理模式(Proxy)6 @4 A( F0 z; @/ V
E.状态模式(State)
! `* I0 T7 ^% e' ?* O
. O4 v. s+ A, Y+ P8 s
5 M, ~- t6 x, W. B/ v3 l5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?3 `3 I4 D% {& a* U3 ?2 `

" E$ P1 M# J1 UA.1个* u& a+ I2 ?; d2 Z7 O+ Z" [, k
B.2个
2 C9 S* a3 A. IC.取决于系统资源
7 H/ v  v. A  G: i7 ^/ T3 S# Y6 N0 |D.3个
( ^! M0 t5 e* ^; l% Q' a1 {! |E.想要几个有几个
( j6 I( f& N1 x- N% T8 ]* m/ M0 E/ k: I% `9 g

2 ?  O' g3 L" u- q6.以下脚本近似的表示了一种在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.多重继承
9 S4 j5 n2 h. A2 B3 U8 pB.接口, y% ]: X  \8 c) E! J# D
C.抽象方法. I0 ^5 S6 b: h1 A$ T
D.Private方法
( D3 B5 ~7 D6 c) I# N6 A1 A# ]E.函数重载(function overloading)
2 o9 j# C  ?$ [" [, X% h1 m" H8 C/ k0 x
4 F0 o  [- O8 W1 w1 k
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
' Y' i5 p+ @% d: `% ^9 n
: v% A% `/ I& E5 q$ WA.__construct
$ V2 D' F& t! D, {' y! n7 YB.initialize
  ]! Q) M. g0 \) ^( kC.testclass
0 \/ H8 u0 w- ~/ V/ ~) nD.__testclass
. ?; x2 Z  `$ x' aE.只有PHP5才支持构造函数
( x. c& e' W6 k5 N
7 m! u! q$ b, Y$ b9 T- t- a, l1 A) ]  V
8.一个类如何覆盖默认的序列化机制?  M* c  C; S6 N4 Y+ S7 {

  g/ p5 O7 I% O& B/ rA.使用__shutdown和__startup方法4 n$ S1 m; q8 ]+ v# n8 k% z
B.调用register_shutdown_function()函数
' q( F; ?; ~# A3 U1 {C.使用__sleep()和__wakeup()方法
, E, O, ?1 X" P5 p$ h8 gD.无法覆盖默认序列化机制
, ~; o. S2 o7 Q4 M) E' X* ^! `; wE.使用ob_start()将类放入输出缓冲中
' ^& s1 g3 X5 ^3 E% L
- i- }8 [7 u' t5 j* ?: [. y7 l9 Z( `/ }% D
9.以下哪些面向对象的概念无法在PHP4中实现?) z( J& p- H4 h  }) a& u- ^, `
' O' P: f' }7 `& E% g
@抽象类( n' h% D6 o8 T0 q1 `5 }2 H5 ]
@Final类0 W0 k* _' ^7 s' ?& N8 Q# M
@Public、private、protected(PPP)方法8 C5 l( |, H5 H
@接口; o4 {4 \8 S8 V) L

4 ?$ @6 _3 D5 d) ~A.抽象类* i$ k' f- e* P4 M7 k- W& Y
B.PPP方法9 L! ]5 m3 s1 T# G, p" f5 X7 {
C.PPP方法和接口* L1 `' y: q- y. G
D.以上所有都不可用
, o. _* V' C' p0 vE.以上所有都可用5 b" |+ E/ |) O7 Y
/ W" f: e! h5 E+ c5 E: y- |  y" k

3 \$ r! E7 X4 |0 D' h* j10.如何在类的内部调用mymethod方法?- y$ y/ K+ W9 C/ |- Q6 R

, V5 s/ E6 [2 n, f. lA.$self=>mymethod();( z. j7 d  `) I* `1 E" Y5 G( K
B.$this->mymethod();
' Q$ a" @. v* h! G: MC.$current->mymethod();! g  k6 c' B5 _/ T2 q: P: f
D.$this::mymethod()
# l9 t  Y6 p0 q$ Y8 m3 `E.以上都不对+ q$ k, |1 f2 x4 l/ Z8 y; \

$ s& j3 W. @6 `& P1 f3 {% }& r/ c. v8 m0 w
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
3 K7 k0 A" Y: Q/ a0 PB.Null3 U/ q5 S% x4 C1 w% P
C.Empty
8 l5 T7 t; m3 Q  m3 B$ gD.什么都没有( c7 S. Y% ~- S& s% R: M  B
E.一个错误; s- \( l) L: [2 t8 a

4 Q1 _/ F- d& W& T9 A
9 I+ \, U" I' B9 p1 t- A: z( l12.以下脚本输出什么?

  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
5 n' {5 V3 n' ]$ ?9 UB.5
7 P& W# v: F9 L0 Q5 Z* }C.25 u; A2 V5 ?& C( u
D.Null
" H8 J% D) J' Q8 L3 E6 ~E.什么都没有
/ Q8 ]" H- W0 C+ z# Y2 [; I( ?( `- O+ R* C9 |8 y
: K  ~9 J$ k" N
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) w+ E: q9 O% s4 {# ^' A  h" z
B.107 o8 s; h7 M% J
C.什么都没有2 u* v! W! Z3 Y/ p$ n* K4 s
D.构造函数将报错0 P0 F" \  x9 _) c* s: ]
E.510  O. o- `( w+ d6 x7 M

  H8 ^" e7 l3 F
1 r6 f, \  v0 a0 U; U14.考虑如下一段代码,执行时,$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+ U/ A/ p: }B.reduce_fraction函数必须接受一个整型值  a# ]  ]" z0 _' v0 i: |  G
C.gcd函数有问题
/ B' D/ w6 u2 s1 zD.必须通过引用的方式传递$eight_tenths对象2 O, I6 s. n! c, S0 B: s
E.对象的实例不能传递给方法以外的其他结构。
$ b$ p4 p' G8 `# H
* A# ]+ W7 U8 J  |: Y0 X. K1 V/ _3 u8 T3 ~9 O8 ~$ I9 o, B* N$ E
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
4 q( C' l# [# `& @) H$ BB.生成myclass的实例并调用mymethod方法# D) |% Q. w* o* }! E* p
C.产生一个语法错误
5 F% [/ i5 I+ `5 p& o5 ~D.默认myclass类最后被创建出的实例并调用mymethod()
' ?/ H, x8 a+ R# y2 {/ \5 m& [E.调用名为myclass::mymethod()的函数! }3 k9 M# S( L) Y; h

' v4 Q" m( y  L- c: f1 v& m
0 e6 g2 U6 Z% k2 n( j" L) U16.PHP中有静态类变量吗?
6 }; f6 D. n$ E) N! D0 h9 v6 P, L: P4 B6 t8 P
A.有5 }4 r$ {) X7 o9 w/ ]
B.没有* X( Z* i2 A9 K9 U( Z' L
0 N. `6 y8 l8 i7 u: t/ k! ?
+ Y9 u* [7 ?( f, x( t* P
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/ W  m# f! F( Y2 l7 F- }
B.2
7 ]' |/ d( e8 Q, ~. w7 Z- DC.一个错误,因为没有定义a::$myvar8 ~0 C6 x* O4 |
D.一个警告,因为没有定义a::$myvar
; u9 W3 r& {$ }4 m) |$ I: |( e" \7 ]E.什么都没有+ ~+ @; {/ ]# h( D8 `

2 N" H* ?" o7 t- w% P+ K$ y) T& w% L  S/ s7 ]" t+ z5 H6 d
18.如何即时加载一个类?
& `1 G2 M0 w/ {$ Q7 Z: u7 o1 e) A( T6 {  }  R  s; C  u
A.使用__autoload魔术函数
5 ~0 H4 u) d( c7 _  tB.把它们定义为forward类
. M5 B1 O* e" E& `% \) z( @C.实现一个特殊的错误处理手段
1 Y: n" U0 h% e" F6 e- tD.不可能* I9 `! f. G" f+ w! f. }
E.用有条件限制的include来包含它们$ B5 k, ?1 ]! Q: Y2 ~% m. q
! b- x% K, X# [  l' C  n" h

* w) D3 p2 h7 S2 z" J0 n19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
, ]0 |: ]3 p; b' ~) G1 f; z! ]6 G7 \6 K# y
    答案:__________
" J" ]$ H# D) k) K9 h# g. K2 Y% u+ C/ \. `9 _% d# T3 P; r

# i1 V2 I: x2 X1 D  X$ d, i20.以下脚本输出什么?

  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
$ g% z* R8 x, CB.一个错误: }# r! U! c  @, T
C.一个警告
5 g! Y4 e1 Q0 ]  ?. _D.什么都没有3 ?4 G& ?8 i+ v" q$ c) \

" Y% j5 N1 N. Q7 E9 N2 L$ n4 Y3 `2 S

( X" J8 h. E7 o+ k答案速查
0 \3 m  N! p! m; L+ s1.类
. d: R' X" ~* L3 K2.BCD, W# `5 {5 E( @" m
3.C2 h. q5 D6 t5 L( m  w0 D' u
4.C0 x- Z- g5 {& z
5.A
2 G, `0 l2 |0 d: E1 ]6.C
" o+ ]5 u" Q3 ]0 @$ I7.C
3 N! i( @$ w) _6 k5 C4 q, s6 r8.C5 [) M" [" t8 y, t- A6 W: H/ @, O
9.D
) R6 Q# Q5 s' I5 X+ V: Z10.B* Y# a  v  G% ^( ?" t
11.D+ r! x  l) _/ r
12.B
! |# ~- \! A! m& k' L* y5 z! f/ y- M5 h13.A
7 }6 U  h0 @% Y* Q14.D8 |# k# j8 w4 `
15.A
2 l; F* Y) R( }0 _16.B
  M: q8 d5 G3 P- e4 ?17.A
4 ?! }8 A: S/ {/ {5 d8 O; n- u18.D
  V9 `/ J' f4 x' @. {4 Z19.设计模式
8 T2 s0 o) @6 W7 p5 f1 c0 M20.D
* U9 E7 f3 q5 M4 \# d! Y+ A# i4 h
* J$ t' o; `+ E1 `$ d
$ U9 \5 H$ _4 K: m5 ~3 A# T3 t) Q
0 @) J3 I; q5 Y# M; S答案详解  \' F. q% d% q$ W, x/ v) M

3 P- u/ A7 M; H1.类是对象的蓝图(对象是类的实例)。
) R% G0 Z4 F% R* ~9 S$ H% e
. O8 T  Z/ p& Q2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。4 J3 M0 w8 L; o3 c3 u5 q

6 b9 B$ p3 B8 l# O2 l3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。7 @8 |  y1 D* h

1 A. @* `' l9 T: E0 l4.单件模式可以限制一个类被实例化的次数。
- U' [" \3 o) j; N" ~
1 W' i8 W3 j0 C- {- B$ r5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
$ @% L  S+ q' V! n( o  m  \5 ]) c, ^+ x" w& ^% W; f; V) l% G
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。) A( o, j) |! K1 K# q
& R0 O" T! _- x2 U/ I( [/ h
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% k4 p- P/ u* ~, g) x
/ m: E; A8 t. \  T4 a
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
. ^# n7 d* p$ r- l' n* Y( E+ ?; B! r0 t" ], q
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。7 P2 f3 m. Z3 c! H% M; y' F! M$ E

: `  X# u' A- R& A  A( S4 N& `- y: P10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
4 |, ^' E; M: a, w
& D+ `+ _7 r2 j  t* ~1 K2 m( b11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。8 b. q9 {  g7 X
/ m: E6 t" t$ R4 z) T6 v
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
9 |5 I9 J" P0 {4 }7 N* ?) C5 C4 O& F* G
8 W5 Y+ n3 K- m# W13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
+ e. s8 }7 v/ h
4 w! w9 p* c9 ?# T14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。; A  C8 U6 [2 U! v
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
* ], I6 W+ f0 y4 F6 o    function reduce_fraction(&$fraction)
9 r; m5 W. |0 \答案是D。4 o4 S. ^# @* i6 I* C9 I

0 ^. d) g$ c& _) s) c8 J15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。% q0 ]5 A$ z3 i* X( b( D
  _; `% L% X9 |' z3 h
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。: }1 R1 F" H0 }( u
5 D+ p2 e1 [5 n! f+ R6 y2 d
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。& l: Z7 b- z1 I5 O) r
8 {$ \' V- s2 Y& Y# e# r, q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 z6 j: m$ L" M5 z
0 H: h$ l- _$ ?! v19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。' N: L% E, {& S2 m8 y% Q# D7 L
+ _2 u4 `! ^# E9 d: j5 a. V; \6 H
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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