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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。0 I+ Q- Q6 q2 N/ w0 W$ x
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。6 U# ]) a- ]% h) H( u
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ s+ G3 ?" c7 F% k8 g2 C
# Q/ O) }% v" @: |问题
% C' P, R( p7 z" w4 z6 @0 l$ @: s* R
1.对象的蓝图是什么?
$ u2 Y2 N& a, \# A' M) M* n7 o1 p. t+ I8 n+ u3 F% E
答案:____________5 j% g& q# T4 J) `; h0 M
+ Y* k" H' N  s1 V7 N
: `" G4 `) b6 ~* e  y
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  ~  d& c3 M$ Q- _. `5 v- D
B.b
* _) M" {! q" n  I/ F5 y! A$ e! JC.a
7 T7 k/ A* Z1 FD.d+ D4 u! P# \) D  l
E.e! [7 _1 x3 P9 u% ]9 j& k$ X( P3 m& a
1 ]9 h9 V7 ?9 U, A( O. F$ t

( A) v( A3 y/ P4 c3.如何让类中的某些方法无法在类的外部被访问?; g) }% R1 H, `
3 L; V# k  s# J- E0 J6 W
A.把类声明为private
1 ^3 o+ q. h: g( CB.把方法声明为private
' ^9 m/ t# v7 H, L; T/ v5 zC.无法实现3 d0 e! x$ O5 ?+ H0 J  ]
D.编写合适的重载方法(overloading method)2 g- t, w* M' Q$ ?* s
8 A7 V) {' q' M9 o6 _- L2 P

- B) [; W, K. t  p: e+ `, K4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 E$ D, M8 _6 i1 r' Z

: u1 a. p( h, s% mA.MVC模式, f) S, f& E" ]  e3 d1 Q5 P2 z, W
B.抽象工厂模式(Abstract factory)
! s) B5 J9 U! ?8 ?& T( q8 ~& j* `9 vC.单件模式(Singleton)
8 v) M5 L+ X5 Q2 R9 o* BD.代理模式(Proxy)
# n+ t: t6 Z/ P. [4 \2 x* i& ^" zE.状态模式(State)
) Z' C$ s5 [9 R. P- f2 `+ r7 ]$ k2 F6 f( Q% u7 T

4 s' q: J! T9 Y7 a- q5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?& w, s1 Q/ i: z9 N5 G

