返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。7 p/ i: V' [9 L1 P
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。! N0 S3 k: M6 K5 z& {
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
# ~/ c9 t8 C) d1 s* N9 j: l5 @# l4 g
问题5 D5 j! }+ k0 \7 ]0 i. j: e

. M9 M. M) u1 K& p2 |) H6 ^1.对象的蓝图是什么?
$ W6 U& ~+ b6 O0 U- j2 h% U; K& x& f4 R. Y
答案:____________
3 {  q/ q$ b2 w) k9 y  z. J! J; G  C- l
0 k; o; }! P* H5 n% Z3 I
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.c5 O4 l1 z4 k5 V! b0 O
B.b
9 r. R: }* Z* B( K0 Q! j1 [C.a$ g8 }: g# c  o) C, ]; D- h
D.d
7 v& M3 Q0 B0 N6 Y% oE.e: {; ?5 t) Y; t5 q
$ h+ ^0 C6 D- p/ O: x! Q, t
2 E' I, Y+ m, Y9 s2 F
3.如何让类中的某些方法无法在类的外部被访问?8 o2 V) w. O7 U9 |. n1 b
. V2 z+ G" i, _7 H+ n/ u( o. A" c
A.把类声明为private
4 x% x' T( s6 B/ f+ {B.把方法声明为private4 B* |: ^- R1 B& P3 n$ S: x
C.无法实现2 n& m& O8 x2 g0 b8 O8 G$ e
D.编写合适的重载方法(overloading method)' D# t# D" |9 a

