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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。& A$ h* V& i* i" E. t. z: U* S
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。9 {( {. Y, Y, ?0 G# R1 J. Q
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ K9 h, z1 C4 V2 L/ `: K
  E; m% W. l4 M+ J/ j问题# Q+ ~' V! Z7 n* J. E: i

6 k& |4 G$ x( A" [1.对象的蓝图是什么?: t3 B+ r2 f3 Y* J& v; u6 O

$ @& Y5 f9 G' T答案:____________
, Y, v0 k. o# \4 K) ^
/ J8 w& G  ?, N
6 K; T& M1 H: r" h/ A, v* S% r2.以下代码执行后,数组$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/ O4 G; K8 `% s2 J/ h1 n
B.b
! i+ O0 ~0 w0 _4 NC.a) {' U) G2 N6 o+ L4 |9 `
D.d
+ X* _2 {0 I4 ZE.e* t6 d9 [9 `' A

* \. ]. I$ C1 e0 q9 D
2 W5 m: s& _# D" G9 a3 H3 g3.如何让类中的某些方法无法在类的外部被访问?3 R" S( L1 N, g9 O- E
/ x+ X' ^# I: P
A.把类声明为private1 f+ E# Z, o9 p# I: X# |
B.把方法声明为private  q# w6 K1 D* ^# r' _4 h' Z
C.无法实现6 Z+ |; B- y5 o# m  I) f! z
D.编写合适的重载方法(overloading method)
" T) g* c( C9 ^/ O$ y: M/ b) k
- U# i8 \: j5 Y5 E' Z5 w
7 c% e$ r8 {$ p( `4.哪种OOP设计模式能让类在整个脚本里只实例化一次?: V6 E% V" z+ i& G  o% F

3 c. r1 ~! C3 p( G( z3 u$ a) L8 t' N4 MA.MVC模式9 i. x% A( J  E& c* o* k
B.抽象工厂模式(Abstract factory)
3 h: g2 N# b  ?1 I  eC.单件模式(Singleton)# m3 F1 I) j2 ]$ M( p$ B
D.代理模式(Proxy)$ W8 W- T2 h2 T4 }! |
E.状态模式(State)
3 O& K+ t# p1 _# L# x, P2 k4 I% N* p3 o6 M+ |/ `1 @% E5 A

. y. W5 o* M7 L; @* C5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?& b' x$ M6 ^2 b3 ]8 z

/ A% r1 G% u5 K) C& {A.1个
. _, X, R1 P8 i& x  w7 m* M2 C& E; sB.2个
, D% Q, I" {8 ~C.取决于系统资源1 Z6 Z. Y6 Y% d& \, {" N6 M
D.3个
2 p, |7 k3 G! f, I# ^3 ^1 Y/ GE.想要几个有几个$ @8 @0 y8 W: d6 b9 ~4 v

0 v$ n! U  M. K& ?5 x9 Z9 \0 ]2 z. ~
. _: r0 B6 g% I6.以下脚本近似的表示了一种在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.多重继承
. ]  K" f5 }8 w! K  l3 D( lB.接口
' L$ b) N5 q: c3 M, YC.抽象方法
* P9 H: L  p* I! `5 hD.Private方法
) w) |) t- I) bE.函数重载(function overloading)/ ~5 @! |/ \" Z& B

& \+ j& L: r& H  \; E% p
1 B- e( P0 J' q1 p7.假设定义了一个testclass类,它的构造函数的函数名是什么?
. }) [) U) o  G# P+ J  a9 n# O+ o7 `$ i1 f
A.__construct
# f( H2 c  ~5 l5 c1 |1 D/ I! PB.initialize4 }! }7 o0 w$ p0 y- g0 j
C.testclass% W! K; e9 N7 T3 g+ `2 @
D.__testclass
' i) i# p( n9 u) C% C9 f  eE.只有PHP5才支持构造函数: {3 @% _! M5 p$ g
* u; f5 b$ C# P2 o% ^5 _
. Z. p. s5 |) T# o6 ?0 N* r
8.一个类如何覆盖默认的序列化机制?
( f+ k' V+ R( O$ ]. f# k% V6 }. {# o2 j& X, t% n8 _
A.使用__shutdown和__startup方法
( G/ l' W. @6 @/ t; G& ^B.调用register_shutdown_function()函数
, D6 ^7 O4 z" a! zC.使用__sleep()和__wakeup()方法
+ G; T, M3 k9 O; w0 _D.无法覆盖默认序列化机制
3 F( F- V9 x0 L( o; w9 aE.使用ob_start()将类放入输出缓冲中2 ?" s& u  S/ k) V6 u9 Z  |* G1 l
0 M# k5 d( W9 ~% B  W6 o! G
5 w1 H) B! a! w" _- F. d' C
9.以下哪些面向对象的概念无法在PHP4中实现?
. x$ W9 G; F% u( I0 V& g& J, U0 g( _+ H+ i
@抽象类
2 q3 J1 p5 Q* r@Final类
5 I# o4 ~" [" m( q@Public、private、protected(PPP)方法5 ~5 `: x9 ~0 T% `3 [
@接口
+ f1 a2 D& O8 V' P4 d, b5 x% @" s' ^2 y& \8 ?
A.抽象类: Z6 ?1 W+ E& ?9 j
B.PPP方法( F, U2 I6 W6 W% p/ I9 y
C.PPP方法和接口# O$ @1 k+ S8 w% W
D.以上所有都不可用; c5 T% u; Y: u! W' r& a
E.以上所有都可用: c& P6 ?1 Z7 Z

6 Y) [- c+ Q0 N$ t3 H/ T7 l! C
% |/ C! \& H, i/ n! J10.如何在类的内部调用mymethod方法?3 h$ H+ X* R, C: d5 d

0 {; t9 E0 P5 \A.$self=>mymethod();
, z/ H& v: v5 X3 R3 _( q0 _B.$this->mymethod();5 |/ h' Q  v$ l
C.$current->mymethod();
' p" G0 F& ^0 h8 f$ v8 JD.$this::mymethod()- r! B% e6 j0 w; h( b
E.以上都不对- C4 q' {0 d0 N- W# q

! Q" j9 `- f* K7 i  z
3 R' r8 |' ~" _) [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
' S5 M+ @1 }1 b; iB.Null
2 ^7 x. c3 `; u$ n  C- L' T& A- pC.Empty  e/ y+ r5 `1 h' O
D.什么都没有
" B/ z/ c6 G7 n) z$ ~E.一个错误. ?3 v9 t6 o2 V: l
, _" j* Q% t# a

! y+ ^9 ?1 Y. `3 X12.以下脚本输出什么?

  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.106 A- b) ?' e  L/ r% R/ L/ U
B.5, {3 l+ o) e: d: P8 ^) T, m
C.21 Q- w% J+ k, t4 b% w
D.Null
" V1 q5 a; T+ M/ eE.什么都没有; h2 ~$ k% n4 r0 m+ _3 M: G
6 h3 w( A, E5 g6 x! X
* ~& I  {, N" D
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.51 n  O% b6 [: F  O0 P
B.10
% a" r; K; Y$ ?; z' V+ D" T6 @C.什么都没有
7 u1 a) J/ S1 P6 d. d+ ZD.构造函数将报错
& q" D( C3 n8 B2 ]/ sE.510
: r7 H$ j/ B9 P& Y1 b! }8 x# z  k3 \
" e! Z, a, ?) D/ O
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函数必须返回一个值! e, M5 p7 B) h+ U  Q# M' x/ A
B.reduce_fraction函数必须接受一个整型值
. a) K; B. w5 q* Z2 rC.gcd函数有问题
2 b; N: P) y. Z+ B! g- }0 oD.必须通过引用的方式传递$eight_tenths对象
! G' Q% i0 a* i" v2 WE.对象的实例不能传递给方法以外的其他结构。
8 ]& x9 P* \1 {8 F6 F/ G4 z9 F: H4 u1 E! q
: c! E7 J: i- A9 s. X$ I  {! n
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法& p0 V, E; G$ F  ?: M' s$ f6 R
B.生成myclass的实例并调用mymethod方法
- ~6 `) C  k/ U% _( q, FC.产生一个语法错误2 I$ w- G+ y- S; Q
D.默认myclass类最后被创建出的实例并调用mymethod(): [9 T3 G# X: [9 [4 S$ B
E.调用名为myclass::mymethod()的函数
# L: x9 ~  S* N
) j/ G& K( h$ e: X. f, D! H' l
% G; |5 c% R- s# d3 c16.PHP中有静态类变量吗?
: C$ o% o" F, \$ d5 h( Y: C1 J/ s) }$ J+ S+ l& L' N' b6 f& Q) c
A.有9 v. y- h3 j, B8 K7 h
B.没有
1 O  }6 H+ k1 r" Q+ O4 g+ K2 W4 P2 j
5 [; I  [3 i. l' V6 r' j* c' I0 \( c' Q; z0 s7 s5 p
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$ o( B( m9 B2 ~! Q4 V' Q
B.2+ u# U# N1 c1 D( t8 ]3 ~8 j' d
C.一个错误,因为没有定义a::$myvar
9 M- f7 A7 l6 J" lD.一个警告,因为没有定义a::$myvar
& W# z3 v4 J' i  Y- t' W' r& WE.什么都没有
8 [) R3 a9 G" _/ B' M
8 E: G9 ~& d) X. L, k, ]5 h/ S
+ E+ M  F, x/ e/ U5 N7 ]$ s18.如何即时加载一个类?
0 o; v. q% @$ p6 U2 W8 c4 d" g8 I4 }) g4 j( x- N, J2 t
A.使用__autoload魔术函数
) r, x7 `. Y, O+ Z' t2 EB.把它们定义为forward类
* @3 V" J6 g8 t7 _$ s6 m7 UC.实现一个特殊的错误处理手段
- j  F, V4 ~, M, U1 i/ u9 T  ^D.不可能
" S$ Y4 i) {; K# D4 l3 R5 p& ?: iE.用有条件限制的include来包含它们+ g! q% `( A8 f& ?
( J- E" S: ~( O7 r, z  S, n1 T
) `- o8 u# P, E5 Y) w: b3 @
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 q' W- W) R8 U, Y2 V  M9 }% b
4 f$ F9 j) d; K4 {5 t; Y. ]2 T6 g6 [    答案:__________
# R7 B" S! K4 j2 k- f) o' U! U
$ K! {$ t5 r  ~1 \; ?% r: x) H$ w2 B5 {
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
1 T- n* D& J7 y6 a) ~, EB.一个错误
8 |2 R3 Z+ `2 I, fC.一个警告
' X$ @  C' s, e! b4 s; Q, AD.什么都没有
( z! d& i' p2 D* m& {/ {- b. C6 D# ]# z
# n$ d8 ?, u8 W+ ^) D
. o, l5 u" ^2 V( l- ^! e( m. i
答案速查1 {) m9 i/ V2 X+ P% E2 }
1.类  o( x1 I2 H1 J1 T" x% O0 z
2.BCD
* a$ e2 c4 h9 ~& [3.C
  Z- n. L) [0 ?4 c4.C" Q0 b; W% l- r: F* T/ X
5.A! G7 a6 h, a4 l
6.C9 F" \& T7 s2 p/ n( k3 d
7.C" q) f- u- i3 B# \% Z
8.C
+ q! G2 u- R! S; i% W2 ~8 H: c8 }9.D4 c0 e+ |6 y; |- ?0 \
10.B
( G5 d0 H) D- w, ]' o11.D' W0 K0 r# u2 z
12.B$ q5 n& G. A, ~! I
13.A* f- L, h# p/ [# d) M
14.D" R+ C+ X. F' y4 y8 c& C
15.A
. I/ r$ W3 l! C- ]$ l2 h& z; `* I16.B
( D( `3 d, E$ q17.A4 o0 w. s6 `1 m
18.D
" V& l: j  t! q19.设计模式
- R$ t5 }7 z; w3 {2 L20.D
! C! R7 \1 b1 a6 t8 H. U( \: }& t( y! d5 |

3 K' o5 X) h4 g3 S, ^0 n! J2 s6 b* a. ]  x
答案详解# Y; j$ i9 c1 O" [9 Z: X# d8 B

: [! p# l2 H5 W8 o3 `% p1.类是对象的蓝图(对象是类的实例)。1 K7 r' V8 r/ h+ w# J7 F

; y/ O; E  o4 U" C) B8 m+ h2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
: u! B3 l  \$ F4 S9 R' f; A
4 g& ]8 {) U! E- h3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
0 s9 b6 o9 p) P+ a2 r
) ]& _# w: h; S% L' N& M3 Y0 b4.单件模式可以限制一个类被实例化的次数。
( ?2 h0 m) e& g3 G
4 ^, S0 E+ O6 G: q, d3 }+ [' e6 E4 e5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。% O0 {: p' ?6 s8 x, L
" U/ V/ y: C' C: a
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
) }: A2 b6 b2 |: T0 y, A; m1 c' n
; j2 y, P9 l. p- {7 K9 T7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。; f/ m% X% W4 @6 U0 \  O$ i* m! G  U
! s4 d$ h+ o/ B9 Q1 f
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。) D, K% Z2 |7 N, ~5 b! P/ c

