返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。9 `. k8 D7 G$ n( E
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。! q. O' \; I8 i2 u, w
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
2 B& H9 n! I. Z; j. W7 N, k+ w7 y  n, u) J! S: ~* _0 t
问题7 q! G- O) J+ B9 j& a: ]
7 @' t! X- @2 {: Q) f! P9 T- H
1.对象的蓝图是什么?
3 H( C. L/ ]& P
2 s( W" e/ ?9 m答案:____________
  S" y; F' b7 A, F+ t2 Q& d( }7 L

% H6 V6 X* W4 s! U" `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  U5 B$ O3 {# B  w0 l/ C
B.b
$ ~# s, T- O; @) Z' mC.a! ?( m9 i, @8 v: X' g) G
D.d( G2 {+ G* w- n
E.e
% c( M/ Z. `6 i0 W$ `
) K# w0 e  ]# k( E$ m
! e1 p( c; Z; y3.如何让类中的某些方法无法在类的外部被访问?
% w1 @/ z8 g$ o5 m7 e( N
& K+ x' Y( h9 S, P5 k" }' RA.把类声明为private
, e# ?  y$ }5 z- @4 G& RB.把方法声明为private& t. O8 R& H, Z9 [$ d- @: J+ T
C.无法实现$ s7 L, r+ `9 i
D.编写合适的重载方法(overloading method)+ }' q: X4 h0 l# O2 E4 n. T% u0 f
1 E, _5 X) a: x9 t1 o  L( x4 [

. I4 v! [/ N6 }# @* m4.哪种OOP设计模式能让类在整个脚本里只实例化一次?. S1 F( V0 t& {9 K/ E+ s
( [$ ]. B0 B3 d/ |5 R
A.MVC模式( D! e8 I4 t* Y
B.抽象工厂模式(Abstract factory)
; }2 G: {/ Y2 M* P$ z2 WC.单件模式(Singleton)
( \. p; v% F2 M1 k7 {% TD.代理模式(Proxy)6 O- l8 W% S* |# M' c6 T
E.状态模式(State). m1 G2 v) P) ]5 A+ H
+ w. n" D6 h% |  ~7 N
/ W- ?- P  e5 c* C
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
8 v) p2 _3 ?( D) p$ o* ^' b7 Y: [8 w) \- c
A.1个0 }& i' z8 h! k) {9 r7 m9 V
B.2个/ \$ F: ]7 V! i; V' q3 Z* v
C.取决于系统资源
+ a, f$ o$ z# O+ g' t+ a4 iD.3个
; r9 `$ u$ U0 F) u. lE.想要几个有几个+ `! R' E: J. Y$ `! c( ?; a4 z
+ j( ?6 n5 _* u* D  h
5 K+ n# C6 w% [5 [1 f
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.多重继承
  N& b" G# X9 l  |: M8 FB.接口% D5 g, M; j$ i0 \" C2 {0 b
C.抽象方法
! ^% ^8 _2 [8 E( j' XD.Private方法  y* X& k  Z* Z
E.函数重载(function overloading)
$ c; R& K( ~8 ~. X6 S
6 E+ G9 F3 \/ F+ C% `3 a/ t3 G* e5 r4 n! U7 a8 O' P
7.假设定义了一个testclass类,它的构造函数的函数名是什么?5 m! _5 r& v- r( G+ ]. P

. _+ G* ]5 F+ N" t  E' `/ qA.__construct3 B4 G+ U+ m) h/ k- C& C1 G; S8 h
B.initialize
2 n6 K# V+ Q: k6 w% y1 DC.testclass
) e& b8 b; k( l5 J* xD.__testclass
3 A1 {- f* }* O# ?E.只有PHP5才支持构造函数
! H/ Z' T& D' N2 m1 c5 n% W! X, w0 A% H) O6 v+ _" n

8 j# w; j* I8 g9 D/ s) U( h: X8.一个类如何覆盖默认的序列化机制?
) B0 ^" r8 `% }+ y- T: x; u9 f
. v/ ^% K1 {$ x. ?  s4 h* qA.使用__shutdown和__startup方法. o+ C/ v1 z, Z0 Z
B.调用register_shutdown_function()函数
; _6 Q1 I% ^0 LC.使用__sleep()和__wakeup()方法0 C% [6 ]  ]9 Z" Z9 |+ J$ z
D.无法覆盖默认序列化机制1 y2 c; L/ m! W# |* E
E.使用ob_start()将类放入输出缓冲中- \! L0 h$ y& u# n' c" N
' @( \0 x* N/ N8 Z
% c8 h( o9 l1 b5 g3 Y' c7 a
9.以下哪些面向对象的概念无法在PHP4中实现?
( [, f" X' c: y
3 k" e$ b! c1 X3 L9 w1 Q5 u@抽象类
; k0 ~% L- A' G: }6 b( }  _( H& S" R% y@Final类
/ q; p  ?8 s7 O3 s) u4 m@Public、private、protected(PPP)方法
# E3 G4 V1 w+ Z% L/ l@接口
1 P# w  t, ~, U+ o4 V4 H( r. \7 ]! }# E4 n& z
A.抽象类: J# _- O2 Z- A. M5 v
B.PPP方法
. X! ~& t4 B  n0 t) d' rC.PPP方法和接口/ X9 a$ ]/ a8 [# Y4 u
D.以上所有都不可用" ]+ h5 T) V  A" X! T1 h
E.以上所有都可用/ p9 [, f1 ]* O$ P3 W/ q$ ?

# b, M; l1 \: Z( ^6 K$ T
: y6 z. u/ N- w; V- |  H  W, r10.如何在类的内部调用mymethod方法?
3 Y4 i8 ~/ Q( K6 X- N- [$ M# E* ~0 d; t
A.$self=>mymethod();  W: K  v8 ]& b2 @3 d" v/ l
B.$this->mymethod();- j7 R- ?) Q. a. G1 N4 J" t
C.$current->mymethod();% w" s, y+ R, e0 y0 y
D.$this::mymethod()9 X/ l  Y2 f! f2 E# M( i0 c
E.以上都不对. \/ ^& f% ^4 f! |. r; C
( o; [( D/ x8 ?! y9 t; y; S+ Q" O
5 ~# f6 a! m- O. ^/ L# L8 B7 ~
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
2 ^5 W' S% P/ D8 V1 X8 E% IB.Null# N& Y0 J; e1 |9 h: R
C.Empty5 u9 |7 d$ m4 n" ^
D.什么都没有( O& d. ^, f2 L5 A" d) S
E.一个错误  G$ s3 Q6 s9 |7 C
$ y& `3 c% O& y1 f/ M
1 R1 e" D$ m4 P/ i4 N% b
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" g/ ~6 {5 r/ H  i
B.5
2 ]- r6 v3 H: m9 k0 iC.26 X+ }' l+ w9 c( S3 \, E
D.Null
/ [3 x/ O, s$ }/ e: t4 XE.什么都没有) p. `* Q4 C9 h2 A  D- a$ n

/ \# g0 [5 W3 w$ L
7 }2 F/ O& O1 y* p" @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.50 {1 R2 E/ h' I; ]9 r, g+ h& g7 l9 ^
B.10
8 I1 z: T0 c; t$ ]C.什么都没有
2 }7 r! `  H+ C. e6 S4 w, yD.构造函数将报错
! n1 a1 i: J" ^% E, aE.510/ m6 `2 ?* S  W% Q
/ A% @' T  h& V+ g+ W# z
6 U! W; |/ r6 j2 }, J
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函数必须返回一个值1 I% N% J8 {, |5 i2 G) l
B.reduce_fraction函数必须接受一个整型值% f" @- x0 z2 |$ P) ~+ D* L% g' L
C.gcd函数有问题
0 O" h  k3 V. ], F! XD.必须通过引用的方式传递$eight_tenths对象4 c9 h. @" w4 o( L6 g1 J# s
E.对象的实例不能传递给方法以外的其他结构。( Y0 m; v7 b# |# v, G; [1 D

7 G; `7 d) @* a" ?
; c9 x& e8 x: x3 \& {- b15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
$ D4 S4 ]/ A; D  tB.生成myclass的实例并调用mymethod方法
4 l: H3 Q' j1 I! ?8 a' MC.产生一个语法错误
) @7 W3 w' e% X4 GD.默认myclass类最后被创建出的实例并调用mymethod()" I* ]. w; _# O7 w' D
E.调用名为myclass::mymethod()的函数
  g/ E# s+ Z7 J; C% k
" ]. i! g2 p; l3 n  ^% x) p$ V2 l# H0 D, z0 v* [" ?
16.PHP中有静态类变量吗?
9 v+ B/ K1 z/ N2 j/ G/ c( z4 u3 ^6 _) d- A
A.有
# ?. s$ `$ o  d4 F$ d- R7 RB.没有
3 ]9 g4 z9 q! w- C/ z' O
- E0 s; ]6 x& _, o9 Y9 x; a
0 E) j  o- c) j- u; e) D& y17.以下脚本输出什么?

  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& C) u" }1 {  ^7 U1 P
B.2& W+ I9 F5 t, X$ _# ~5 v
C.一个错误,因为没有定义a::$myvar; x' u' y7 Z# Y5 G* _* b/ r) @
D.一个警告,因为没有定义a::$myvar. j+ \3 m* }* d  M
E.什么都没有
! b8 S! P- |; L" Q" Y* u+ W2 Z% x

: e3 O2 t4 b" r- Z* V, A18.如何即时加载一个类?
1 S- ?5 ^" P1 _/ g! j* @2 ^
* a1 w, X; m2 YA.使用__autoload魔术函数8 E: S% w" a  M+ t
B.把它们定义为forward类! V& J9 W% H* S1 z4 e! I
C.实现一个特殊的错误处理手段
: ~# q1 Y2 W4 aD.不可能- U- s5 s. }. J
E.用有条件限制的include来包含它们
& b' K- |- n$ q; e4 V8 c' P3 u$ E# h! Q  f4 u* A
4 \# I9 T6 C  K9 o: S+ k  T3 H
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?$ {* A$ b2 i3 W  {, b0 e, e2 t
8 x. M) e3 ]! X, B  W$ q8 ]
    答案:__________6 n& ]. s. O0 X! p