! b7 n. x! N* u6 a) w8 JA.1个% v" p' Y7 R0 E+ `% P5 |7 H! Q
B.2个
# [. D7 i7 b5 _5 M: r, DC.取决于系统资源
1 u: q/ \) j9 QD.3个. S" N2 n9 p" v# }$ t0 |
E.想要几个有几个
" ~. B, d$ }9 _4 i" s! u# D4 I& V" k
& d1 }- f7 X* \& G/ }
% }$ _, K# e+ @% i; L6.以下脚本近似的表示了一种在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.多重继承
: k+ x# ?! x( g- L$ fB.接口
% Y" Q/ M% W* V4 q5 Q$ x) I  PC.抽象方法/ W. j6 Y! d% ?
D.Private方法
4 h# ]9 `% _; B' X. @( r5 vE.函数重载(function overloading)
1 z2 s; H2 g8 C. e" e. B$ h  T" F( b8 |. }3 g8 W1 u( ?+ Q. v7 J' G/ P

  c7 r2 E# d" Y0 b( R7.假设定义了一个testclass类,它的构造函数的函数名是什么?" g& ?" B& l, \5 b0 W/ T" R

7 P2 J/ A9 m% q6 ?# P/ j$ s; sA.__construct0 m/ M/ _! x' B) E% P8 c
B.initialize$ |1 V1 Y; u1 e9 x3 J) E8 w
C.testclass
" F! a, C& I+ D& }( XD.__testclass
4 T( l) P2 R( N+ O+ UE.只有PHP5才支持构造函数
+ j8 h2 q0 [3 a
& [" J1 _: v$ g$ [: U- c  [9 P
# m% N, d* L1 [  }4 H4 t4 q8.一个类如何覆盖默认的序列化机制?
3 {$ v; ]: U2 _
9 R4 e1 L0 \. r9 M# E" kA.使用__shutdown和__startup方法
6 E- ]  |# I0 \; k# EB.调用register_shutdown_function()函数. A4 H6 Z( D9 J5 L
C.使用__sleep()和__wakeup()方法7 c1 l+ h/ n4 C7 t& [7 ~
D.无法覆盖默认序列化机制4 e# P+ k" d$ M% f' H
E.使用ob_start()将类放入输出缓冲中
+ S& Y- U# }+ K, q# G4 r! z( v. H$ ?  E. V4 k0 T$ K

0 P/ C* H( k! ^! n. v! e* [. G9.以下哪些面向对象的概念无法在PHP4中实现?# W* @1 L( ?( J2 h! b! D; q+ g1 O
! }6 M8 y; L; b: M
@抽象类  f# C' b& J4 p
@Final类2 K% J) Q$ I  f9 |  ^
@Public、private、protected(PPP)方法
' |4 ]+ P, T% Q, \4 ?5 y/ A@接口# l1 Z3 K/ ^& O- y9 }0 k: L: ?

) C+ T8 |1 L+ a: M1 O8 X7 yA.抽象类# B1 }5 p" Y/ t, N
B.PPP方法
1 Q" M+ s; n% SC.PPP方法和接口9 q+ G2 S0 E- W5 H/ h
D.以上所有都不可用% J% k8 V# N5 c) ]( m% n6 h
E.以上所有都可用
5 u* o" l; i0 k4 e9 `' u0 X% f9 i/ J4 k6 _0 J0 Z

7 T+ n8 p' b) u) ?9 L" L10.如何在类的内部调用mymethod方法?
7 X6 D0 _9 }9 f9 [
3 ~. D, I) x1 w& V3 |. x9 u. O2 YA.$self=>mymethod();! A# S  ^* x6 S" X, H
B.$this->mymethod();
3 ?2 u: r( R' {C.$current->mymethod();
2 A) E: c, A  k. D! K& U& ?# YD.$this::mymethod()( w' v7 K8 i- O) [- {) w7 m: ]* w
E.以上都不对& K% G5 D& o4 W% l* {$ v+ O

3 O" ~- N9 I# `; S5 [# d4 j
$ s% t' `/ f+ n: D* _& ~8 R. S11.以下脚本输出什么?

  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
: U- F2 o0 _2 O  b6 KB.Null* `6 M$ J/ q# z) U: ]/ _% a6 W
C.Empty
& k. I! b1 ~3 V& S! UD.什么都没有
# J* Y5 t6 H! U" ~3 Y5 g  v/ fE.一个错误2 F' e( F) u, [" I
5 V# ?0 ~5 h# f5 n7 K

- m! ^1 a- \( l2 U0 m12.以下脚本输出什么?

  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.102 T. S/ q& b# h7 W
B.5
4 S/ N& K% Z  S9 Q8 MC.2
9 F) l+ w4 V8 z; TD.Null
2 n. m2 N9 ]3 }9 m/ y* j! pE.什么都没有
1 ^' }# I+ z& V  G7 u  W/ h0 n- M; S/ E: U* d: b  k

: L1 }; F5 S3 z# z13.以下脚本输出什么?

  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.55 A, x2 {# Q. L  D
B.10
6 e3 ]5 {4 i. ?/ j3 {C.什么都没有
9 }' F9 o" k9 v4 N' o0 sD.构造函数将报错2 w$ C  F% m) q0 G  c+ ^$ h! A' Z
E.510; d- Y" a' q1 }. {9 a$ ?' P

& j, b$ ]$ p# x- I; A9 t+ B% k% g# b/ v5 V" T- p
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函数必须返回一个值
$ |% i( X- K! X, M5 H8 MB.reduce_fraction函数必须接受一个整型值  ^# w: g0 ~3 h8 b9 O
C.gcd函数有问题
1 j4 R4 @- @  R) ~- D; `4 H4 X9 DD.必须通过引用的方式传递$eight_tenths对象
8 U: e  g' u) F: d3 ~E.对象的实例不能传递给方法以外的其他结构。
- s" Q( ]- Z/ l) a  M: q8 }$ Y2 q. m6 F; o5 I1 {
5 }& ?6 g8 a4 i/ |" w7 B! h5 H
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
/ _/ h$ p3 r/ [- b# ?) k: \B.生成myclass的实例并调用mymethod方法  M' E# ~$ x7 q! \9 V3 u
C.产生一个语法错误7 n. f  ^% A& M2 Y# H6 V! k
D.默认myclass类最后被创建出的实例并调用mymethod()& a) h( A4 h1 g6 y: Z) D9 G  I
E.调用名为myclass::mymethod()的函数& U, ]5 ?) e8 p. @/ e% x  b8 H4 W9 D; i