5 v! H$ [) D. ^6 Q1 y( m
& e) r" Z+ c7 b+ {. j) N4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
; t7 B& _; C8 U4 @; a* A3 K/ m% z4 A- V! k' f
A.MVC模式
5 e2 A/ {+ w3 v6 vB.抽象工厂模式(Abstract factory)+ X0 N; d1 U5 o2 ^# F$ l. S: y5 a
C.单件模式(Singleton)$ L3 F: v' y  K+ A1 R+ ^& g
D.代理模式(Proxy)* n1 s: l  `% F
E.状态模式(State). F  Y2 c$ m, R
0 Y: [5 n: }$ \$ }% M
+ v5 B; @$ O/ I6 }+ F
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
6 F6 c) J) a8 k/ C" r  @0 V# f$ h( z& A& x( q
A.1个4 D8 q# f1 U% H2 b3 y/ p
B.2个* |, p% y- S9 D. F9 r; T  Q
C.取决于系统资源
9 m0 O1 u# F4 ?* ?D.3个9 ^% Y5 e8 J$ j6 x* }# y
E.想要几个有几个3 D3 G7 D7 a! L1 E
+ a4 |  `4 J- V" P* |2 s# O2 ^! Z
2 M2 C. N( f0 z+ h; }3 N; I
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.多重继承' u9 F: H) R4 c2 w6 I7 `
B.接口
+ D! c( H' k% bC.抽象方法/ g7 L6 I+ |+ e/ g8 U
D.Private方法
6 n7 d( b7 t% v1 h7 L* h# B" `E.函数重载(function overloading)% M2 G6 {" J' I; {8 O

( N: m5 g/ V1 I2 g$ v( D3 p( r0 d% E& \" d* s
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
0 E. O. a4 i! y+ {9 e$ J4 l8 G1 R/ L. D, P9 d. }; Y
A.__construct. S* ~  L8 l. I7 d: }! c( }
B.initialize
) Y4 F1 s( u3 iC.testclass
5 R+ }1 {( H; H( y3 ?0 _. L) hD.__testclass
$ f0 G3 C% t5 b9 E0 ~% r" S* EE.只有PHP5才支持构造函数
- L( F' f  Y" [- H
% a) R/ G. x( o2 p. y" @( ~
% z2 C* \; v# k+ j2 z& E8.一个类如何覆盖默认的序列化机制?
9 ^3 e- W+ P' z# E: L
3 }& ~/ \+ y' P! I" D& OA.使用__shutdown和__startup方法' U% Q8 q7 U5 @/ U
B.调用register_shutdown_function()函数/ A4 `  c& \7 k" F+ T
C.使用__sleep()和__wakeup()方法
' j  q' k% L# s' @D.无法覆盖默认序列化机制5 i3 W+ S% U0 [9 r  Z7 k# q
E.使用ob_start()将类放入输出缓冲中
% E  g' J5 u" ^0 m6 y, w; K. I+ s0 r
; n" b; I- n6 L8 E5 z# ~
9.以下哪些面向对象的概念无法在PHP4中实现?
  o; |# N# |7 d0 q) z+ V& W& t4 V: y6 g2 q: W
@抽象类' i# ?! s, `2 q5 A9 W+ u3 o8 j! h; p
@Final类
8 O; K; N/ J& K: K& N. T( t! [6 t1 W@Public、private、protected(PPP)方法
+ I7 m) j5 n3 \: x* Z4 P@接口2 ~2 j9 y- @1 ~* ]- F' ?9 H9 J

: I0 e7 `/ _; [* j# v4 ]% C* ~# YA.抽象类) @5 F6 ~3 c0 i) Q; p$ ]
B.PPP方法) J1 W; ^$ P. v
C.PPP方法和接口+ x6 x6 b, C! A% U
D.以上所有都不可用
; l. W  }, y1 q. E! Y7 ]- VE.以上所有都可用. K; S* i" k( ?6 `4 I

; b+ m/ v5 @1 w$ r$ D  R5 P
3 p  i3 X# r3 j  \# K10.如何在类的内部调用mymethod方法?* f( F# l- L4 l/ e

8 W' O9 W4 Q, r: dA.$self=>mymethod();% D/ [+ c9 ~& d1 w" K6 H
B.$this->mymethod();$ {1 \1 h4 i4 q$ }* D& j! w3 A
C.$current->mymethod();
/ ?5 R$ |3 m& w3 p: lD.$this::mymethod()2 C  T+ X9 m/ w" B  \+ J3 [
E.以上都不对
  _, p# ~5 L/ n1 h- e3 J4 R6 M0 N, E5 I/ q+ r& B% S

7 e) `0 n9 g( 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.10
. M3 Q" M9 Z4 `9 K5 AB.Null
: ]) ~, ^0 W+ b6 i: C# g9 E( [; L  aC.Empty; d1 [, L$ _) k. |. a* P
D.什么都没有6 `" S" c0 ]: k6 C. A4 b
E.一个错误
# ~5 ~# [  a5 o2 x% M4 o( J1 Y- t7 F

% q" C+ e$ l# k" m; @; Q12.以下脚本输出什么?

  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
& K; Q7 u, i% t4 aB.5
; h/ w( K: }, S4 V0 \C.2& y: C% r0 o* m
D.Null
* V" h, e4 \: M6 s% [' W* [E.什么都没有
. p3 F+ o" s9 m
; y8 h. R( f4 o7 g! g2 e9 s; K
) |' p. t% E8 b. J13.以下脚本输出什么?

  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
. D( {6 h) d' a" G# VB.10
( G+ T' B6 @! U6 _+ c) |% j( [C.什么都没有- ~/ N5 u4 _; o6 t% ~- r' V
D.构造函数将报错4 p; ^2 g' t$ m. F# p5 D6 Z
E.5104 U+ U+ L3 W: T3 s) A  Z

: p4 G) U& n7 {5 }' s! y
6 r2 F9 w: G' }8 c7 i14.考虑如下一段代码,执行时,$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函数必须返回一个值
4 j! ~0 S( E9 xB.reduce_fraction函数必须接受一个整型值
" Y4 @4 s( J3 ^% Q! VC.gcd函数有问题
3 e9 J; Z! v& r0 rD.必须通过引用的方式传递$eight_tenths对象
  q- Q9 P! i1 X+ [& IE.对象的实例不能传递给方法以外的其他结构。
0 N* T0 V4 p; \  V* T
" j( l6 H3 I' i, W+ x/ V: y. V3 i/ F
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法# D/ W: O% B2 x
B.生成myclass的实例并调用mymethod方法$ _- m; X0 Q2 @9 ~/ R) f
C.产生一个语法错误9 b2 X$ r+ w: d" s* q3 k% F
D.默认myclass类最后被创建出的实例并调用mymethod()
" K7 Q7 @. u; J  p1 TE.调用名为myclass::mymethod()的函数
. u2 c; Z4 k0 h) P1 F. W- n  C3 b% }1 d1 j% `$ |

  v* X3 F! q; x: j* n6 s. t  \16.PHP中有静态类变量吗?) h$ @1 A3 ~: W! G4 {+ c" _) O

9 A. A. [1 E# a* w0 @1 |A.有. w# n3 J5 c- T: ]" a9 |
B.没有
7 y7 y. z2 a1 d7 S7 b/ Z1 o: g  h0 w# h6 B0 l8 Q- V4 A

* w2 u7 F" E( k/ }; m17.以下脚本输出什么?

  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* K# @/ `7 R* ?' k% I) U$ \
B.29 u- E9 ?1 [8 A, Z7 h4 Q1 R
C.一个错误,因为没有定义a::$myvar
9 p/ i. w& L3 S# UD.一个警告,因为没有定义a::$myvar
# U5 O, |9 G8 C% uE.什么都没有  M* i  T6 }9 M) H

6 n- p1 M! _" m: j& K3 o, i1 p- R0 R4 u( @2 f
18.如何即时加载一个类?
, L5 p. E5 ]% m2 m0 K' o8 d" ^3 \* g
' N! |! z, |$ J8 Z! J3 d9 I' @7 |A.使用__autoload魔术函数
$ c8 m5 K8 c' b, lB.把它们定义为forward类
; v# U: K* b: a  D9 D( tC.实现一个特殊的错误处理手段0 @* R# p8 W, G( g/ s8 q
D.不可能
1 K. n/ y8 p, K4 a7 U# ]E.用有条件限制的include来包含它们  U1 d7 w0 G5 y; W0 N
7 c. Z+ \7 f* U8 ]0 l4 a/ a( ^7 z/ B" l
6 m( ^5 E/ o+ W
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?' h- |, ^5 |: e# I

6 \( O* ~2 C' ?0 s& ]    答案:__________! ]* [6 i4 ]. t8 M; p& P* ~  Y2 ?. e) Q

9 O9 I7 D: Y7 y( @$ K" C: G6 g. \& U( ^$ N
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
! J% Q( M, f7 N1 ^" @/ t, y7 a1 mB.一个错误
. J* J8 z" T* Z: c  ^C.一个警告
. h2 L8 a& V/ t2 C) S; X. w$ fD.什么都没有' d& _: f( {8 z) K# R

* w2 D1 R- f* m6 u# Y3 z1 g
* g0 ^. s) e* L; p% _4 `/ U% h
5 e$ H  x4 _& m# t( f答案速查3 B# A, i+ V+ G8 j3 H* H/ m
1.类% E5 [5 S3 `, J, R! m8 _0 Z
2.BCD
5 Y( q& l8 R- K. j5 Y2 L6 v3.C
  C: O# K4 Z3 n  u. q4.C
* l1 H( _4 R: ^+ I5.A; g0 Q8 i# q+ Q, s) B& D' P5 j" c3 H
6.C, n. T3 s: Z# Y" `. ?  s
7.C4 \2 a) n6 @, u) t5 |
8.C4 D7 }- H4 _- j. K7 |0 L* Z
9.D9 b. v# [, J5 ^# L8 c- R
10.B
) h+ p% d. S4 u/ h9 t# W3 v11.D
' d! p  r+ S" U6 U- Z8 h1 c12.B3 n* Z( Y7 i1 [# }, S0 x' G
13.A
# S( T% Q4 T/ \0 U14.D9 y0 p) F$ D, O0 D5 v6 V
15.A
. f$ [6 j- r' E" v" N9 A/ V& a! R16.B4 y, z6 p4 O! T: T- x0 A
17.A
7 E$ b4 P- |* v8 N6 J1 L9 p0 j18.D4 a. B  A/ p' V3 p
19.设计模式
% N5 P2 M' b( K  F% p7 j9 ^20.D3 y8 [/ X/ G+ @* p$ H: G
. {0 z' b+ I& U
! |5 k2 l- a9 _1 {/ z& S# ?* p! |
9 A1 e/ e, N% y0 Z5 N
答案详解. V8 y3 C# N9 D/ I

' s+ F4 {3 I6 B+ X1 i5 H1.类是对象的蓝图(对象是类的实例)。2 p( X, r' Q! c3 E' q4 z. W) U4 x
3 g- `- U* j5 i2 ^, K
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
8 Y7 T/ z# S1 B5 `/ n
# F6 c8 s4 H7 D: ^- B; u3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。0 Y+ H# F5 c  n# K  z2 M' u

' h$ K- A& x1 j5 i4.单件模式可以限制一个类被实例化的次数。8 A( b% {% Y' n

- ?/ P" d% n8 L0 W( M- ]6 f5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。# c: x  @$ W$ J: ?. |5 n  g
8 E, r0 d: }5 Q
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。) g+ z+ O" G, Y2 ~$ K. B* z
( u2 J9 w3 q8 D3 |
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。0 v9 O# C, m5 g% F5 @1 j

( v. ~5 t( k8 O- h) V1 n8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
# P* I* C# s8 J2 R. c
6 B% b1 T: r& G9 X' R1 f& T6 N9 J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
$ _& d  u, `) X$ @6 k% n2 E: S: q3 Q( t$ f4 `/ |% u3 d
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。# X! E8 E& j! u  u$ `  m
! J$ x* M$ l: o3 s: D$ o
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
0 A  p1 ]1 k' d2 c1 l) w
( X6 p, h4 k0 L12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
! A* p* }1 r* c$ v" R* j: ?9 D( K4 N' Z8 F# z- ~0 h
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
$ @- p* g( Y. I# Q2 v$ ?; g: i/ C" f' U4 O  F# M" S% @
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。& R& V+ D% _8 e6 K+ q6 G) M
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:# P  q3 m) E+ r' m% J
    function reduce_fraction(&$fraction)5 @. p' g  A/ U7 m
答案是D。4 ?3 K2 |: b/ H

$ O5 q; ~# A% V) m% E5 Z1 D7 P  ]15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。0 G# m% J9 Y- g+ E
9 \" _; ]3 }/ W* p
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
6 m- w/ \8 _. ~1 w
4 j5 K! C/ R: q' Q17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。8 \2 {5 x" u' |& }) i1 P

9 G# Z0 P- ]: m$ _0 b: n18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
7 e! U# M  M- v, @; Z+ E/ B* m* M: C7 e3 E
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
( U) w" P! k% ]: A) c
0 K; x/ o" ^0 \. p+ ?6 d20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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