" U  H) i  G2 @" _) z9.PHP4中没有题目选项里所列的任何一个概念。答案是D。8 d0 n0 P8 G# ?  _# _% a# y
* G. l( A3 C0 `3 N1 R" e6 q0 y
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( V4 c9 U/ S- H; `- a$ J

% R& u# ?) {% o5 r% [1 c2 K11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。6 z9 N4 H6 N  n% N: m' n9 ~, |

5 n: M4 P7 L" d' X$ `  v12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
+ X- I! A, J2 t6 ^  n  H
8 a; s1 K# O3 S/ e13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。/ P2 S7 H  q  F# d2 ~: l8 D
4 A+ d" Q0 o) L
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。# e3 z3 ], F4 `; _6 y5 w- ], X/ l
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:/ x2 H# a8 p; Y! q$ t( V' G& k
    function reduce_fraction(&$fraction)
4 a0 Z" ~) c) n1 T; }7 A答案是D。
& o7 I4 z8 A. t( [- `- e+ U" P4 u* f( c+ M( G' s. v
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。% G; d! ]$ {% O. g5 O
3 y8 N5 j9 x( R3 V
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。  K, L/ v* x$ H
* O4 U: O& Q+ Y; {; r  L4 Q
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。, E' T+ u' o. w- a; s

) G" E$ W1 L+ V+ W7 s7 `* {  E18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
- Q' T$ t6 R1 V; n6 G
: x$ V8 {" z2 Y19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。, I/ [0 T1 `7 q) c' T! S

8 M; [0 x$ u7 J) f: g( _* K( f20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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