返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。7 q: a# ^* ?/ J* P3 U. S* K
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
  N, c4 @' r/ `4 |. R/ U- [$ ]0 ]本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ ~; S5 l4 T: A. C" D2 z; p  N1 s7 W1 K1 Y4 m( n' E$ W
问题  B+ e4 o  [/ w2 Y% J
) Q5 ~( s- W1 m; m
1.对象的蓝图是什么?0 B- W. {8 w& q8 e8 b4 z
4 C& m$ \/ c% _6 v
答案:____________2 I& ^: E( i% g# R9 v

* ?) Q( ^$ j' Q+ O
2 c/ e1 z. M0 s/ a2.以下代码执行后,数组$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
+ V2 P0 o0 t7 W6 T4 \+ S4 zB.b5 O7 E/ J6 O" f4 _/ V
C.a
, t2 I; D  i" J1 LD.d% D7 S) d/ p2 b2 g
E.e
3 T$ ^" f/ p$ T* C2 @: |
5 K+ A! C: \; p  f. @7 J  r6 g4 m0 I: f) C% c' y0 M$ a) [
3.如何让类中的某些方法无法在类的外部被访问?, q2 b( `! [. C

& h+ K  O5 b( G' D8 S( xA.把类声明为private
# l$ j7 b  @8 aB.把方法声明为private
8 P$ {" H7 Q- @# ~! {0 t; [C.无法实现1 Z# Z4 v- l9 i2 V: j8 H# v5 E
D.编写合适的重载方法(overloading method). J- D4 }, Z8 ?5 c# m+ ?
- n( z" R/ S! V% m& P  q8 @

- G* m" A; m/ Z( b: b6 G4.哪种OOP设计模式能让类在整个脚本里只实例化一次?+ O2 C. X8 D4 ~7 }% Q
6 {" \$ j, e+ T
A.MVC模式
' V# H0 N) f0 h( z% T9 B; x6 HB.抽象工厂模式(Abstract factory)
$ `( l; h/ d( k! EC.单件模式(Singleton)( i% z" {4 h  M. p" W( o  l' a$ H1 }* T
D.代理模式(Proxy)/ S5 c. k0 x; S. O  N4 R7 m
E.状态模式(State)2 o# j' ~) v% a5 n8 L0 L
7 Q7 N1 k. L2 Z. ?9 z
* g8 x6 ~5 }) q/ e
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?  _0 N# f# g- K% k, ?: G

9 z" [8 \  I5 m- y1 k4 [- RA.1个
5 p/ R' C0 P/ d/ yB.2个
) W* j! v4 o- {7 j/ J. z3 \C.取决于系统资源& Z: ^3 v5 Z' j9 r$ ~" e: Y7 r3 a
D.3个6 J3 f' o( A' C, M; [
E.想要几个有几个6 t$ {; E/ H2 l, p7 Q
. D8 T7 y& A' m0 l; d; {

8 D: Q' T/ ?5 C% H) _7 d6.以下脚本近似的表示了一种在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.多重继承. u7 `: y* z/ @! \- M8 D# n
B.接口& h/ A- ^( m: X1 f: y
C.抽象方法
2 _' ?, s( E5 d# ND.Private方法
8 {- E# H% _( T  Y! [E.函数重载(function overloading)9 B6 m+ u8 v9 @& w
8 y& j" C# u& Y) F
6 Q  H" C' G' x1 z( {) i7 F
7.假设定义了一个testclass类,它的构造函数的函数名是什么?. _- f4 o$ R( r( K

$ n& z6 v6 n7 [# r6 FA.__construct* G7 @7 v2 A8 C5 d
B.initialize
/ x& C% |9 k% A4 s3 X& ?: J1 R) PC.testclass2 B0 X$ ^6 \) `7 `4 g
D.__testclass7 j3 H+ I; y, d! c/ `% f2 D
E.只有PHP5才支持构造函数
5 A- X& R' `" x9 H# Y# W  b3 s4 b
4 R' u$ p6 X. L0 g9 h' x
8.一个类如何覆盖默认的序列化机制?: R: D1 b+ J  m: x; p8 e
% U: d) T2 \( n1 H. d) A
A.使用__shutdown和__startup方法
4 g7 M; S9 ~% w7 q# j! [B.调用register_shutdown_function()函数. m8 h. {8 q% T
C.使用__sleep()和__wakeup()方法
6 W8 Z! K$ Q1 B3 `1 `D.无法覆盖默认序列化机制; F* [& T- w) D# Y* }
E.使用ob_start()将类放入输出缓冲中
$ `/ D0 G. [! w- B6 y2 g( N$ @! c# `

. ]8 Y0 }+ ]! x1 ?* e5 y9.以下哪些面向对象的概念无法在PHP4中实现?1 b+ U9 U: c% g6 r- z2 M
+ E, E. {& U1 o& `
@抽象类/ S7 Z" A0 W' q4 ]- ]' v" M
@Final类  B7 |. L- x: n& N# N4 e
@Public、private、protected(PPP)方法! h0 X/ C+ N3 D, n
@接口
/ j3 i; d2 ]! ?4 R$ f
& T: ^* K# W2 Y: @1 m9 z4 Q$ rA.抽象类
+ {4 }" K% W9 S) P  n% [B.PPP方法  f6 F# ^  p, r8 j' z
C.PPP方法和接口  A2 [) |0 k$ V/ M+ v$ `( q& q
D.以上所有都不可用6 V+ n# B4 p; Z! r: N
E.以上所有都可用8 K, V8 A4 W! `3 O! J& M, H5 {

- s6 o( }( F4 V' n) C1 n: t, f* O- ?, \- n
10.如何在类的内部调用mymethod方法?
* k8 V$ }, U9 F1 q
, ~) k6 C. x2 y* yA.$self=>mymethod();, b- Z  j/ W5 R/ o4 c/ @8 J* W
B.$this->mymethod();
9 D, r* c  b2 p# x/ G1 vC.$current->mymethod();9 F7 j1 R" I9 s4 Y$ g
D.$this::mymethod()
* q, k/ u; e% {" X) ]% ZE.以上都不对
: J8 B$ z3 z2 e: p* y/ h
" i. x+ I. W: w# o$ U4 S1 P% U# k# r5 P
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 S2 B9 ~; P; U* e; z" F- m/ A  uB.Null4 k6 k8 Z9 q, x% M
C.Empty7 j2 p% c8 b2 _" J
D.什么都没有
, Y6 z- e/ E! @) T7 c4 x$ mE.一个错误
9 I% L. l8 p8 P" r1 j+ ~4 s
8 \) R$ W0 g8 z" l  }4 R1 O5 y6 w% P2 T
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
1 B" b" H! B6 u  ^6 WB.5& ^" d# e  R% H& d
C.2
& S& ~# L# t8 u* F9 E: P! l+ {D.Null) Q5 o/ D/ i; e1 E& L  W, m
E.什么都没有
" v- |' R0 P6 K2 W: x1 H9 w4 G: J4 H$ O$ s4 U

( j6 O8 T) T: n9 ^" g, u" W  _! ^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
, z% m% Q6 `0 B) H  ]5 E% G, pB.10. n; f1 O" B& J
C.什么都没有9 ?1 P) A9 P9 D- o9 e+ [# ?
D.构造函数将报错) _) [' q' O# r& N! ~3 B9 h7 Y
E.510
# Y2 y  |: C8 w/ M
% g+ ^# S& l: L! Y9 X( n1 N0 Z9 K% c6 {& F( w
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函数必须返回一个值
& ~) G  c9 v) eB.reduce_fraction函数必须接受一个整型值
/ R! ?0 |) |" b, s4 S# OC.gcd函数有问题
# ^& x; V. C8 R$ }D.必须通过引用的方式传递$eight_tenths对象
) F  Z& V0 ^0 r# X- BE.对象的实例不能传递给方法以外的其他结构。
' }2 [* u1 L/ @$ U+ t1 @) ], d/ m8 G" }

! l2 s8 t: ]1 u: |2 E' B: b  W, N% m15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
1 ?5 f$ P9 m, {' w' G3 R, _B.生成myclass的实例并调用mymethod方法7 e5 Y1 j+ T4 C  M
C.产生一个语法错误1 b$ |" T3 ?* F& T) a/ t; E+ b
D.默认myclass类最后被创建出的实例并调用mymethod()
. H) b- \( q& f& Y: {" vE.调用名为myclass::mymethod()的函数
) t* \. z/ y, g' X# l+ ~3 F2 T

8 l# v! B0 g. H& R3 `16.PHP中有静态类变量吗?
+ @$ p6 W& X( m6 W. b2 X3 {) i; x* R
A.有
7 C" ?: y" ^0 `+ r+ w& bB.没有* q/ _- r2 p- l8 }& Y" ~3 \
- _  V  N4 ?, |3 e- G. t0 U

0 l! o( G6 s/ o# T, E& H3 ]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
- o+ k$ ?" {7 VB.2" k: r: ?, i1 P8 z0 E; |. d
C.一个错误,因为没有定义a::$myvar' r6 |4 a1 U3 e0 K. ^. D
D.一个警告,因为没有定义a::$myvar; d) Z* e5 d) @  S' m
E.什么都没有
: k4 ^! Z6 h; P, @) G' R! t6 ?9 d+ Q! Z3 ^

1 r7 S2 i0 S- t! f7 A18.如何即时加载一个类?
7 H. t! j9 h2 C
, E! F5 `3 w2 y  u- DA.使用__autoload魔术函数- x0 d. z& I1 L8 J
B.把它们定义为forward类8 K8 }- Z; f. X* w
C.实现一个特殊的错误处理手段- Q. t- c) ~) j" J1 o9 m
D.不可能
* j3 w2 N; Z4 u/ c$ ]% e3 O5 ^E.用有条件限制的include来包含它们4 F3 q8 ^& S. a; D' X

