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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
+ h* v& ?, l7 _' e! P' q: xPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。, p- P( r- Q: a
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。2 \6 U' T& M+ J! i2 ^
7 q8 p- P0 N, j* b
问题* n# t1 t9 o4 [, }7 V
$ X- C6 m. d0 k, h( y: B2 I, r: @
1.对象的蓝图是什么?% H" T* [! T+ f8 j6 \/ _
0 W! }0 Y; m- m( S. J* b5 t  n3 O9 M
答案:____________
, x0 m4 A+ s2 x
; `; w0 V" J2 v; C
+ ~$ ]0 |( m9 g5 b0 Z, [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.c0 A6 B, d% e- \0 T7 Q; ?7 [8 k
B.b9 X6 D  Q, c# c5 n# \% P
C.a, I, D- Q6 u$ `1 \, T
D.d) t0 H$ z- v" ~- K% G# g( R
E.e1 m! Y! a3 M" a; h- e5 i0 R
6 b' O6 u) m3 {
3 S/ R, J5 j  r
3.如何让类中的某些方法无法在类的外部被访问?
" n# l  M2 u9 Z# O0 `. k$ J& j4 I2 ?/ _# z/ o0 d: Q8 V/ G
A.把类声明为private
1 K! H; h" m  G) Q& b2 EB.把方法声明为private
8 g0 }' h4 I0 W0 i- C: |- JC.无法实现
8 `1 \" k8 n5 }) _7 k5 R8 JD.编写合适的重载方法(overloading method)
$ G& x+ V" o4 a9 v6 s. `0 n$ D, |4 r

; [7 G- G# @0 V- N# v/ \4.哪种OOP设计模式能让类在整个脚本里只实例化一次?6 f0 B) z; i! H  X8 I

( O1 u6 @+ V  b4 b8 f5 p2 J5 EA.MVC模式# ^9 u  b/ o' A3 e4 r, x' k
B.抽象工厂模式(Abstract factory)5 f$ |  p$ N: z+ ?- Y% e
C.单件模式(Singleton)) S8 l. }: _% o  ?1 g
D.代理模式(Proxy)5 c2 ~8 A9 S+ G- ?) d. L; ^
E.状态模式(State)9 c1 W" x+ M" o4 X
: w) B/ d0 U% s% p& w

, |) I6 F$ O" p5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
- [) q; s7 u3 }) h) x1 `, {& |
- ^7 j1 s9 p8 R4 z7 UA.1个2 B  o' R7 x3 G( j; t- |' p( h: U
B.2个
9 c5 [! h, P7 p  j7 GC.取决于系统资源
3 ~% q0 z) s- ^8 CD.3个9 Y( G! A1 ~  e  |  c0 m3 B
E.想要几个有几个: `3 N) q# L: z% c) l+ v
8 a: J* m" ?. m. n& Z1 W

$ G1 M4 j/ P. p( S6.以下脚本近似的表示了一种在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.多重继承$ s' |% w' g1 O( m6 [* G5 ~
B.接口
7 @" a9 ^4 u3 YC.抽象方法8 x5 N: l0 q7 U/ ]
D.Private方法
5 F6 p# i1 p8 ZE.函数重载(function overloading)5 [* W8 R; J" u
* W$ ^1 I' N0 n
) }% t7 e* @+ o' |+ y& [
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
6 J1 b3 E" z( A" d
  h6 G0 E+ p! i( t# z$ P9 IA.__construct
! G5 y- y: ?- W! wB.initialize) ]  }5 j+ ]9 i! Y
C.testclass1 g1 ^$ D5 ]! g. Y2 T# D
D.__testclass5 G* ~* I& z  |7 B  ?
E.只有PHP5才支持构造函数6 L6 ^+ g; Y0 k
3 Q; l+ R! x# |) X' i1 X

8 c  R, t* f9 O0 S1 V& \  @8.一个类如何覆盖默认的序列化机制?  k) b% A2 a" I2 {! ^/ _& h

