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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
$ F5 D+ q8 @/ s% G; K% ^PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。- P) s3 t6 |2 V% K/ e$ I
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。+ V5 e& o! O8 M: g/ L, Q
. K( U; c/ c3 T1 w1 a' ?4 v
问题
! f8 M" q% d+ K; @8 y4 Z+ o* R2 E! H
1.对象的蓝图是什么?
& N' s# f: |1 Q* y4 u1 }4 L1 u+ v. w" o. D
答案:____________
/ G" Y$ l& }, s! e- D
& L/ |1 {, h8 ^, Z' m: \% t. I3 |) c+ v- g
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.c; b8 o# v) _5 |$ D5 @( h1 a
B.b
5 a' s1 z) c: [3 \  T1 J" rC.a
5 y: x- n8 s' b6 AD.d
+ o9 P  s6 U, n  N  U1 eE.e
4 e: X* \+ m5 q* T; {' f) ^# |4 [; g

  e) u* C  {' y  v$ {6 G! Y4 \3.如何让类中的某些方法无法在类的外部被访问?
4 W  X- ^- ]6 _& }! W
' ?0 V3 r: B  I* _* N; ~A.把类声明为private
/ O( }" V1 E# B+ Z: fB.把方法声明为private( h" d% l  p1 X0 U% }
C.无法实现( g! @0 c% ~( t1 t- G  o" |
D.编写合适的重载方法(overloading method)
0 s* ~) A' d% T2 p8 x: a
9 G; R1 ?. c' ~, k. U3 U
; y1 d/ y3 s5 i5 o( V' {4.哪种OOP设计模式能让类在整个脚本里只实例化一次?: V/ \6 C' x8 P; Z) X! k
9 d# c. f/ {  a! g. N3 I% x
A.MVC模式" H! X9 [9 |" k! b
B.抽象工厂模式(Abstract factory)' G" a! \; p& [* `- V* D% J
C.单件模式(Singleton)
9 X1 y3 g* X5 Z5 M0 w; a% W4 qD.代理模式(Proxy)0 g( H9 U) d  ?7 o8 X
E.状态模式(State)/ n. u- P7 b* O. b- D% }! K

- }+ z( y& m: ~
9 |  X" h2 U" f' X/ j5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?, [0 z- X/ A+ n
  {+ w  }  V% w  G, X6 T8 K3 O) I: h
A.1个
: d( `8 _% y! v0 FB.2个
) I8 `3 _) t; Z* q' [; b4 QC.取决于系统资源
+ Q- f' c. o% w/ _8 B8 H% aD.3个
, s* K6 u9 H8 T1 [# L  rE.想要几个有几个9 J% {! m1 Z/ {! Y, c
+ }( J  l1 i7 T0 [. b# I% S

( l6 y9 x$ \5 n2 X- M6.以下脚本近似的表示了一种在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.多重继承; I3 K1 `- r8 P! x( }' \2 L
B.接口
. Z! r. U! ~9 P) }C.抽象方法
' ~7 J9 k  k) pD.Private方法
1 a3 ?4 x- z) k% uE.函数重载(function overloading)
/ X1 \; D9 l. p
5 q% ?# t& `3 ]  B4 n
% }- H& P, d; Y2 {; O# `& V7.假设定义了一个testclass类,它的构造函数的函数名是什么?* d# ?: g3 V3 e

  a1 Y5 f+ W/ s+ ?A.__construct5 ~& _! o# {  T8 d
B.initialize
6 V% W( n3 o4 k) `8 ^% aC.testclass! \& j; w, A, F! Q) C8 }* H
D.__testclass' Y' A" B' D  {  W2 i1 ~
E.只有PHP5才支持构造函数
; h) D* y/ i7 g4 [2 B1 M1 t3 l7 U4 S, i! a3 O

7 t" O: G7 C. _- T" a+ q8.一个类如何覆盖默认的序列化机制?
: `# Z- _5 v( R# U0 O3 q" B. L6 `) a" B1 Z0 F
A.使用__shutdown和__startup方法
' B# U+ i" K$ u3 A* RB.调用register_shutdown_function()函数8 A2 `& v6 q# F0 ~
C.使用__sleep()和__wakeup()方法
: i2 ~0 M6 `" m( s; }7 L4 s- }D.无法覆盖默认序列化机制
4 x) B3 i3 h8 R8 qE.使用ob_start()将类放入输出缓冲中
( ~6 B( N) p, }% \) Q' f% T
+ T# d" G3 b: S- P' y! d" [/ y  ]; }. [2 K
9.以下哪些面向对象的概念无法在PHP4中实现?; n; ]. t- K3 J  f2 C- z
+ y" S0 S1 X1 F- B. X
@抽象类2 I% |' e) ?4 O( M) f  b2 E$ H7 h
@Final类1 A/ ]: |7 U' L
@Public、private、protected(PPP)方法
% @) h# ]5 b$ a2 Y@接口
9 z( Q$ ^' ~  G( ^2 Q7 b& y# Q, N8 _* \' @' A
A.抽象类
) [$ b- c# S% j8 B( e. {B.PPP方法+ T0 h3 _; Z0 S# k# _& T
C.PPP方法和接口
0 O5 I1 `' I* l* _0 m' kD.以上所有都不可用% a0 D) y6 b) y: q; g* e
E.以上所有都可用  \) K, j$ ~  j