8 U0 W. D# ~5 H  O
: v( C6 y$ w( B5 k4 C19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
  r$ r& l# B5 `/ S! n, U+ G/ b8 L: b* {
    答案:__________, m( P2 {, l9 ~, _" M
' i" T4 n! R  K2 L2 w
( y6 U% o- r1 r/ g- `/ O5 R( 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
2 E3 p# T2 p7 pB.一个错误
" a  u4 I* q3 N- ~8 @C.一个警告( ~* a/ O2 ?8 ]; `) d
D.什么都没有
+ \; }% o1 |; e9 |' u" ?
: P: W9 U( e+ h0 e$ t& ^3 U5 y% N3 i8 g) i

+ p' M: H2 {$ ]答案速查
' ]; R! s3 j: y6 `# x# M1.类
6 ?9 P, t* q; U/ P2.BCD( w  }. O: v6 U4 _6 s
3.C2 E, |- b! ]& _8 }# J4 Y( B
4.C
. w3 U* i. w9 J+ d' u  s5 B5 \& b8 W5.A: H' K+ p& u' e+ q# B3 ^
6.C. N' D1 y( }) ~# u& q9 x& w
7.C
, D3 Z- q/ n4 i' N2 a* T' L: `8.C
% ?; A$ ?: J( }& I3 k3 k9.D. Z/ E( e9 E% J! V
10.B
; Y7 }# {7 h- m5 [11.D6 y5 y% v7 h3 O. {5 E) l
12.B
# E' k, G5 B& U% g" ?7 B0 d13.A; T  S( C$ S7 ?
14.D
  `4 }/ r7 t& u  Z* x15.A
