返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。& K3 B2 l1 O+ l$ S
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
* Z; n; G8 s( t本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
2 m+ G0 z. H* F9 \, t2 E9 \5 G* r/ u6 G" p. f
问题
& b) `3 S* Z/ H
$ P: A* |4 u3 @3 w* y7 J7 K1.对象的蓝图是什么?
2 u+ X. g# \! t7 |. x- ~% i' f; n! L& Y
答案:____________
7 @7 H' u( k8 J+ y8 u% E" ~. E  r; H* J8 z
' |6 z$ c' E% W. i" W/ j: e0 e( o
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+ m+ P* E) b1 T3 ~7 n6 O% U
B.b/ V! V! E2 O' @
C.a( X3 F1 z  _& `7 i( v
D.d& F% _7 s0 o, ?5 k( O0 {5 @# t
E.e
2 D9 Y4 f& i7 ]5 @9 A3 L' ?/ Q  X

6 ^( S* K( D/ y4 u, w$ ?3.如何让类中的某些方法无法在类的外部被访问?
- ^+ u; F- E& y: A8 S3 R, [8 A5 p4 q+ H) J' |6 J
A.把类声明为private) n& e# L. \+ q8 K$ p0 l* G/ i, d
B.把方法声明为private( x0 u. ^5 e6 t) A/ w; ^
C.无法实现
1 `) v- j! D! g( O0 e( V2 XD.编写合适的重载方法(overloading method)! Z0 r, K* ]$ Q2 Z* ?( D

  D' w5 c! q2 j* t9 ?0 [6 ?+ d7 h. l
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) T' E9 f0 J9 X, s9 R9 p" l' P5 p) c
- x' R  J& |% N1 G) P
A.MVC模式) S: m) d0 L6 a: A
B.抽象工厂模式(Abstract factory)/ v# i) U0 J+ d
C.单件模式(Singleton)+ ?" t* n3 i* C1 L, u
D.代理模式(Proxy)5 C# s9 q; r) s  ]9 x% q
E.状态模式(State)) {# @# _. `8 s+ o+ Y9 k, H" Z5 ?
. H& [- |/ f3 D9 _
' Y9 M& }9 {8 f3 a; z# m
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
9 V$ c* U8 X  P/ Y6 `5 o+ {5 k! M1 O/ P' n/ j3 o
A.1个' d. _+ c9 [5 _4 k6 V3 O0 k- a3 a
B.2个- Z: O5 a1 ^6 A7 w
C.取决于系统资源
1 M3 x* @; z  `1 U2 ~) |D.3个
/ y  b3 Y, m' I) zE.想要几个有几个
- `8 h% T7 w6 d# a
6 e7 k' A' l! H
9 U; l& @: {5 i1 Q, V% j6.以下脚本近似的表示了一种在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.多重继承
# Q3 g+ S  c7 ^4 B7 g0 ~0 wB.接口  l  k9 L; v# C8 h
C.抽象方法# A+ F2 b. P! s( A4 ^* f
D.Private方法
3 F' G1 Z! s: ~3 y5 VE.函数重载(function overloading), W% S) @$ a: ^) A4 V8 v
& W" y1 r  q% x( j/ R& V# [

" a8 x0 D& B' [( w5 Y- c% R0 X7.假设定义了一个testclass类,它的构造函数的函数名是什么?2 V; c9 ~, j, W
! F5 y7 Q! @) s
A.__construct6 J, Z0 P$ {. `! v3 f) S9 i
B.initialize9 E& R4 r* H/ ]1 u% K
C.testclass) I  _1 \1 }  R' @7 Q6 z" L
D.__testclass
. J- L% k' ^. ]# q$ n7 RE.只有PHP5才支持构造函数
8 t6 `3 K/ C+ A0 L# c' ]% M+ d: j3 P& N  t) O
/ S% u" p( Z$ S2 Z' ^
8.一个类如何覆盖默认的序列化机制?2 {- ]% D9 r" D% b
9 [( q. l- N" l5 \. C4 x
A.使用__shutdown和__startup方法# C3 l* b5 T9 I+ ?& F& f+ ~
B.调用register_shutdown_function()函数
  ?1 s3 i' s. K# zC.使用__sleep()和__wakeup()方法
! i) c/ H% o8 F8 u/ ]D.无法覆盖默认序列化机制
! ]: U. a3 H7 y  l! v2 y& IE.使用ob_start()将类放入输出缓冲中& Z( n6 M5 R* b8 M. v

0 |. a, O6 X; Z+ c, c5 d
8 R, |" S  J  K* o5 ?9.以下哪些面向对象的概念无法在PHP4中实现?$ g. g& K' Y5 V( W6 T
& v4 I+ o; L+ L. A- Q8 n& _7 {
@抽象类
1 T6 {+ n* o  n5 j1 Q- O@Final类, Z9 V' ]3 \( J* m; F
@Public、private、protected(PPP)方法
- h" ]6 p6 r; X, l9 ~* Q7 o3 X3 D. h@接口, M. k" O: b, @
6 a: ]" G7 e+ T6 e0 K
A.抽象类
, f' t3 ~; {( ?" C) L, LB.PPP方法
6 h3 I9 O% @. m! {- ?! zC.PPP方法和接口
6 a: W: ~: u" @D.以上所有都不可用
% z% S0 Y9 m! jE.以上所有都可用6 H* Q, q2 d9 i/ Z+ Q& A5 O( D
1 P. m1 E% Y6 M' s

9 \/ r3 M" K+ }- C# O8 C' p7 g10.如何在类的内部调用mymethod方法?4 K+ b/ w3 U& V$ F; p6 t+ z
% H, {. c/ }/ h7 P! W" j
A.$self=>mymethod();# ~, x9 H1 ?$ e' B& c: N
B.$this->mymethod();; p- }' @  Z7 S
C.$current->mymethod();9 C" t0 a2 D( Z2 v0 b5 w5 G
D.$this::mymethod(); O( l" n: }- i* u3 S9 r
E.以上都不对
5 l& @% z& b+ Z$ R7 S: t9 h7 X" L( V8 s) D1 R! [1 w4 i9 p- P

6 {( x; Y0 r0 k  Q5 J7 z3 |# ]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.10
' v* j4 u* Z; |  `5 Q( IB.Null
+ y7 y& a! m/ S6 aC.Empty
$ G- _5 g3 K) QD.什么都没有6 }  r1 ?8 `9 Z* r& K
E.一个错误; ?! G* d$ h* U! G
& p$ J* Q7 O# i
6 x7 M7 f+ u4 T' }
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.108 g- ?- q1 j! Q, N- s- o: f
B.5
- h! p. k% E1 G$ m8 yC.2, V* `3 j+ b  w0 z. L& e! q
D.Null
' ]1 Z2 n  [+ O' G  tE.什么都没有
0 E( m$ X. o% V* X6 f  ^
3 C* e: q. E$ `6 u9 ^
6 A) e  l4 B* s8 Z) n2 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
2 N' ~, S9 n' I0 cB.10
( `5 F4 C# D$ m$ L, D) l4 XC.什么都没有; a' S+ E% J% F5 x2 w
D.构造函数将报错
" i  n5 Z! Q1 zE.510# Q6 {3 L- [) l+ D$ d4 u+ S
% j6 Y# |7 q6 ]0 X( `- v
5 M; K% X# n+ y) y7 x! @: J
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函数必须返回一个值
; `# x* `" ?: o6 gB.reduce_fraction函数必须接受一个整型值
  {2 Q2 g" W( k: D, Z4 [C.gcd函数有问题
8 F! l9 h' g1 LD.必须通过引用的方式传递$eight_tenths对象5 h. g* n" P3 C# E  g" u
E.对象的实例不能传递给方法以外的其他结构。2 M( \2 }* k% r" s/ s% b3 v
- H$ _2 F9 U+ n5 s& [% [/ H0 m% V
; |% @' T7 k! K: m# e/ t" F; o
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
7 K/ c. {# T5 x( A! wB.生成myclass的实例并调用mymethod方法" y& S% C3 R. l
C.产生一个语法错误
; s2 l' t0 z: A( a/ fD.默认myclass类最后被创建出的实例并调用mymethod(), x9 M% o: }7 t: \  e! u
E.调用名为myclass::mymethod()的函数
) W& X/ u5 L, D
- J" O9 y  `/ |" Z/ @  b
9 J; f% p4 Q' B. T) z) E16.PHP中有静态类变量吗?3 s' a7 p! a( y
+ k% j8 m* v4 g- u0 p
A.有9 o! `. l/ u5 t
B.没有
1 \+ r0 s2 e7 l. Q( @) j) E7 |
) B) p4 Z" Z# {! _/ I$ r# [& r1 j. O
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.12 \5 R; N; Z' b# F
B.2* G) o6 u3 L, w& \2 R$ q" H
C.一个错误,因为没有定义a::$myvar
! I. t, _1 O, ]2 f1 zD.一个警告,因为没有定义a::$myvar
/ F6 W2 X( ?3 h3 LE.什么都没有3 c. H+ c9 J' i% M5 k- T& P: o0 D

; U. [' [$ g9 A. J4 |$ N, N% P# p5 f: m. F( E
18.如何即时加载一个类?
, V; f. z( Q# y' ~$ R( L- A; t4 c! `! ?  S8 ^+ d( ]
A.使用__autoload魔术函数
3 S3 l" x2 e4 z! R* l0 C% O- j6 lB.把它们定义为forward类
- R, J9 U% h) R; D4 FC.实现一个特殊的错误处理手段: @1 Q% \. w! L8 F% K" a
D.不可能/ e" `) k: R& c
E.用有条件限制的include来包含它们+ A! l: ]+ ~: [7 \

: O7 h8 [" v  n
( u! R3 {( v9 Z+ z# @; r19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?+ u6 y: U8 Q  Q2 W/ R; g. H
) S5 P+ J' s4 P. O3 i4 b
    答案:__________
/ [: p* H; r+ s/ a6 r9 U- y8 D$ U9 x3 j) |! g- o

# k0 C4 W: k* A4 P% ]: f! f# Z/ @$ j20.以下脚本输出什么?

  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 called0 i: y6 B. q/ |8 f0 Y2 j# q
B.一个错误
  E+ q% Y& G4 EC.一个警告% F2 _6 N3 H! b) K( p0 E- W# A
D.什么都没有0 H$ X1 t, f+ L9 @* d4 Q# q! R

+ N3 L% k6 M4 n8 ?* r4 Y6 t1 l* H  D+ m3 w" o0 Q: ]! e7 _6 b

* n  x) |9 e- l& f9 d* d答案速查
7 Y4 q, ^* U4 {7 a* \; W1.类3 g- g; {( C2 l# T5 Y5 x
2.BCD; o9 C3 y! \$ U+ L7 F  L9 e
3.C) `/ [" K! e& U& `3 b% v
4.C
: @& K# ~! u4 {5.A7 w4 f1 t! y" X* o1 K7 Y5 x
6.C4 ], T1 D: d2 B: p6 q3 r: V
7.C
* l* \1 E7 C* i+ s8.C9 p! k; T0 W. {
9.D6 i  x4 G. h# W# `5 r2 _
10.B* v* c- y4 H* G" m. `
11.D
! A  p9 }2 \. x% e* L, k3 b12.B& Z/ w! W1 g) z# \, l; G- p
13.A/ D! o/ H5 n  R3 ?0 m* g; r
14.D5 w' g" l5 R- K1 Z4 e; e; |! T
15.A
5 K& L2 \& ^+ r1 _1 t16.B# b3 u9 P9 e3 i+ u
17.A
5 G" Y6 [& }! L18.D
7 u! o. e  s1 ?" |19.设计模式& a5 T7 [7 D5 F+ a% e
20.D9 K# R9 W% p5 f+ _7 x0 f: m( K3 f' b

0 S( W! _9 i) l' U3 x- `4 H9 Y

9 o% ]4 @- N2 t- m9 B& ^: l答案详解5 F) q: [2 s! u0 W

+ ?  z! [  F; g1.类是对象的蓝图(对象是类的实例)。
# F- l  g* l& X* o! b* @! @! f% O" q& P; c
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。: l# c& @, |/ a. [8 H
* F% A& r6 y4 h# I* Z
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。: c7 D9 D8 J4 ?! G9 o
, G3 }3 W. R) x  i0 W3 y
4.单件模式可以限制一个类被实例化的次数。0 i. l1 ]' @! h( ~3 `, E
) L. B$ n' n$ o& ]
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
( _$ j% S8 n' p  x" I/ i1 J5 v' ]0 G! ]/ }; u# B0 W2 G
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。0 f9 q' @! L  g0 o) s
2 r" Z  Z! Z# p# A9 j" W9 P
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
. w2 E6 @6 U4 H' A0 N' T8 u9 ?
, Z! s! m: W( a- a" }8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。0 C1 ?6 F- x* u- g# a' P% e

: y$ ?3 |$ A+ v- A6 W! _6 S3 q0 L9.PHP4中没有题目选项里所列的任何一个概念。答案是D。6 N7 ?! U& X# S

0 n$ v. i3 E7 x! |0 I, X6 u* L10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。9 X# y2 ~' W2 D

2 w1 d( x+ S5 e* b0 r# c0 y11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。/ t* k, \! e' K% r( ^$ q+ F

5 }3 C' M) \" v) q% ~3 R1 _: f: G: F12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
$ X( U$ f: E0 _& }9 A* F4 V  N) i+ Q8 F* Z7 ?, i
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
4 b* C5 P! C1 [; V  a
) [3 G* f8 J0 l1 s$ f3 ^14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。4 ?" p/ _5 I; U3 U+ E8 W1 B$ A
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
- n/ S: S9 L! T# F    function reduce_fraction(&$fraction)
, n; q) r. b+ c2 ]答案是D。  N6 F3 i. o4 W. Q+ }

1 C0 ~( Y* c6 @# G15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
, ]! e8 P0 X. u. M0 e+ J8 G( }& V( v
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
  H. F& L3 }# @2 I; }
; n3 B3 `6 h7 X2 M) O; }17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
5 M  ]# F3 W9 C" X/ i* R; U
$ w4 d' `8 l& G& Y( u4 X# c18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
: T2 m! S& Y$ k+ E" z
$ U5 e, m3 t0 x19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。  i. L7 O+ X% l  k2 C; R$ V
) {) ~: I( q# w" V+ ?) L4 A
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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