3 A% X6 q- A1 `  y: N7 m+ s& Y9 e, i, X+ S, H
16.PHP中有静态类变量吗?% w6 K" ?0 z, O: @) Y' N3 X5 h
7 ~9 A6 t' n  X! ?
A.有
0 Y+ j" c; a0 R% s' ]% BB.没有
8 ~7 D; R; n! \% w+ |  g5 ?: Y& x) i" I: q
' y3 _( k6 u. T
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
& p" K0 F# e3 F; A. qB.2
3 {0 Y. \" E  r+ }4 H0 a8 \C.一个错误,因为没有定义a::$myvar
: X  {! |3 ^# t' F- q% lD.一个警告,因为没有定义a::$myvar
& I* R. \1 k2 `5 GE.什么都没有' P- I) h4 g# q$ ~
, e  x5 N  o( w  q2 X5 M
2 I, `$ d- K) @7 `1 }, _
18.如何即时加载一个类?8 c: {6 l9 J* ^& V9 \0 X

/ U8 a3 Y3 {/ D( cA.使用__autoload魔术函数* W% Q' K6 }/ _% q  d: E" A
B.把它们定义为forward类6 H+ j7 I1 d* F  G& d& e4 S; O
C.实现一个特殊的错误处理手段0 J$ ?% m+ y2 k# H7 g; D9 [9 I" F
D.不可能" A" r, l1 {$ J! ?; s2 z2 M' x
E.用有条件限制的include来包含它们
% {5 j9 m# Z4 H/ J4 ?: E/ T  {) e' p- m% |

( G! j3 u  O! ]4 b2 w" G19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
. Q" X3 I; |- Z8 `! N* P
( {& R; C- k$ ]1 f! p    答案:__________+ q* a) @* Y% p$ }: a! g

  i- }$ b- t/ ^$ a. |
" O" o0 z+ d  G* {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
" j; P4 f" F' g7 h+ A  oB.一个错误$ i# Q* w! J, h4 ^1 b( w  q+ z
C.一个警告
! I5 j% N* G- d3 f# d) D' X  _. qD.什么都没有0 Q" F) w0 V2 G3 J- |0 y
  Q4 N" J) r) q2 r, @4 v4 w

% ^& Z5 L0 L( j- G2 c1 s- G" Q. h% a2 N, E' |2 s
答案速查% F0 L5 f% @: @
1.类" M' G1 ^& `0 s% q7 \! N
2.BCD
* e# m# x3 Y8 t6 u3.C
' {6 T/ e0 v: {5 \  K: Z4.C
. c* J: f/ a5 a4 Q5.A* K2 T  W/ q1 B; h/ v7 a* J
6.C
4 J; z: O3 S3 x8 S- U, ?! X7.C
  a  S- F0 Y. }& k& k; G* w6 w/ F8.C& r/ B: [* P& \6 `/ B
9.D
+ K9 [5 p8 c7 o10.B
6 @" x6 I( \4 t' Z# M11.D
: N9 f. z* f' s! q0 O4 e/ u12.B6 v7 ]. ]3 k, Z, \
13.A4 W& ?# N2 T" R3 P; D
14.D8 r. s* X. ^9 c& A$ c5 V
15.A
0 i7 U0 A3 L! C" l) E+ Z3 [* W16.B
% V! G2 `7 `6 c: r5 ?3 v17.A
$ u3 i8 g( q8 q: i" _18.D7 M! ~5 {- P8 {
19.设计模式& G/ z, o* ~  U/ E, u
20.D5 I) M5 A  t+ S! R  d% Y
% K( D& }8 _& a

4 n7 N  Z( n, s& V1 I8 I# E0 ^& M, j( o' q' P
答案详解% U+ I9 f9 s8 S8 h# ?' ^- r; }
5 U; R0 U5 p! b
1.类是对象的蓝图(对象是类的实例)。3 V: }% }0 B- F$ V& N2 d8 L

$ u  Z8 Z2 V& K6 @5 k% @2 [2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
% x8 Q% S7 W' ]0 z) ^" f) e7 G; A5 g4 J: J, x
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。/ N% ?- M# p: o) z# f

1 t5 J2 T" z3 T3 f: \2 y  u  X4.单件模式可以限制一个类被实例化的次数。, l! F+ {" l- X
# i! @" i6 p+ ~9 A
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。0 X1 X! S' r5 `$ y; f( {1 ]
9 o- I2 ^! H  g# D& K% q
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。+ R) T  u1 A( N; y. ?" n. }! L3 F
& a4 H4 I- u# I
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
. @& t8 J4 Y% e2 x( G1 w
1 |+ c. T7 T+ \0 B8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
( k: n3 x9 ^9 z% t% N- Z- B+ o
: v2 [' F8 l# d2 h$ T- p9.PHP4中没有题目选项里所列的任何一个概念。答案是D。7 J4 c5 t7 b; q. f, u

( ~5 j7 G6 y# |+ c6 U% y4 u10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
; f. C& t$ F$ H* \
  B, D2 [$ O& J11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。) W3 }. A- `" D7 \! e; C

7 J% P9 _& r8 \, j/ s12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。, k: ~% ~) i2 y( n

6 T# D! D! l2 A2 a. x13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
1 N1 D: }1 o- Y
4 S7 |; v6 r3 S14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。# i7 G. h: B1 U
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:2 P4 C& F% A" |; f! e0 m
    function reduce_fraction(&$fraction)( S$ Q, k1 o5 |$ ~9 [
答案是D。( F! X+ f0 [$ D, c- ^
) Z$ D& W/ b9 H7 _- Y
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 T8 M2 B; u9 a& ?! N/ b( j2 p: v
& p7 B; |& j8 t1 T16.没有。PHP4只允许声明静态函数变量,没有静态类变量。! R% B% ^% i1 A$ z) K6 D8 X

! F, z" b6 F6 x- Q# [0 L9 g1 `+ |17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
" ^% T/ q* t9 b7 r% {. O! n3 X  u5 P' y2 e' a
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
( s1 w6 \$ p" Y9 N# {4 N. [8 z
- n) K" a( C. m( T  V4 X6 i; m19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
  [& c; l" |% W: b( [- A/ R$ t
: A. `, U* i! }4 B* A1 T20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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