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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。' s  @. N2 s- c0 K) z2 ~2 B
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
+ b* K3 ^% L( i/ r# k本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
- ?3 p7 v: c, F3 @# n
/ a/ C& B3 i! T  I$ p' U7 |问题) I8 x# ^/ k4 D- s* V" e

1 g/ ]" i2 e6 c4 u1.对象的蓝图是什么?
( c, C# ^7 Q  I  O5 F+ G5 a6 i
8 [7 f+ b8 @2 T: L答案:____________# D0 @* l  ^& |4 O" M) B/ o

0 }- ~/ I2 O; K& D. p( g
4 |. N* P6 r7 D5 s& _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
- S, ], T- y5 f1 e+ i  i4 MB.b, V' Y6 G6 ]6 L3 }# l6 p$ w$ Q
C.a
% _) ?4 u  U$ m- s4 wD.d3 ?2 t- U. i( D+ W2 [
E.e
- s" n9 F, S" W  k: w" z- g/ q) k( M/ s# ]. k- Q
5 N  S0 K* _+ m! Q3 Z) ?: f" [# a
3.如何让类中的某些方法无法在类的外部被访问?
) I# l: K( a7 s( ]1 `
4 K. ~1 k! Q% i' a* @( S# |A.把类声明为private; {; J/ v$ j* X) {% I% c
B.把方法声明为private
$ o1 f7 G: |  M+ x4 p/ C  L8 a# ^C.无法实现
) Q+ O8 y; J9 ]" M, B: @D.编写合适的重载方法(overloading method)4 n# {% J1 C1 ?$ [/ t# T4 I
. ~" `7 `% ^# N3 w
) T' J4 d) c: h5 Z: ]. O
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
- ?. K9 d7 p: p$ P* ]; k; S( J  b  [/ @% }0 S1 w4 c' t
A.MVC模式
- x4 D- `& G- \6 d4 o- lB.抽象工厂模式(Abstract factory)4 C( l2 J- m3 y6 L. e6 u9 d* L! b
C.单件模式(Singleton)4 Z, K9 n- e4 ?; p( q$ @
D.代理模式(Proxy)
" Z9 A. J) e' K) ~# wE.状态模式(State)3 \. B9 f* s0 l

( a, @! K8 }+ N
* m4 w9 x/ Q. u. a6 I3 D5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?( V, M- Q5 ^: ^; z" U8 {; n" y
% r' c% s+ Q9 P$ [: @$ }5 P( g
A.1个6 a( X- f: W. F+ c5 g9 [. r
B.2个
; D- j8 u  }- n( j1 f' L  v# aC.取决于系统资源
9 H2 o! y! d: F$ lD.3个/ g# l" e. V9 U: B2 A
E.想要几个有几个6 W* |( n8 `4 c4 k
8 k8 z+ [9 D! T  W6 A" ^$ E
  x/ t4 G% ~1 T# s3 C
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.多重继承: H8 m" }( `9 X2 D/ x, r, ^2 L* S! x( ^
B.接口/ t6 n) w2 Z! o. }' `. Q
C.抽象方法
. g) H0 u# J/ v6 z. e2 h5 U8 GD.Private方法% [1 F) Q( t  R! R$ {- t
E.函数重载(function overloading)
+ @+ h8 D, l% F0 `, P
; @3 e6 j# Y% t9 z1 `
3 S' N9 R- y% d! ~( X0 O  |8 C7 X7.假设定义了一个testclass类,它的构造函数的函数名是什么?8 r0 f& L; t# A. _1 B

& s" J. `* z  X$ Q' V& ?& mA.__construct4 {& i+ [% K- |" D  p0 p4 j$ r" F. N7 R
B.initialize
$ R; B, }& S- iC.testclass% q# G* r+ }7 W8 T/ `
D.__testclass8 T: n: p! C; ?, }! G2 M* z
E.只有PHP5才支持构造函数/ g/ J" `6 y  ?! N
  ?- v- I% o% t, ~
* v5 @$ W/ C: ?5 x! z% t
8.一个类如何覆盖默认的序列化机制?& B) L* C  m( v8 n$ W
3 u3 I+ v$ P# v  Q/ {. R3 b
A.使用__shutdown和__startup方法
$ t; _5 }' g% O+ A4 a3 A/ W# {B.调用register_shutdown_function()函数* j" C  Y$ P* @" }" K# E5 ~
C.使用__sleep()和__wakeup()方法
, W9 X; O& ^  G! P8 I$ eD.无法覆盖默认序列化机制2 e/ {/ C7 T; g9 H0 _2 y  Z
E.使用ob_start()将类放入输出缓冲中# U1 A1 D  U/ @
8 X2 q% D* {# l7 u- G% f" B; W5 [# R: z

8 A7 {9 S3 f4 y: ?7 N9.以下哪些面向对象的概念无法在PHP4中实现?
" j; ?5 y8 _7 K- K+ p3 K1 E+ c2 ~+ `4 U9 t4 y+ D/ k
@抽象类
) f! D/ V4 a  ~% X2 S9 }@Final类$ W  U" t2 O0 E$ s3 ?5 n: a
@Public、private、protected(PPP)方法
  ]; o9 j5 ^  H' y3 L2 ~! N. @@接口  B7 x) Q! _) y- H9 S! F* ^