+ @' A( b5 x6 W. F5 c1 xA.使用__shutdown和__startup方法  ^, g8 S: C6 Z1 b# t' I
B.调用register_shutdown_function()函数
8 x" S# [; p* Q& b: y4 GC.使用__sleep()和__wakeup()方法9 z# @/ x1 |  G# t, A
D.无法覆盖默认序列化机制
- A( c7 ?' J/ r3 v, |7 P, rE.使用ob_start()将类放入输出缓冲中
3 R& n) D1 R8 D+ O# y7 C
. T0 Z0 w3 G. M0 e8 h( w" a  l- M/ S1 q/ ], W& e5 x
9.以下哪些面向对象的概念无法在PHP4中实现?7 i  s+ U6 U& z3 M' l' X1 W1 H
( Z0 ]2 e2 \7 ]5 R/ h  w% U; i
@抽象类
7 [/ c! m( L3 G6 |2 i# I+ P4 M$ k; ]  N@Final类- v! J: C& [( {: {; n) y% ]
@Public、private、protected(PPP)方法
+ X0 y1 Z6 Y7 C1 h, ?3 o@接口
5 _& O! n/ }6 x7 P4 R; L* [
3 a: J4 Z2 Q( h# DA.抽象类
2 j8 D5 F5 l) z  Y4 N1 Z- pB.PPP方法' y/ }8 v6 U) B; B3 M
C.PPP方法和接口( p$ L6 n8 {9 |; v
D.以上所有都不可用
  B& |( D( O6 _! S/ N" e1 wE.以上所有都可用
' Y3 G; s6 q0 u8 k" j3 J, K6 B" G' ?0 n
- v6 c9 X" d  o5 Z9 h
' d, z" s* |, Z10.如何在类的内部调用mymethod方法?8 Q! v& C, a* _3 ?. K( z9 q! l; b
' i  ~# H4 m7 O: z4 |: g- B3 e5 {9 K4 v
A.$self=>mymethod();
: L  U( E4 m+ G  {! g2 `% sB.$this->mymethod();
2 Z! O, D0 d! t5 r) H+ w+ ?C.$current->mymethod();7 B; ]& a8 r' |6 d; g# o7 m" J
D.$this::mymethod()) G. T1 p1 W3 E# f
E.以上都不对, o, V, ^: ]! Y9 G$ r, K/ T9 J
" ^( o# ~/ L9 z- M- c

5 j% _- r# u$ \0 m/ u! u- g: M11.以下脚本输出什么?

  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
$ m: x6 O& u% w6 \! R& a* s- m* q4 U) a) pB.Null
$ k' O/ [- O/ jC.Empty  r6 R9 N3 k- h6 q
D.什么都没有6 d8 T8 C7 H5 L8 H/ x
E.一个错误5 D5 I! w9 g! t% ?1 P
2 P% `0 E# d: d- o# S* l' S+ R

, x( K5 X6 Z7 Z/ N12.以下脚本输出什么?

  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
4 a$ V. h/ G0 T, hB.5; I- f3 p* K7 H8 e2 b: \
C.25 }$ G- P# b5 P6 P
D.Null0 R, ?5 l7 i1 [$ c6 ~1 R
E.什么都没有
7 [: m) f2 x' }4 N+ ~! f: K$ C8 E
& `2 ]( N3 [# v- T+ K+ j5 i5 d% G, n+ ], S1 g5 {
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* s1 W% ~2 t5 P3 m* Q* `% V
B.106 z! a, H2 x* S% `0 x) ]7 X
C.什么都没有$ V, U/ X3 \: q: f
D.构造函数将报错* J$ j* j2 j/ g
E.510
+ t& [1 O& Y1 Q* Q
. V# l+ r. w; a' K8 `
% {  j! d' R# ~% |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$ Y: b) [; nB.reduce_fraction函数必须接受一个整型值
& Q1 k$ B0 g) `0 r7 J! OC.gcd函数有问题1 k( R" O4 ~/ P. I6 a+ ^
D.必须通过引用的方式传递$eight_tenths对象
" w8 A  y+ t) B5 BE.对象的实例不能传递给方法以外的其他结构。' k5 j! b; z; _/ x# _) g) g& @

( M# m$ B) t" o1 J4 P  g5 k3 f8 A$ d/ q7 H
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法6 {$ f" s4 d* O
B.生成myclass的实例并调用mymethod方法
7 t! q! j6 p' j# t( \, K, R. NC.产生一个语法错误) ~1 |  l4 }# {6 p
D.默认myclass类最后被创建出的实例并调用mymethod(); Q& h" S  B4 Y/ t/ t( k' Q8 T2 A
E.调用名为myclass::mymethod()的函数+ i* ^' J6 }- ^+ q; K+ A% @

  v1 a+ c0 M5 H, k
7 A3 N, ]' H7 i7 q16.PHP中有静态类变量吗?( r( _# y+ _2 w' J7 ]$ s. M& z
% V6 y7 k) J. ?6 E6 O1 m
A.有5 ?2 E+ E3 S1 N7 ?4 U; t
B.没有- E3 z3 h) j$ a2 G, J* ~+ B3 I- R

. l5 X) A( \& f+ y8 M- h& K( H- a7 S% a
  f5 z, X  o5 D3 \; O4 u. 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" x/ V6 H& G* t8 ^* _8 g8 A! P9 N+ G
B.2
6 [8 R/ {5 ?+ ~7 `: F* SC.一个错误,因为没有定义a::$myvar
8 V0 Y4 m4 N! F! {2 t- R1 UD.一个警告,因为没有定义a::$myvar+ N0 t2 m# Q( x0 S
E.什么都没有3 P) C1 V7 s, ?: f7 j* e

1 }# V& i9 |9 }4 J' S- B% _% D; u5 K2 l" h' p
18.如何即时加载一个类?
* H1 @, ^, S4 F+ L1 ?0 {* K% S$ z- T6 Q4 r9 u0 o- k# X* n) l
A.使用__autoload魔术函数4 R) y4 k, H' A
B.把它们定义为forward类: D8 m, O! Q8 B, x0 S8 u
C.实现一个特殊的错误处理手段
; G" a; S; L0 E& xD.不可能
9 L5 _( o2 h2 O2 q/ }# _3 ]" P1 sE.用有条件限制的include来包含它们
7 C' O0 x% Y+ p5 W/ T8 s, l' n
1 Q6 t7 a. L( h$ q# ^% Q1 L: v9 m% K' @  J% l
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?. I/ ]2 W! @* k

5 H% p4 d# l  d* W5 O) C    答案:__________4 X' g0 u& e8 H0 n& x: ?- }" f
( c9 S& B( p: J. ?$ C3 [, z
: B4 |- `$ O3 d- z) ^4 T
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
7 N# _$ G6 {+ g; P9 R; o. tB.一个错误
1 j  d2 z0 Q% N1 B+ J, w8 vC.一个警告
  [$ M% j# a" E( u: _% fD.什么都没有0 I. R# R+ X$ t" A4 B+ h/ v
% v. W% p% X. F( ~" c) X4 o# c

4 B  l# C* N. w9 e
8 L1 T0 U7 ^6 \3 q答案速查3 D' _$ i* ?+ a" K! P) c$ u
1.类
% }3 ~' q# A) o0 y9 t2.BCD( O* J& {3 u! _
3.C
! b- \0 V2 K! _4.C
0 f6 b% q) l6 g1 M% u0 y5.A# }- C2 a( l; A' U6 m- Z: M
6.C
. v$ c1 [# v. ^- a, R- Z3 Z7.C
) `8 A/ i8 `% h7 j) d$ b8.C4 l8 {  S6 p8 u+ W
9.D
: ?4 b, E& T1 n. b& R10.B
+ [6 u4 C  O9 @' i2 w9 A; N11.D
% n- u' T5 V# ]8 @* {12.B
( i- c+ T* @' a* w$ P13.A
7 O$ o/ {3 _, T* E14.D
8 F+ U2 U5 R' I, \8 M15.A
+ c/ g+ G$ W. ?4 N9 w5 t. [16.B
# J) ^$ n2 _, p17.A7 G$ j( P/ k, a7 t% `2 w
18.D
4 ^- Z* p. o3 _19.设计模式
4 @$ }, H1 o9 R5 I' y* q4 _20.D
" g1 X5 y& i/ E8 Y+ n& X' ~
: q$ X& x& y& k. y! O
2 _& i; o3 t$ I$ Q, e0 W; Q4 {' m7 ?# S! _2 {* ?
答案详解0 _5 `, g" H: f
. c9 R' a) g' W9 f: f
1.类是对象的蓝图(对象是类的实例)。
+ `/ g( n6 ~3 D; C+ Q5 e
) j* y2 G& Q4 j( Q2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
% C. P* I/ \+ p# m6 J5 u) [2 ^
6 W4 f# B1 f9 ]3 h% }# J+ p2 D3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。5 }6 i* b  F* I- v

, @' X2 ^8 H2 q* e% F4.单件模式可以限制一个类被实例化的次数。- G' h% V+ ?3 F6 n  ^$ j
1 l5 ]8 I+ Z; \" d
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
$ `4 o+ C7 o7 R
0 x& T; f1 n) f5 W6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
- Y6 K+ z% t0 K3 K8 T
% b+ L5 k2 }' z, E1 O  r: r7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
/ d# ^- t1 {: E0 w) u+ h( p- n9 `
* E! d5 X# j" W9 M! b+ X' u8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。( _; f  y7 b$ L5 q# o) q2 ^

3 L8 m+ y- S3 Y; c' P6 F; h9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
- C( j0 R, w8 O+ F7 K( t# J5 P  j! }! A
+ p  C5 U8 x" s  b3 p4 B1 c; C10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。) o. }8 W/ ^/ R8 N
0 ^# J  G/ _/ r4 v
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。$ P2 J# {& k% f2 y) q2 Q* v

9 q- c- Q) A' K2 [# p/ S12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
' [' o8 b+ P1 a2 N5 h4 R
$ ]5 J% T: Z! Z. X9 w8 m13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。+ f% g. s" N9 K# m

7 _2 |8 i& K$ i9 k: D: D6 |14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。9 L: b3 O  q/ K$ C2 B2 T4 P
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:& r: v+ z* d$ h. y. g" M6 h! @/ Z
    function reduce_fraction(&$fraction)
+ h' B/ {/ V# S0 q答案是D。- S' X7 a4 H; A7 k# ?0 H+ |

8 I; E9 Q6 _; u15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。2 G9 T* ?; W. M1 ~6 X
+ Q7 n! I* ?" O" j* H
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
7 H- k7 @; ^, H
5 E) J( h& ~- |2 r17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。/ o4 ]" l+ c0 k6 p

, e2 r$ P7 v1 x0 G2 X  D3 R" }4 u1 L18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
) B7 \% W7 F" o5 \( o4 ]: P% Z; P! B) @+ n1 n- {0 Q5 L
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
" H7 ~& N/ D( I
( c( h2 [4 u5 f20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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