9 [# d7 R* P. S! e3 j
/ n. F& H. a) V2 ~: m9 E10.如何在类的内部调用mymethod方法?9 @# N$ p3 J& l& z6 y
1 }7 O1 n* w1 n+ k4 l# b* l/ ^
A.$self=>mymethod();
# \" Q( f1 R" XB.$this->mymethod();+ ]% e# t; [7 r: Q
C.$current->mymethod();
  K2 ?/ w0 H* S: T: N; [" mD.$this::mymethod()* }( E! I% a4 W, b) m5 w& L8 J
E.以上都不对% a4 o* h7 P5 W" `" q0 ~6 [

4 l, l! \- B9 {- f) o3 k7 _
) L" k* f1 k: z0 N- Q11.以下脚本输出什么?

  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.104 m. k2 I% R' a" r
B.Null
8 E( @% [+ t3 j7 w5 v8 M9 a  qC.Empty+ W# r4 q5 O* B0 p( h' V
D.什么都没有( K3 P$ b& T% z# h- K# y0 G
E.一个错误0 r& S* b7 `8 Q# W+ A
3 L1 @  N9 y5 a0 a8 e
2 j0 x+ ]( T6 b  c4 D$ f" c
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
+ u; v% I6 f4 S. q, Y( k6 R9 IB.5& q& d$ u  V7 C4 K1 I& ~$ n
C.2
! {1 z, G8 M$ f$ A5 B3 c( [: bD.Null6 p7 ~0 A! C/ }" K
E.什么都没有
; ^6 T% X6 P/ t, W/ ]' z  |6 h3 |- q. F3 z$ b

* Y2 l# P0 v% y/ r6 e) e" G13.以下脚本输出什么?

  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
+ X" H1 k# B! _+ wB.109 N5 R3 F0 D, H" U! q. g
C.什么都没有
5 U" r/ P2 I& |' `; @D.构造函数将报错/ O. b6 _& A1 D
E.510
( q8 J( f+ Z( s5 r5 ^) h: T4 W5 k* x2 Z9 A- j0 {

, d8 p) H8 `; z* j0 P" u14.考虑如下一段代码,执行时,$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' ?) V+ Y/ f. b/ B  eB.reduce_fraction函数必须接受一个整型值9 ]) v& J& X& ^. d
C.gcd函数有问题
" v% V6 {! ^2 J( i0 e  sD.必须通过引用的方式传递$eight_tenths对象" L2 F* a3 m: s+ i
E.对象的实例不能传递给方法以外的其他结构。
( N5 {1 r& K' q2 \9 z  [8 z. O! T9 ?/ H" u6 }) x5 i
  e- t# ~9 ^+ S
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
$ _/ y8 V1 J$ _" R9 K( C% FB.生成myclass的实例并调用mymethod方法" p. E& u1 ^7 ?
C.产生一个语法错误
& N7 q$ |, ^0 w8 ?3 X7 eD.默认myclass类最后被创建出的实例并调用mymethod()
& D6 f, C  {( ^1 F/ AE.调用名为myclass::mymethod()的函数
9 Z; |% g4 h# g) s' K5 @7 w* |
* i# u6 b6 M6 }* H- W& ^; @: {1 g
  z; t& M9 L. ~3 p4 ?$ B2 J* _16.PHP中有静态类变量吗?
; |. g& }, R1 F/ R  i; P4 u6 W9 @  `3 Y" W9 X. f
A.有5 Q0 Y! E; X; R; D$ j1 M3 ]7 p
B.没有* L1 ]/ \; c0 H9 d

4 E( |( F) ^7 b, v- `& Q0 t! z% ^+ f% L& a! T' Q: y1 z8 y' ^* J
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
% L( b% f6 ?( fB.2
& d' F3 N! s- ]) f+ QC.一个错误,因为没有定义a::$myvar
; y# {3 p0 A" ~! W3 ]: nD.一个警告,因为没有定义a::$myvar
8 I8 j! z# w7 N. z* ~; tE.什么都没有1 q" M# g( x6 n' ^( F5 D
# v/ `& ?$ k' D) F# @4 t
8 n1 R3 q1 @" }* b& N2 B, \. i6 ~
18.如何即时加载一个类?
5 c# d! B3 o- F* y9 o' a, `! A6 a* E: @& ?! M
A.使用__autoload魔术函数# i" ^' P# @; r* ^0 N
B.把它们定义为forward类; {- B1 F( e  s$ X$ p+ ^) g
C.实现一个特殊的错误处理手段* N! o- G6 t2 b- R: z
D.不可能- I& z1 E5 A9 o: ?# ~$ H5 {
E.用有条件限制的include来包含它们: |* F& O5 e. O) P& w% y

8 {+ [' k& ^" M9 I/ A- v) z0 P- _  m7 N7 B
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?' P( B2 M6 N/ H$ c- t# x
! l6 g% J1 Y5 n2 t6 B, X, S/ R3 f
    答案:__________
2 h& Y8 @/ Q; a) d( ?  ~) I8 o0 ^( p( ~9 E6 ~

7 ^! x, K0 t! ^+ E+ k% w8 |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
% f- t! r; P' ^5 QB.一个错误
" M+ ?/ f% v: P( `; B( k( E# lC.一个警告
2 e9 T0 j+ @  }! qD.什么都没有) ]; f! S: }. p

1 U! ~6 U$ v8 o5 C8 X6 f
3 U& G  I- K; q) L: p( [# b) d1 I3 m' k4 t
答案速查* C; C3 g; Q1 h& F
1.类
+ h% d/ i/ l1 B7 ?& U2.BCD- n' d# V8 L6 S9 c' O. i( V$ E
3.C
+ y2 A/ Y  Z# H$ \7 g3 u4.C8 {+ j1 U3 {0 M) }. z/ }6 m" z9 |6 ?4 d
5.A
7 \: z6 n6 W7 J  \* Y* n- M& d6.C
' T' g" x3 R* |2 @2 n$ i- y7.C
0 o9 @) K( P0 R7 E. z- c5 t! r" R8.C" Z9 ^" k1 I4 L5 o) h
9.D
" I8 l, @$ W2 K: s10.B' r/ [9 H7 X  K! b4 `
11.D* A4 W' k$ A7 D8 h
12.B
: N: b, k; P; [; {0 |+ v1 _13.A9 d& s; N8 A5 x: K9 T9 f2 B* y
14.D9 W. h3 W& Z4 U  n7 z
15.A
4 X: w* T* s" J  i; A4 E16.B
2 X1 q* W  Y7 H, b17.A
" O% J# L) o9 @) T! T18.D8 E4 o2 @; f8 J5 O& E( w
19.设计模式
; W5 ~0 U2 B) ~8 Y# C20.D
; s: X/ j, B/ v+ C! `' a/ y/ w& O3 @( O

9 n& |( f8 d8 Z; y  J$ p. T: S5 Q, W$ n, e( i9 G& X: [
答案详解" L- D; d# p- B3 q' b4 u, I0 ?
" _3 @& S- Q6 F5 m  }; S
1.类是对象的蓝图(对象是类的实例)。0 V) O' O9 m3 a6 [% r. W

5 ~/ @' v0 h0 M% B2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
5 c, b1 E! S' @$ x* L, A9 j
  Q) W6 I9 n, I1 w9 _- c3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
, Q! @' N: x/ Z  Y9 e/ V1 s- r; p
( N6 k% D! @: n2 ^0 S4.单件模式可以限制一个类被实例化的次数。$ D7 b7 m1 _# v4 t$ m( z

  U5 Y+ ?2 F8 f: I+ k5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
0 _/ @* E6 F+ a& G! N4 m
5 E/ G# M: B+ }: E" Z6 A  q3 j0 B6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$ ~0 X: @8 P1 X% l$ N6 |- r8 J

$ S% C- g( n2 x  R) F7 S5 A7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。  A7 ?2 w+ T4 G
/ J, ~$ w+ \) e
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
/ Y. S+ I$ ]- w8 [2 G# Y* N) B9 \/ _% B
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
& D- p; k7 d5 z+ `$ N/ P) w! W% c6 A) E7 t. p7 `
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。5 R6 v" Z+ H" J/ }+ }4 _' F

; @  S$ [% N; v' I) Q- R" B11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
5 w. T- E% M; J9 f5 N0 t4 [. b' Q
8 U3 d7 u! f2 B0 \. n/ R* O12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
. w; \( [5 P4 S
& w- b5 L  Y1 F13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
6 l- x0 U  s0 J. h4 ]- @/ |: Y& K8 H' L: F
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。1 |( U' L- T" `( E5 ~. k- Q
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
: `4 P7 g( k9 c6 V) h    function reduce_fraction(&$fraction)* {" O* h! f. L" F" @- O5 S/ n
答案是D。, s5 z4 U+ F, c. H/ j

% G; m7 i6 V/ w5 a" H1 N8 V15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ u: g8 F& M, {, @  P( M
" v+ @9 B! p1 P: ]4 o. J' u& ?( P
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。4 r. Z$ V, n# N' Q0 ]
& h) J2 |' m- L3 p7 x0 ]
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 m2 z" e7 z- p2 F/ R; Y- B7 Z
/ Y& K) S+ y7 a+ ?18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。9 U- u/ Q  C+ I# k, M- [7 o) K
$ [* P5 Z  k" U% q2 K
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
2 {% k4 J; b/ B% t+ S  R7 t+ X, `
: v+ M6 ]0 l6 [' @4 r20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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