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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
- {" C5 f7 [, N3 }5 CPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。+ {" n$ d7 |3 r& n6 l3 K
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。2 |2 g. B6 ~/ ^' O5 l: ?

( q; P  e( g$ ~' C" H问题; A! v# n  K* f! `& k

3 u- _; [, F- f( K* b/ i1.对象的蓝图是什么?! S) ^# p' {1 q) B9 P

: ?1 j! X! {. o: }* x答案:____________
* E& i1 K0 y& c; o5 S2 t7 {, _% |' ]; T6 w/ C) j* f

/ ^. m' I# S5 W! S2.以下代码执行后,数组$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
) ~4 r! g" l+ V7 I; |- eB.b
8 e4 p) G$ C( Y$ l3 m/ r5 ?C.a
& G  t+ {9 x' M  B: ~3 q; D1 `D.d4 p( @- c7 G9 T
E.e
" T1 m9 c. y% U$ L& Z1 H' `  e  J, W4 k. c1 t. T
& G' a  g9 X) F, a% a
3.如何让类中的某些方法无法在类的外部被访问?
/ O& ^4 D# H8 k: H8 l: ]
+ c9 w6 I1 ?# c  u+ W6 A; AA.把类声明为private0 w! u& p6 ~4 q2 w, c6 ^
B.把方法声明为private
* ?. H9 c- t- S" b1 |  hC.无法实现
, M6 w# R3 Y2 g) SD.编写合适的重载方法(overloading method)
) p& E( H+ I+ P( u3 C; K
( G! g5 f9 _6 \; f( u
4 u' z) X3 ~/ Y* V5 A4.哪种OOP设计模式能让类在整个脚本里只实例化一次?& o7 B. q4 C( k6 n4 f+ z
5 F' V: D2 H8 z7 Q4 \
A.MVC模式
$ n5 B7 ~3 I( \" c2 v) iB.抽象工厂模式(Abstract factory)
! M. q  O1 f/ S7 T: EC.单件模式(Singleton)
- B0 y: |0 G) C( X: ?; ED.代理模式(Proxy)# K# a, U5 _' T& @$ u9 @
E.状态模式(State)
# y5 v6 c% O& O: _1 B
- R: z' k& D0 ^  J( F
1 s+ Z! X/ V+ {0 N3 T7 k5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
; f+ Z' P1 J  T2 V( |- p, n; f/ z8 m& q5 G' K' q7 X8 i
A.1个, R3 r/ u$ g8 `7 j5 ?# }
B.2个
7 j) K- w& W6 H# |& v% DC.取决于系统资源; h% T, ~8 X: l$ f4 s7 t# U( @# p
D.3个
% M/ {8 x1 V" q+ ^$ dE.想要几个有几个/ ~5 D8 S0 S) Y( e  d: u4 A4 ~
4 S& H) ^9 `4 t- B' m

- |; k# g0 F" ~& L; l' I1 x7 j( W( ?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.多重继承7 ?7 V' X$ i1 R, g' a& D' L
B.接口
' C9 q+ K4 [* W- u: _C.抽象方法
) g' i* `  [. n5 w/ oD.Private方法
+ W% `# Q9 d3 Q( kE.函数重载(function overloading): @2 T! M/ W2 C" ^. r

( y4 S# A/ _! g' u" _. L$ p( J. k( s) b, Z
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
& Y3 D4 d: G3 k+ t) J4 V* |
- n) F  i) x5 a4 Q" A) S4 @0 h  g5 RA.__construct
' i/ I4 A, p# e# fB.initialize8 |( v: `: E% @4 @, g6 E4 {* O
C.testclass' p2 j- ]0 K; Z6 y4 W) s( R4 M& j
D.__testclass  W& Y7 E; ?1 d! A' u! v- e
E.只有PHP5才支持构造函数! G, y0 z/ r( C+ g$ O* J
: c0 R% s# {3 p& Q. y

; M1 ?, ^0 N. ], c8.一个类如何覆盖默认的序列化机制?/ }' S! I! ~" D3 _& z0 k8 U

8 m6 }! u3 k+ AA.使用__shutdown和__startup方法6 w5 C( I2 {3 c0 G* X% I0 Y
B.调用register_shutdown_function()函数
9 y4 B" a# ~6 s4 b2 [) }C.使用__sleep()和__wakeup()方法. G/ D  a* ^1 d4 P* _0 s
D.无法覆盖默认序列化机制4 o4 q  p6 u) z0 U9 y; H/ X
E.使用ob_start()将类放入输出缓冲中
1 e7 _/ O% t, l6 _% y* n, \
2 l; ~4 w1 j+ U( T& E+ M; |0 h. L) C; x$ M% q+ J; k' w; z
9.以下哪些面向对象的概念无法在PHP4中实现?
8 V8 s% D$ u' ?* s/ e: y# [! I9 G) e  I. J  s* v0 I) H; F
@抽象类+ @% L+ i% Q; a, i
@Final类2 }( g  ~9 P' U7 D
@Public、private、protected(PPP)方法2 p! {4 M1 M2 f1 [) S/ H: d) W
@接口
2 f9 j8 W, {& D; A# a7 N4 r- _$ I  s' o% v
A.抽象类
7 _! v, }4 r% l% _6 S) T3 f/ JB.PPP方法1 ]; C! F1 x# `
C.PPP方法和接口
( z7 V7 g. l! u4 X. c/ w' M5 y# mD.以上所有都不可用0 t6 g) R# j* ^+ \
E.以上所有都可用
+ Q1 J# ]# q  j. n
$ J/ Z) t, b. @9 V; l2 F
0 M: [  T) M) j$ l: X10.如何在类的内部调用mymethod方法?
$ o5 Z- t; E6 f# ]7 f- n2 N: v
( b5 x6 V* ]. ]  z8 SA.$self=>mymethod();
0 A& \1 m. E8 }& tB.$this->mymethod();
; h3 f1 K# c  OC.$current->mymethod();
( E: z; K- e; y6 [/ m" e, b* O8 c0 n1 VD.$this::mymethod()
3 g4 f& z0 f/ e2 W3 xE.以上都不对
/ A$ v. g* a1 _( x& D3 m1 {. N6 D7 n$ Q5 _- e1 v
) i8 Q7 g4 q6 x4 Y: k, W6 Z
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.102 t4 g) |% C& P7 k% H
B.Null
& v# n+ Z% x" `' y% ^4 q4 IC.Empty5 W0 P6 P# W* P' E) r2 L4 d; T% x" U
D.什么都没有. C$ A$ G+ d+ u0 t% ?: ^; y, t% F
E.一个错误
3 |. a( _  I/ c" X  ]3 ~2 A
& |  F- i$ i; R& Y" A/ f6 Y
* V+ a  j' _: G12.以下脚本输出什么?

  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: c. A& r8 i
B.5) h) y+ x6 q" `- T  |+ v
C.2
! c5 o- P) B! H3 F9 U+ dD.Null
3 s. o9 j! }7 p# E1 X1 D/ |  x, }E.什么都没有# _7 L% \/ S+ [. G4 n
/ n" D, `" ^& o
- w1 m* R! ?0 K9 y. W* g4 |6 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.5# h1 G( q# @2 `8 L$ p
B.10
7 x; V. c" [- Y; c1 O" I0 ]C.什么都没有
# V0 F: [+ J3 H" y3 f9 Y9 ~D.构造函数将报错
* Y! ~7 A4 d* s8 Z) ?E.510
5 \  V  K: R/ K
( D- A4 h8 t* V0 P$ x9 t1 N6 V9 ^+ \! f: h4 M
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函数必须返回一个值  ^" B) y- H  y8 B
B.reduce_fraction函数必须接受一个整型值
/ H* T- F  t. kC.gcd函数有问题
/ H! F. g- J( s# M0 R$ `7 TD.必须通过引用的方式传递$eight_tenths对象
' q) i+ J* h& ^E.对象的实例不能传递给方法以外的其他结构。
8 K. z; l. d" T3 b
; O2 x0 M, Q2 f- d# G4 A; m& x* t: A# k4 _2 |! {$ J
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法" H$ o# D0 i" G3 Q  E
B.生成myclass的实例并调用mymethod方法
5 g5 _  V, [3 p# }$ w" DC.产生一个语法错误: [6 j& ~6 [. `; q* H& R9 C. E5 L2 o
D.默认myclass类最后被创建出的实例并调用mymethod()
' E4 a; L! X8 O3 B6 Z6 tE.调用名为myclass::mymethod()的函数
( ?% W6 K" V: C# D1 y) o" Q& x5 E; O3 O9 f4 ]- K. Z
. l, c$ W9 k7 S
16.PHP中有静态类变量吗?
$ b; J9 x- _8 D6 w- `% `6 U1 m+ z: {. `6 L) G4 ?8 D
A.有
1 b5 B8 `2 R# g; O: SB.没有
( G" E& p% k6 l. m; i
, m4 z; J  t, v) T9 U: ?, j
7 U5 V" j) t" q6 _+ I) j17.以下脚本输出什么?

  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
# e2 ^! ^4 n4 k8 r7 UB.2$ A: _4 O7 ]2 b; H. z% J2 f
C.一个错误,因为没有定义a::$myvar
/ m4 k6 T# \6 r3 F" kD.一个警告,因为没有定义a::$myvar$ ~! B! ?& K" {2 t
E.什么都没有% E# c% r  E0 U3 u8 w- r
6 C9 C6 R% B2 {' o

' p4 u4 M. r" C! H* h( q18.如何即时加载一个类?
9 ]8 T3 I5 {( M: b9 f! @8 P
( X* X6 h3 n* j6 o  K& B7 ^4 y1 wA.使用__autoload魔术函数
' H0 A  P0 v+ T% Y8 A( F- O# `, C) pB.把它们定义为forward类, X  j; f/ P0 M( K" @  `  N
C.实现一个特殊的错误处理手段5 d1 T' q* D1 E# I' F4 _7 C! k4 W1 h3 e
D.不可能/ H) q# [0 z1 B- `8 |
E.用有条件限制的include来包含它们" L! G8 B( a: \$ @  Q4 F
; a6 J* O) w0 X- \+ S

+ v1 w- V! w1 J2 E19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?/ K2 {0 ^+ M" r! D

5 o$ m8 Q0 j/ B$ ^) m2 j    答案:__________! O/ C  W' f# D/ j

/ E1 Y; b# _+ t, R
, l" j: f& U! J; R2 h20.以下脚本输出什么?

  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* O3 R6 S+ Q2 _- N% w
B.一个错误# E" W2 X& z2 Z$ k
C.一个警告! J* A4 y  `/ O3 B  o) q* [
D.什么都没有
4 T  J* e* D9 m. [
0 R" Z- e7 z8 G/ \; U/ ^) {! w* R0 @
2 S# N3 Q: M: m9 ]2 q6 y4 _4 c8 f
答案速查1 I! j* S0 X) z
1.类0 A2 l) Z+ @( U
2.BCD1 X; z# V7 C9 D3 P# p! X
3.C+ W1 i2 L. G4 o$ L4 Q, r' U
4.C1 P8 s% a  A7 l5 M) O) B2 b/ g' h8 H
5.A) A9 {* p7 r+ Y& f+ I/ f
6.C
! p9 F+ J& q& \4 ^7.C9 @& D* F0 Y) d7 M* x
8.C
- W& M* C) J# a" _9.D/ E& e9 o( P# u+ M8 Q1 j/ w' O* q
10.B: a% J) J3 K3 E( A2 \1 T3 D2 x
11.D! d" ^! i! N3 A" E4 R% B
12.B
% c( H3 @+ N9 x" V3 P: F1 e13.A
* \+ z# J0 P1 q; R2 }+ `14.D  N! |5 f* }( x/ o9 k0 X6 q
15.A2 W! q/ @8 M2 a+ w3 N. r9 V# j3 p
16.B
  i# ~4 T# F- [17.A" b, u: k: ]0 ?$ v
18.D0 j3 B3 D( M/ b) h4 I7 [% l
19.设计模式7 q6 N# [* n6 L( k1 s7 t. a
20.D; u7 ?* G0 e- G8 o8 g" z0 [

1 _6 q! \$ J" ~1 Q4 X6 ~, ^! l2 C' e; |! {. W
( R( w' ]7 M; T- \
答案详解' H! l# Q+ V0 f! U0 G+ N; h) o) Y

9 i! c0 y9 r7 I% B1.类是对象的蓝图(对象是类的实例)。4 A& S& a' r- z: z( e+ {
) j* K/ _) v5 ?6 a& q) `
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。4 v. @$ h) p( G5 W$ S0 v

% s8 N; I. _2 h- J( l3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
# h7 Q$ Y- w% U+ O0 G7 P4 r* H! m3 ^# F/ L7 W1 E! e
4.单件模式可以限制一个类被实例化的次数。
: @6 w( f) n- {$ ~# P  N/ b' K' v% g/ v. k. C
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。" ?7 o2 _+ i5 x- D9 T* }
" `' q$ e" e& o$ t4 D
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
" p9 w3 o7 e4 X3 y7 B) {# k. Y! Y
# E; h& a; M. v7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
$ a( E- [! s! m- @) I, B- J9 |- [6 h
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. E/ e) _- J2 z8 z
% o# I8 k" }9 u; Q) _
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。7 i+ N, @$ |9 j5 G) A! I
* a' e9 O. f6 ^( _4 |$ T$ V/ W9 [/ W
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。: S1 w8 [9 _/ [3 n& `7 T
! z( e- m$ c! C4 N
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
+ D2 l2 |+ V: ]: y
+ Q( V& f* ~# L! y# C' I! i12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。  \. f8 E( h, w
9 I# S3 u' u" U, c
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
. M4 ~; \) C1 w2 C& k1 A- f+ F, i5 O% j/ _
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。) o2 R% S# \. Y+ S! \* Z& d: _
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:+ w' r& L" O0 b4 y- L6 K5 }& `
    function reduce_fraction(&$fraction)' b0 i7 |& O& A  `0 H% I
答案是D。
! Z6 S0 P6 Z9 h7 V2 S6 z
) q" v( `- q6 N' y5 `9 T15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
- @( c/ q6 V! n+ e. e; J, h: F  H) g  a5 g
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
, ^. n6 ~2 ~6 ^8 W% K. ~+ `/ M3 R" h3 ^& }$ P, I1 f
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。  P$ F7 B6 O( m- a

8 L, P+ m$ O( }2 a- F18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。* p; b+ `# V9 _6 o; W& W

+ f  {) J1 o# X" U: y: n19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。' u: g) e: N1 ^: s( S

0 Q0 |! N3 G/ a7 ?20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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