0 B$ A8 q) G* p: EA.抽象类8 J3 U- B8 f- S( f! O7 o% W
B.PPP方法( C9 Z1 R2 r0 d+ t0 v/ u1 g
C.PPP方法和接口
8 v$ i: f" I9 [D.以上所有都不可用
5 @5 v6 t% o& C7 e5 jE.以上所有都可用
5 Q. S( P' l1 w/ A# ~( H% \4 l! d6 G4 D+ D
) x$ s6 }9 ~9 M, C7 C& U1 r
10.如何在类的内部调用mymethod方法?; [0 I$ x( I9 T1 d$ k# z% m  k

3 J8 M! A5 m3 ^% TA.$self=>mymethod();: Q" [, ^' N2 E
B.$this->mymethod();
: P$ q% Z5 N' M; G: C- SC.$current->mymethod();
/ |, |0 s8 W' ~D.$this::mymethod()
( c! Q9 K$ y! ^# s# ^8 SE.以上都不对4 r0 T6 m) {. w$ d7 B( L
0 F) O" n' n' w+ W1 }/ y1 i/ o6 Q( p1 n
  h) |' w1 C7 O+ x9 s8 A) D
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) L" n5 Q' B9 e3 u* L) V
B.Null
  S# h, o/ C( U, G6 j9 `C.Empty
1 \# N3 l* C/ L4 V& S) i# j5 ~3 l! ED.什么都没有0 q  F/ P4 q6 J7 h  g3 t# J3 j
E.一个错误, E3 u! R3 t) ~
' t/ h" @# C. Y8 R6 p* n
' N+ M% X" n$ y! J3 i$ v- _- s
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
. q! A, `$ z4 y1 PB.5
7 n" {2 N. a7 s1 }C.2
9 f# i- M) B4 ]( n% [* nD.Null
  l& p/ G: c* h/ J& XE.什么都没有
, q( O! u' A2 O- s: h- @5 J
! D$ L" ]9 [6 D( z3 ]! w' v/ U: m1 r) Y
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; F# g* F0 l6 C7 R' o  m5 V
B.10
, }0 E5 H7 V: V; ]* HC.什么都没有
: y  ]5 |! \. y# Q( Y& \D.构造函数将报错# J( |' u$ W. p1 b* k
E.510
) _+ Q0 l9 G1 F* v3 h# J& T  a$ E7 L. s+ G; g
0 G3 p( A* `3 [" N: Q( J4 i( e
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函数必须返回一个值* \5 }$ P; x  A$ |5 a: S
B.reduce_fraction函数必须接受一个整型值
6 v$ w) O: t! z! A5 h! h% Q' S4 {C.gcd函数有问题+ Z. H& L+ P' g6 q, V/ V  q
D.必须通过引用的方式传递$eight_tenths对象
3 \: d( X$ D8 KE.对象的实例不能传递给方法以外的其他结构。( R: U2 b$ v: f/ C" [& k, L
) c$ B: o) z( u0 h7 }; O2 x6 t
& l8 V, |8 t3 `9 v$ f* i3 ~
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
8 A5 G/ L$ s3 ?: Z7 i  m' z9 b; DB.生成myclass的实例并调用mymethod方法& |/ u! A# M2 I- H. t6 P
C.产生一个语法错误! c  g" H( X- L$ u1 N; o" P: c, |
D.默认myclass类最后被创建出的实例并调用mymethod()5 U0 ]) _1 O, E( b( R+ w! Z0 Q
E.调用名为myclass::mymethod()的函数
! W8 T$ a5 A+ |, \7 L
, K9 `  y, Q% p: Q# F& g; g( l5 v+ B+ M
16.PHP中有静态类变量吗?5 h3 D- f* H7 E5 V% a: m& Q
+ X, H3 a6 {, f4 C( C
A.有0 u6 C. t. t1 [1 @
B.没有
' L1 R  r9 g& D2 {5 k2 P6 C7 v" Y; Q/ V( b4 ^7 T, q/ B

# j4 [0 \( a# T17.以下脚本输出什么?

  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
/ O# `5 s! Y# a8 F& Q& LB.2
: w; n3 ^7 @- `6 V9 O6 B* X8 pC.一个错误,因为没有定义a::$myvar' Y1 l/ B0 ?2 T
D.一个警告,因为没有定义a::$myvar
% Z4 I& p2 Z! Q9 _4 CE.什么都没有
$ U: p) q  I3 _! `* @
0 M: X3 U5 T* Q; X( @! @# O" i0 k/ i* W8 [# E1 i, o" D
18.如何即时加载一个类?5 l1 W# P6 f( @. V
% x, \" }4 F4 K6 N- ?, `
A.使用__autoload魔术函数
7 e1 F6 N5 ~: eB.把它们定义为forward类% F& o- y% o4 i" T9 s
C.实现一个特殊的错误处理手段% [1 J- a  n: A/ M0 V( d
D.不可能
% M% V2 L; O+ i3 d( \, iE.用有条件限制的include来包含它们
9 Y) o0 S- Q  V" J. Y8 A9 [- p# s; |
0 O% r, n  F2 j$ X# x, B
7 z. M0 G. {# e6 Z/ }19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?: f" o$ O. t: }1 X" L& x
  s, e# l! l. M% W0 S
    答案:__________3 z- ~6 \4 H( _5 V4 i+ P4 s
# D7 \6 r7 Y5 |& W9 J  j8 e

: m7 J) L8 X# L+ D20.以下脚本输出什么?

  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
& q/ ^) Z, F8 D' AB.一个错误
& b( H" h$ J& C! eC.一个警告
5 h- @8 u9 n4 o% s3 S* R% J% qD.什么都没有
$ Y, _4 V% h6 e4 H$ P$ [- A& w0 V. \/ g# r

7 D& T$ E3 D% A* M4 d
5 @: f  V( k3 Q/ @; m答案速查
. q! O$ A. C+ T, _2 }3 @1.类
' t, g0 [9 p( Q# _$ z2.BCD
' k- \( S7 A# @1 D: @" v  \3.C* O1 X7 n( M  F( g% C) o2 d
4.C$ M$ ?) B9 u! {/ k: s) [
5.A5 ]. {9 T. N6 ^$ w- t4 V% R
6.C
5 I3 L# r; Y. p  e6 _2 }7 B7 C8 n8 M! r7.C: [$ q9 W! Y! G. }1 G
8.C! O8 }( x1 \6 r8 h7 d, h
9.D
% N9 O- ?* _9 ^2 Z5 W' B10.B
2 P$ W# x4 ]: e& o! g) w6 T: m4 I11.D
1 Z- Z. ?& |- |* \0 n8 h8 F0 @, H: E9 e12.B7 R! X( Q( n. q, l6 l
13.A; w' d  x! X5 ~/ I9 N! |! I1 E
14.D! _0 Q" i- K7 m2 [8 C; {
15.A3 I' k3 @; K. A4 i8 S! j
16.B& m& b7 b7 h4 a8 ?6 @& z3 e
17.A
6 s! M* W# P$ R4 t6 S18.D/ ?. X* U* }9 z1 e
19.设计模式* g  E$ \2 j- u( X3 J+ v
20.D
  Y8 Y, ^+ N0 ~6 s5 y4 v
1 Q' b4 m0 a2 J. G, [& V* L, N6 z1 s; I
1 U0 w/ l5 N3 _9 k
答案详解$ a3 G/ o2 f& T7 ^6 a! [$ ]
4 K0 b! ^, Z3 g4 J( M% r) ^' ?
1.类是对象的蓝图(对象是类的实例)。
4 W3 Q! f- y- |* v& E: ]5 _
. z2 h* g. D- S  J8 }( E/ \2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。' b$ `0 v0 ~. L* r$ E

6 p# H: |7 `- e6 u8 `2 C1 A3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。% h6 V  M" Y; `6 |; D; [8 A! i; v
; ~# ~" N" V  u, s& y/ c: X
4.单件模式可以限制一个类被实例化的次数。
! Z! _3 S6 E+ C9 L! V( q
, J! E1 N4 j" v/ p1 O% C5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。2 u( {8 P) X& F$ R; ^% f3 v

$ M: G! {1 L. n3 C! ^! O% O6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。8 f! q; `. B2 _* Q% u: \; [
4 R2 H  l: r$ Y7 D4 V
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。8 A+ d" D6 u9 a% i0 W7 {& d
3 j# x# Z4 z, w- R( Y4 B% S8 T; K
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
. `% Y4 _! \" p1 Q, m. d2 Y/ u7 _$ q1 I' O, O& W
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。" w! c& u. j. Z, h

5 j3 H& {9 [* O5 _, G10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
: ]6 b2 O0 ?. R2 F1 f" B# `9 S$ d2 A; l
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。, ^0 F* a& R( H! i- ^. y+ P

& x- K, m) f$ q. q12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
/ G  J/ ]) [  ?0 q3 V2 B) i7 G; d$ |$ b% _+ p/ G" a
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
' U% ~  @4 Z+ ^4 A1 @
7 C* O, E( e+ N: S14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。. V) X% }* G0 t" T4 T6 z! S
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
3 A% d2 U2 d( U+ E! a- `3 @% }& U6 [    function reduce_fraction(&$fraction)
5 {# m3 N4 V; K: ?1 z* a答案是D。
5 E0 q  U  V& `/ A! B. T) ^$ J3 W1 e7 W+ D1 Y
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
) b0 |: c3 o+ [3 S1 o
. I. W. E2 K3 p16.没有。PHP4只允许声明静态函数变量,没有静态类变量。2 v1 p# [) [1 f+ Q
5 `; V  s) r- b( I
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。. r  M: J3 z/ _/ l
4 K8 b3 W7 k, {7 [' _6 D
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
- b9 r- C3 `/ }6 c% E$ X6 [5 D" ^
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
$ @) I- m  ]1 C- c9 b  S6 I. e% f
! u1 k( }# ?' x8 y5 ^20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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