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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
- a& n9 ~& n2 X' _PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
, @" V3 q3 j& h& S: N本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
. X" V2 z3 [" c; g, J2 S- s9 J: s6 S! g' t$ R) L
问题
( B5 k4 p  k& \& s  `  x) d
  _6 y+ Q% I" @& m1.对象的蓝图是什么?, h  R( t- U' F2 a; f; h3 _  G

; z& ~' Y' v- a/ s/ e5 Z答案:____________
; T6 A9 n7 X1 `: F* C- H0 r" j# H6 H0 R

' ?/ z  q( M8 L" }* _+ j  S+ E2.以下代码执行后,数组$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.c3 P" E1 }" C1 q* a2 e& u
B.b$ V0 d6 c9 A/ O5 e" p# v7 @3 L0 ]* O2 @
C.a( _8 M( D( A1 b0 X( B; }2 f
D.d: q) \7 i% ]/ d+ \8 K- q: w' ~! q
E.e; L: f3 m. H4 W4 w( f" ?& q

: O4 J# P9 _* |4 Q( J8 Y
, ~; E: C; E& \$ h$ e3.如何让类中的某些方法无法在类的外部被访问?; k& h) \# T: A8 j0 F
6 _6 o. H% I. l  S: J. k. k
A.把类声明为private
1 E* \+ J5 q( y7 @& H2 [6 PB.把方法声明为private
) j3 k" ]/ }, Y& A" n4 w3 GC.无法实现
6 \; y, g0 j+ R1 Z; E) }9 mD.编写合适的重载方法(overloading method)
5 a' w- f' T) U9 G1 |
  j; Z: J4 S* B9 E( R9 a3 y% ]( A: q7 S( c/ L$ T
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?: K+ Z5 S: Z& m$ A
% S  b5 b( S. m6 Y4 X/ `# m2 v
A.MVC模式7 V7 B3 x9 Z5 K/ d* C  [# Z
B.抽象工厂模式(Abstract factory)" y; D  C. ~  K' _+ }
C.单件模式(Singleton)
. D1 i4 o* U. n* b6 z5 b- t9 ?D.代理模式(Proxy)7 W4 o5 p- W6 }  {# s- M- n
E.状态模式(State)
* @  n; V: K2 c+ \$ l
; w4 ?/ b# o4 ]4 @* X2 T
1 x- }6 M5 ?9 A" O7 I0 @* D- f. u5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?" C9 H8 l8 |/ T1 R. {+ b/ X

) L% ~# g. g4 D; FA.1个4 r* p/ v+ H, L, J3 y! Y' Q/ c
B.2个2 t+ R  _& u# R2 a' C& ^0 i
C.取决于系统资源: ]# ^0 G" E! w2 E7 {. i: m
D.3个2 D5 I0 Z4 W7 o: m  ^4 X
E.想要几个有几个
7 ]+ ~8 M- p4 T# Y. U3 V+ K$ Z; i" {; I  i+ q7 B" N
3 R  D" y3 I' h2 r
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.多重继承
$ r9 N: C' w4 j: OB.接口" g# ], N, n; t) y* a. }3 d
C.抽象方法
$ \6 s. w7 p4 G6 z, E/ d9 vD.Private方法
1 ]* s9 }5 m5 x4 u: OE.函数重载(function overloading)7 }; V) c3 I, Y# r
4 V% o* G0 n: M8 h" v$ ^
% h1 }( h" B+ J# q. T  z
7.假设定义了一个testclass类,它的构造函数的函数名是什么?9 x5 j* A$ [1 u6 n3 X' A1 a: o
  }+ q# u0 W& X5 r% {! L
A.__construct! [  G; H9 a, j+ u
B.initialize" X0 |0 J* x6 g; `
C.testclass
; \- L. U" I2 @" t1 }D.__testclass
2 c/ \. [# \+ U  E, y% wE.只有PHP5才支持构造函数9 c" P, f* N' a, E7 [# C( i

4 d  X  g/ Z% V8 A4 A+ g( B
/ ?% v9 H. q+ s* c% H8 L+ t! k8.一个类如何覆盖默认的序列化机制?3 [/ L3 Y; l1 F# [
# \; T/ V: N* J5 I
A.使用__shutdown和__startup方法$ |) T$ a& U4 r8 V7 W% b, v, {
B.调用register_shutdown_function()函数8 ^) Z1 V2 E$ g9 \7 b' w
C.使用__sleep()和__wakeup()方法$ Z1 W* B  |( N" s9 m) f. M3 r9 c9 r
D.无法覆盖默认序列化机制; s  f  q3 g. N, [8 J6 ]
E.使用ob_start()将类放入输出缓冲中' L7 y1 H& i4 u- n% R. X
# g! j5 l0 {# u7 i

! ?6 U8 R' r9 W0 `) T' X2 U9.以下哪些面向对象的概念无法在PHP4中实现?
/ E) z+ i: ?( b6 N1 z2 j5 F( q% K" w+ T! A6 r) T
@抽象类( b) w- v9 d$ I6 @+ d# ~. Z
@Final类
/ s  i" f- A0 T2 k* k8 r@Public、private、protected(PPP)方法# I; {  Z2 x. u6 ^
@接口& a& k1 ~1 s4 q7 Z

( r# n, Y4 V! NA.抽象类' J& E- k  [  A. F2 b
B.PPP方法
0 g1 Q% b  p: h5 f0 y' RC.PPP方法和接口
& Q5 b% q9 P# E! a+ yD.以上所有都不可用3 p* [" T, Z: }& I/ \
E.以上所有都可用
1 C6 V6 U) l" G4 a# `5 l0 j0 P9 p6 C. o
! l. w( N8 ^! b; \2 E
10.如何在类的内部调用mymethod方法?
$ k' F8 t7 O0 e2 I2 F+ C5 v- M+ S) N
A.$self=>mymethod();
4 m+ r7 D" Z0 c& v, D6 }5 {3 zB.$this->mymethod();
( ]9 A/ k# \* ]! ^3 U$ _C.$current->mymethod();
6 Q( S8 h4 I8 _3 c$ ND.$this::mymethod()
, J/ {( i3 i0 y5 }2 V2 |E.以上都不对
) B5 W% h2 H5 r" u4 w9 _! K5 K* A7 |1 O5 ~1 Y

+ C8 [5 s( \! l! v. U5 l11.以下脚本输出什么?

  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.101 Y  |; P* @: d; P
B.Null9 i% `, u# M' q& ]9 ^* S& [
C.Empty
5 W2 F9 b2 H7 ]1 i) cD.什么都没有9 I# ~5 z; O/ w9 @: r- O& r
E.一个错误
) _+ E1 A& }8 a% k8 u! B
  ^+ ^  x9 f/ s6 T# P+ b; Y
) X7 W/ `8 V6 ~2 h8 ]2 z12.以下脚本输出什么?

  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
6 R/ f2 `6 K& Y! kB.5
' `1 P5 i) O+ U; yC.2
+ e8 ^* ]) u1 Q: ?4 S  d6 g6 XD.Null, P: c5 {  P+ T) c1 q* \7 a( ~8 ]
E.什么都没有
9 e( u  j5 R, [6 H7 |, `# y+ ~/ X% R6 Z% \( v! c% _
$ t$ ?0 ^0 L, }! h9 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.51 x6 ?& f- I( w7 y
B.10# d& r5 c9 H, D9 z! |1 q4 \
C.什么都没有# p2 k: V  k/ C) S0 I0 m  o; E
D.构造函数将报错
+ p5 a! _+ s! f9 yE.5104 R3 l- ^$ b2 L% k$ W4 X5 [

; }* F. K2 J6 L& G& _, [' b8 a+ j5 A# O
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函数必须返回一个值/ Y( |1 u' \. Z" A& {0 _- V
B.reduce_fraction函数必须接受一个整型值
' q  Q! G5 K) S) ~: `C.gcd函数有问题
, U. I$ X. y+ j  E* u* g* bD.必须通过引用的方式传递$eight_tenths对象; M/ A. Y7 \6 J$ a# y9 k  b( [, Z; J3 R
E.对象的实例不能传递给方法以外的其他结构。
6 }8 l1 A: _- z
% ]4 s' V( u% g3 p- G" B4 v4 Q3 |5 m! }6 b  m
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法4 X' `7 Q; V6 m/ k, r
B.生成myclass的实例并调用mymethod方法' `6 ?7 M, ?0 z# }, C
C.产生一个语法错误
+ j2 M; ^7 c' k; Y/ VD.默认myclass类最后被创建出的实例并调用mymethod()
# P- y) j0 G: |$ [) kE.调用名为myclass::mymethod()的函数
) w/ S9 V# b/ L* {
4 M9 V* i( G, L- V! B
$ V: N2 I5 m/ r$ M: t( ?; n  Y16.PHP中有静态类变量吗?
- `) H5 l( O. m( J6 N/ n" ?0 v. `1 B  R( X- d8 g6 d6 ~4 X
A.有
3 n& `: C5 V8 V, U& A7 x) g, d- t" dB.没有$ f7 M) v# O, i9 ]

' y$ |0 w' u1 \4 t( O
& g* N$ P% O$ X' V* n17.以下脚本输出什么?

  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
0 }0 `/ g, d$ X: x$ OB.2/ O5 |# u# A" k' I9 R+ I1 }
C.一个错误,因为没有定义a::$myvar
8 Z  T6 d# y5 d( ?( i1 J0 q9 a$ ~$ HD.一个警告,因为没有定义a::$myvar
8 W6 }( a& ], ~* V! |E.什么都没有8 q, J1 F: g; s. I1 c3 Z6 ~

; q# F+ i* L6 \- d9 z- \
& G3 x: c, s  I, j! ], Z  b" M1 s9 [18.如何即时加载一个类?
9 M6 c' ?3 x8 p  z
" K: V' V9 M' C9 EA.使用__autoload魔术函数6 h( {. D: q5 A) W& C
B.把它们定义为forward类
$ F, v. R/ {& R) |C.实现一个特殊的错误处理手段. v8 ~3 q$ j% W) O. F
D.不可能
/ x2 e9 L" H0 I& [- LE.用有条件限制的include来包含它们
3 {' t3 R: h; d1 ~3 A7 e8 r6 B- j7 N8 t; I! i' q* V& ]: v
% I4 M; V1 D9 }! y$ Z  G5 A# c) z' ?# y
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?1 F9 s+ S1 O# @

  m3 I0 P$ _+ y% x% p3 Q7 J    答案:__________
. _* t7 r6 w1 B. N4 K) I' P. F. d' j
2 S/ J& X" ~4 g) c& N6 c3 I
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 called5 _7 R* H; S; Y6 v) M# O  r
B.一个错误
7 G3 u' f# a5 U& lC.一个警告3 G) g- D* b" t8 p: ]9 D- a
D.什么都没有! m7 b( p  Z: C! d* y
' v, ^) t' k7 u

' @( v( p6 k/ g; S
1 Q( O2 g4 n" I3 T& G& q& L3 }答案速查- ?- I8 ]! m2 V5 Y
1.类( n% U6 B% s& W" K0 _5 {
2.BCD
' B7 H% A7 I0 {8 c3.C
, h8 n: V  H- |' d) \4.C
2 F/ R5 W7 g+ M4 s# \" \5.A
3 z$ p6 ^" T; r5 h3 ^3 F/ u5 h6.C
) S; U$ ~& v2 `3 p7.C" i  \0 f8 U7 J* A  |) n
8.C: w3 T8 o4 w* p& s/ a2 v
9.D1 h: H) R( R1 l. b; N& ~2 }
10.B0 D" T. a: Z" y% i. U* h2 e
11.D( ?. E* k3 e, |: _
12.B7 W$ O9 |  P; z3 W" W8 C" B
13.A
1 J8 ~+ w# }) C* C14.D
' `& W. H* K- f( @: n! A6 u! Y15.A7 Y8 w% n( F" V# [8 T
16.B' |6 v4 v( m# l
17.A
' C/ a4 D- U& ?# G18.D9 W1 r+ D5 N% P# [3 E! x( `1 g
19.设计模式
) a" Z" Y/ Y& V! f6 \8 t, U20.D9 U8 N, y; @1 x$ z' U
1 R3 z: l& N9 F1 `2 E4 @
* D. c  K2 W+ B2 y$ {6 ?
, c/ U5 ^' }0 O
答案详解
. X- N- C, l% M" g9 Z$ B6 k$ Q. t9 }
1.类是对象的蓝图(对象是类的实例)。
, {/ [  F. T3 R& R8 \: E& `" e* o7 r+ s. |+ v- c  h
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。& L8 Z- E  \2 t6 k

6 j; L# G' w6 u5 c& U4 x' q3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
# u5 ^' Y' ^# ?$ N# k* J, W' M7 h, L5 t9 q
4.单件模式可以限制一个类被实例化的次数。
1 x: i/ i" S- H7 G. c5 G4 L1 l- b3 i
( ?% e0 N+ v+ ?8 O# q) X5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
1 e, @; X1 j4 G1 ^  y2 S0 U" R/ C8 }1 P  p7 M
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。6 {8 ]7 h: k7 h& n7 H
2 ~, H" p+ Z, n, r8 i9 o0 G" v
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。+ v0 u% }. ?! }0 A. h: D

% W+ }" [% @7 Z9 b8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
7 ]" b) q4 U3 F; u  A1 f* }; U" r% q9 j3 p- y2 F0 _  Y
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
- \; e# {. E' h- A) Z! C( |4 ]
- e5 M) W- n8 X& ^6 P; a$ v& `10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
' M- s$ o4 p9 f, @; S1 A
: g, c- y9 e1 Q$ u11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。, T8 @* e) k4 O6 k4 p+ c5 ~

; q: `' W. w4 m  R- D12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。) J- O: Y/ U) B, J2 E
2 Y" u, _$ z* U
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。9 u/ q3 O/ @6 p1 V- W7 C& z

" d. H) e2 Z2 |6 f3 d& i7 \14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。2 L+ ^# J1 V6 w2 ~, j3 B
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:$ v- W' p$ w; I$ w; b+ g
    function reduce_fraction(&$fraction)
7 n) p# Q/ \$ \, r' k9 q. \答案是D。
* e+ G% ]) f3 k, X$ u$ ~' @# n% ~( a! q, Q& f" _, J1 E" `; O; P7 M
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
% d* Y. @% e$ z. L2 R3 M$ Q
; P: r+ f& [) S/ N* M$ f16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 E( k1 \( p& d! ]+ i9 k: v0 h* s

0 E; ?6 ]" a% R17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。: F+ a" @) W3 C. F) k2 f3 p2 \2 z

+ z' o5 r  O. ]18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
' W# t) B' X0 f. _. m' }3 }( _" ]
2 ]% p, m2 I: u0 W4 K7 r- A19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。9 H# W6 r4 i% f) @

( V, O3 ?3 w4 j% r% ]9 I1 B7 ~* e) W20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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