* B$ x# c( Y2 v0 R7 |5 S9 |' u& v16.B
& f$ u3 q, K' `& q3 N# E  ~7 n17.A" e1 i3 h" Y4 g
18.D+ `( s: }+ z! H  I
19.设计模式
/ y/ j7 j# E: s20.D# G: @" R( N( S9 g$ t

+ T# ]' @- Z- n% g4 ~; d& c/ K+ a8 e7 h% x5 o
5 M, X- E, j' x$ r3 l  Z
答案详解
& C7 l2 K3 @4 F
' u+ P4 i% I4 P3 J( C- V1 D1.类是对象的蓝图(对象是类的实例)。
. s0 h9 g4 t, p8 @
0 U4 V4 R7 H7 G# }) Q2 T! J, u; F. j2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
! ^) Y9 V# x3 R0 d- F
2 B& F# f3 q: ~" O1 g) ?3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
! L; `9 B9 Z- l6 P; D4 A* {
# r1 t3 N2 S0 Y5 f* a0 U+ |" `4.单件模式可以限制一个类被实例化的次数。
& Y. X2 S" x9 j' g0 M& V. i& Q( g0 F$ h6 H9 `! f' L4 R" F
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
/ C9 ^) |5 T: {: U$ Q, N2 f9 s
& r0 [, m$ ^6 a* t6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$ N' {5 ?7 o1 l' ~" A+ C6 |

& c+ D. t. p* G1 a8 D/ U0 k7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
2 Y; d7 b  F7 }. i$ h2 D1 O' o4 y& h0 m7 [+ u5 T# [
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
3 z- P5 f2 F& h0 w; V* k" S. x& z
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。8 n4 z( ?) I1 {$ U
- x0 O" p: E5 z2 M4 k
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( z0 f) g& e$ P

, x/ H2 B$ v& v( ~11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
) ~! E( Y0 l9 o6 ?1 T/ x+ [# E. X! W4 n, `3 ~
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- w& @! }6 ^6 z- n9 P( |% A
9 [, G$ d7 m. X% b4 u
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
; _8 S: g4 }3 M1 y% k( m
$ F! B; _3 w2 P& d14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。9 c7 g: `$ x4 ^/ d* w
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:1 |1 B# p0 x; M9 Z+ J% t- Z# I
    function reduce_fraction(&$fraction). U( R9 B2 _2 v. y) |! a
答案是D。1 e* M7 \5 A7 t. N
0 b0 h, @. i, Q; ~# G+ Z7 g
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。+ Q& R" n7 @5 I0 U' P
/ c6 G: h* N) X4 j1 D- n; Z
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。5 u% K% ^( `( }2 a6 d4 Z

/ W: {8 ?, w" s17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
% e( T. ?$ c) r
- Q7 F6 b/ \3 `4 N1 A/ g18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
" G- J" S+ T, d( z/ P: T2 g+ x. Y8 R' F: r2 e4 c- J7 w
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。4 u, V2 a: X  G( F5 U3 ]

& i/ _: |5 g7 v+ T! a# x2 k! q20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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