- A# N9 ]' Y5 j; N: o, C

3 `' N& @* q, `7 @. _, P20.以下脚本输出什么?

  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  M: {$ }9 j; J( _0 J: U: b
B.一个错误
3 ~' q6 V$ @4 l# L  ~C.一个警告3 d8 ~1 Z8 ^% U6 }
D.什么都没有
: V9 F% d4 e8 B) |" ^  B
. l. K, ~, u9 |  {4 X' K+ {) ]0 Z/ _; u2 `* C4 j& z

1 S7 Q  Z% s+ n% q答案速查
4 ^) Y1 O/ C) \& y1.类
% U# P  H% @( b2.BCD7 z) t% x" }& q: R3 l& N; o- a
3.C# l( I9 ?, Y) e: {# i6 ]1 t2 ^
4.C
6 S4 j, r, V8 L6 G0 ~5.A2 J# c0 d- |7 x3 ~
6.C- W, b' m; T5 t7 M! ?
7.C
3 I0 O: W0 D; `8.C
7 W+ n' K1 u4 c( t: Z  u# [9.D$ }9 `& g8 a+ ^3 E2 U, e
10.B! p5 J6 t0 d7 D& F
11.D
$ U9 Q, F0 B# z! h7 x4 y- s5 {  f12.B
6 d+ d2 v$ |  A0 |2 ^13.A
* q# e! ?- }5 A; \$ T& L# n14.D
/ D" \+ O) \9 q" P15.A
8 t) l* y. [% z) F3 n+ h0 J16.B8 A( U; _- `! E% D- w
17.A
9 `! k6 S' o6 B! V18.D( a* m# \9 u: E* C, H2 i
19.设计模式8 o& `8 [& h; C( L
20.D
7 @- F, d  R1 `5 E
  b+ h" j# Z# L( b: @4 l& w$ W+ X6 t

6 X: @, I- [# |$ C0 f7 k答案详解
3 d. _5 p, @3 `' U7 v# t6 @; \+ [; k
1.类是对象的蓝图(对象是类的实例)。! v5 V/ B* c7 Y8 F
3 o( Q  R) I9 a5 u
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
- l: d/ n) Q! @2 n) z, T5 u
: M# W" V; K  ?0 k3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。. {' s2 q' g' b: ]
; A# v( R( x8 p2 J/ P4 P6 d. P
4.单件模式可以限制一个类被实例化的次数。- Q+ @9 i) J0 j8 d. Z( H8 I
# T/ {; {! H+ O. ~$ y, f+ e3 e+ q
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
0 C4 u+ x$ Z% j& o  E3 H. ?
8 v+ U) ^2 }4 i4 P6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
8 Q7 s: v( a9 U# I# t& ^$ U5 D6 G# L" v, }
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
1 m8 Q' \, {: Q$ y$ i9 ]9 |' J" h9 F5 R% ^( @! A2 G& H3 D
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。/ S; r3 [0 N* ^) L- T

1 r8 F# g7 t4 ^3 V9.PHP4中没有题目选项里所列的任何一个概念。答案是D。. z" D( }/ k) s0 P. b

, [" M% {( q( Q# n! K1 i- [" r# U10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
3 w) |5 s: z1 `
$ D- q2 v  }% {4 e, ]11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
2 [$ ]$ }* s1 K7 C+ M. y
! L; M. ]/ k: a6 l. ?12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
9 ^% i& s) Z( q- v% m& z1 v
% p: X/ k8 w! C% w* O, i13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。* r  a2 d" |! B0 P: Q4 [% e

" M2 a2 B4 F6 p1 ?6 t14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。9 O* k3 N" O% A
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
# h5 H! ^6 Z3 Z- U. I8 J5 ]9 N    function reduce_fraction(&$fraction)
: w% A+ d# t& f% y. ^" V" W( ?/ }答案是D。, t) D$ y' ]$ `  M  P6 y
! F( |& x/ b6 E4 F; }$ N
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
% n' o9 c( M: d: X8 p1 v4 t
( M/ o4 j' [, T: _16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
0 K( ^5 I7 l$ L/ R* l) `1 I$ l/ s& M% c$ r  G
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。$ a1 n" p3 |: B! A2 a

; _: U) T0 e" x: U18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
- N& k" m* w7 Q
6 q, C. M! s* w% Q8 I19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。/ D, _- `* X% |9 J/ D
) I  F  {% X: E
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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