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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。/ P9 J, z9 r; |5 N9 O
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。4 W) G: |0 V& V) R7 z; V9 w
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。- [/ W7 n/ W/ G% u# Z# J

4 v$ a4 _3 F( |) L" e8 [问题
7 h; f9 @9 ]7 ?
) Z2 V/ ~9 j1 x2 M* c/ ]& p1.对象的蓝图是什么?/ g- h3 `. Y. g( v" {1 @  ^+ _
' o* j! t9 E# _" D7 n
答案:____________
7 j( B' w- T( L  ]/ w" \3 [
% b  e  {- z1 l7 D- d$ W! [: M* j$ ]% S9 \) B
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( G& M0 b1 w5 D, o
B.b; n( L$ c2 `2 Q: M  G! Q
C.a
+ J8 u: B2 [; L0 I9 m6 uD.d
) z$ k/ c- |2 l& ME.e; I5 `7 Z2 h: ^, D9 D
+ w' P/ N1 _9 S
1 u5 E1 `3 i" b. x0 A9 E# c
3.如何让类中的某些方法无法在类的外部被访问?$ A" q7 Y. u% o7 S( E6 k  M

; _; Z! o7 d' Q, xA.把类声明为private
. k! {* ?7 V$ \  ^, PB.把方法声明为private
3 v7 s/ X$ r. h7 Q3 \$ }: RC.无法实现4 K& l% f2 d& ^) v2 ]
D.编写合适的重载方法(overloading method)1 b$ \3 E0 `5 N2 s* o# v' Y5 e4 ?
& Q, x  N9 N) V$ e  ^7 {5 {6 b
! B% l" ^9 }8 p, ]! C: \, |. M* h
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
0 D! J  [6 }: B- Q* B2 t3 \* D
0 x# q% W: Z1 P8 f# VA.MVC模式. |# h" C% @. f  s' Z
B.抽象工厂模式(Abstract factory), o6 C  h- W+ f0 x2 T
C.单件模式(Singleton)& n( s& S% D$ w) O) k6 M8 B& d
D.代理模式(Proxy)6 O  D, \+ B0 q
E.状态模式(State)5 p& p% |% F' W8 d

! D$ M+ a) q4 ?. t% w7 Q' J+ `% N
# s2 y3 ]) b- T. b# `5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
, T+ Y4 i4 w' y) P" {* K" H2 G
5 ]+ H4 v: z% X1 a- \A.1个
: O* {9 o1 q6 J6 O5 WB.2个
! ~; ?$ H, ]% \2 Z' d+ QC.取决于系统资源
8 b2 e" S3 \8 FD.3个
8 g5 B; ?/ ]+ y6 ]9 T: H( EE.想要几个有几个
# ]/ c+ ]  m/ {) Z( H
, k: l& y" L7 o$ ]- o* O4 e; r7 a; y% y/ `
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.多重继承+ A( U+ ?8 L; S/ v, c- R
B.接口8 V! @+ l: D8 z
C.抽象方法, k* P6 {6 r- m  o, o; l- E& x
D.Private方法/ \! ?3 v- y0 Z5 u9 P  o
E.函数重载(function overloading)% C, ~! t4 Q7 E

% P) P8 x  R' d
3 Y, ?* e. H1 h- a7.假设定义了一个testclass类,它的构造函数的函数名是什么?
( \& T$ Z: h- A, i7 }
- ?( s6 Y' _# ]# Z$ }) S# E  hA.__construct
% ~2 C4 J; R/ M, AB.initialize' K) P* }9 X  `- R1 \  _
C.testclass
  v2 T9 z7 N& w# c# k" wD.__testclass0 ]! E6 @9 Y5 U6 c' ?
E.只有PHP5才支持构造函数
5 z% C% P4 X# R3 ]
! H- V/ y5 K# F, J
/ h1 v$ W! ?9 M% f# V: U0 [8.一个类如何覆盖默认的序列化机制?, \% O, e) c7 k; V' v

; K7 Z$ y5 C) i7 VA.使用__shutdown和__startup方法% s0 s3 e2 y9 `/ @0 `
B.调用register_shutdown_function()函数
* k" ~) q1 T; e2 {1 P$ d6 yC.使用__sleep()和__wakeup()方法
% ^& Q0 T( _# N9 N4 h. {% vD.无法覆盖默认序列化机制
, T2 H* F  A7 Q. v3 r6 }7 aE.使用ob_start()将类放入输出缓冲中
% B: @, _0 y" `* T
7 P! E8 |- {0 W0 V
6 |: U& u$ G! ?4 X0 ~0 k9.以下哪些面向对象的概念无法在PHP4中实现?, [( }* X  ^/ T7 \# J# _
' F; p9 g) K. K) {* R; X) H, z5 O
@抽象类  G3 e7 d0 ~4 j6 Y
@Final类" e% a6 u5 e$ @6 [) x& T
@Public、private、protected(PPP)方法  G% ^+ Z9 P: O" e
@接口9 S* }0 z1 h& i

) o, \. G8 t- i" Z! CA.抽象类
( O* p" d6 W/ K4 c; lB.PPP方法8 N) r* P1 {+ ?. I
C.PPP方法和接口/ K; |1 Z' c1 W
D.以上所有都不可用
" F9 O% E9 f. P6 t( iE.以上所有都可用! I) o% w+ ~: t0 @' z7 ~4 s
3 H; ?7 v( A& ~9 v" D- r

5 h6 W9 ^$ z( W$ E0 _10.如何在类的内部调用mymethod方法?/ }; J$ I5 |5 }8 u

0 y/ c4 f; Y% ~0 \/ p" x' R/ bA.$self=>mymethod();3 n: ^* V' L% ]9 |. m: e+ s& D
B.$this->mymethod();
6 t7 i8 |- @9 SC.$current->mymethod();
3 W' p& t6 V1 q; E8 K- [D.$this::mymethod()
# q2 g+ l, F3 C/ D8 {7 A9 DE.以上都不对& y$ V" `1 q; A9 O% }7 j
, e& S7 e1 \1 E) G

# Z# x, G. V6 _6 t4 N4 v. G11.以下脚本输出什么?

  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. T% l& a' a5 s& B9 k8 x
B.Null
2 h# A1 a# B) y2 V' m; ?. uC.Empty; H3 S2 N- M3 p$ A
D.什么都没有
! ^7 N, T0 Y. I/ H' GE.一个错误. e, ^! ?/ s0 @! u" J2 f$ ^
1 l0 T! J- {& e# P7 P* t
$ q, W/ t+ X; ^8 P- _5 h
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
% ~  m, h" t' bB.5
+ Y+ a" J4 ]1 k  j$ f- r" m$ r+ p" tC.23 [$ @# H& M1 ]1 d* p
D.Null
1 L2 m& H2 I7 f- e9 v  j9 {' EE.什么都没有' s& E9 _8 E( n/ q4 }; `7 ^: {0 b
! P+ g) P  l& z0 _) e( ^

% u" I" u- i" W5 M) `1 }4 p- y13.以下脚本输出什么?

  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. z& m- E( a$ B
B.10! b5 B, q/ P) }# P# t# k+ u
C.什么都没有* F1 C7 H2 I; a9 x' }4 J% A( S. k
D.构造函数将报错0 \4 r& k5 i7 I! G
E.510
/ |5 q9 j  V/ y! n( h8 g" [# R
% h/ `  [: |: s( P9 ^4 M/ _1 @4 g, M! Q) |7 p# `- M( E; s
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; [& G; }) X) q) ?8 WB.reduce_fraction函数必须接受一个整型值
" D$ U" d- E: J. EC.gcd函数有问题
2 f: Y7 B9 @7 y( B8 B% `5 HD.必须通过引用的方式传递$eight_tenths对象
* j+ t4 m' U. z. W" c+ nE.对象的实例不能传递给方法以外的其他结构。; b6 R3 N% T& t5 |" q
5 q+ Z% B, w9 c  i

9 L5 D7 ~' X7 i6 l: e15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法
5 J6 m# S2 i8 y7 W* L$ {B.生成myclass的实例并调用mymethod方法& r1 v/ y0 d& _& ^' X
C.产生一个语法错误0 o# E( R6 [; y( Y. h
D.默认myclass类最后被创建出的实例并调用mymethod()* G* S. M! H4 {! L( \
E.调用名为myclass::mymethod()的函数
9 P, m9 j6 _% n8 m8 [! x6 m" K! h1 ^4 z* t1 X3 C

$ _( |0 g6 B* N9 C; r. {2 e* I( [2 {16.PHP中有静态类变量吗?
; V% E* a+ C5 A) U) [; ?: n0 ?
+ q% @' G7 P( A8 `: LA.有1 N, t% y  @0 y- N% b$ I
B.没有
9 @' i0 m* C& C) W
1 {' ^, Q# c4 Q8 m) e: `. Y
  w9 v9 u' `8 Q17.以下脚本输出什么?

  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& @! V0 s: ^  _: M: P2 Y  q) x/ U' o
B.23 d/ ]* N& \! Y/ E( E
C.一个错误,因为没有定义a::$myvar0 B/ e3 ^4 S, F) G+ u
D.一个警告,因为没有定义a::$myvar
# Y$ I. r- {. i7 QE.什么都没有5 H" g2 l  }/ A+ U0 ]0 \& q
8 {# P% K7 }  ^4 f- Q4 X

2 B( m6 M9 @$ p* o3 K18.如何即时加载一个类?
4 q* Y0 p- Z( `! ^! L3 G: {- D8 O4 R/ ~; ^9 C' e
A.使用__autoload魔术函数& `" n9 M3 @6 s
B.把它们定义为forward类  I4 _. G6 e! }6 _& r
C.实现一个特殊的错误处理手段$ H! l& B3 ?! V# a
D.不可能
7 A0 j+ s3 Y8 Z9 J) Q, a; ]* r9 pE.用有条件限制的include来包含它们
, q1 Y# J4 H5 Q* V5 t; H( T6 q1 k8 m  w. ]1 O+ s9 x$ x3 c8 e

3 T  o  F; ~" a$ P( D19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?3 K; W# Q& X( G+ e

9 `2 W& D$ F' t; c( F$ E% H    答案:__________, q( W% ]5 X1 F: ]2 V( H8 E. S
0 f1 q" \  E2 q0 t
% G) S1 f, X  ?! M( X# w! ~
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
# r& F+ n7 O! A% I* P5 |8 S  J. ?B.一个错误
6 M$ }! U, k% wC.一个警告
( y2 f9 X4 R' f2 Z8 \% PD.什么都没有
6 Z# b/ [: S. e1 F  a4 s
/ @" _: Y" Y, S) c6 x5 P; L1 x6 [. w/ _3 N" ^
3 x1 S7 Z, i4 R1 q+ T, |( {
答案速查& X8 G! |: Y5 Y9 O
1.类
5 z" i4 {. H# F8 b( t2 U" Y; n2.BCD
, `' `8 `1 z1 Y, i0 g( w0 R3.C6 t- b$ ~: z8 Z* r
4.C; k% {0 D3 l2 P6 f2 i# {6 Z* h
5.A
' m( ^+ ^" l" U6.C+ ^: B% z# N9 F1 y0 f) M5 N
7.C( ]. F( P2 [$ j3 h- B
8.C$ y' \' b. j; W; V( a4 `1 t) e
9.D
- w% f& O+ {$ n10.B: P# Q7 x0 t9 ]/ ~" l! O2 d
11.D: b3 ^2 R6 d8 ^
12.B/ f& E" h2 y  n6 l* h/ v5 }# U2 }
13.A
* X( Q, O* J" e" m14.D
) V8 h9 H. T9 b) e/ L, U" Q15.A9 t2 Q$ F9 N  I6 A8 g0 s
16.B
" a- Z  J% E$ W4 C: y17.A6 N# I  _8 X& q# n
18.D; z5 ~3 ~/ x# y
19.设计模式. e  T& p, U+ x) l: W
20.D
6 G' D! ^* `( l3 g8 f1 ^
; _3 t' W9 {2 @8 j
$ M5 T7 l7 n  B' y0 J4 Q. c; g
+ f' `  F- p' C答案详解
5 q. t) W) j" V' J& y% k$ P* y- }' ?( U  s$ p; v* H
1.类是对象的蓝图(对象是类的实例)。
+ g( W# \/ g5 \" t# m
. A# x" W8 a8 g" g+ l; e5 A2 l0 T2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。% b, @5 ^  W$ a% @6 B( k; G( _) s
7 t: {4 e( [1 n6 b  F4 ~
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
* }# A6 m( J" H3 j9 c
7 _' p2 h& R- I6 Z1 J$ t# B& l4.单件模式可以限制一个类被实例化的次数。; l) C& ^6 {& v- h+ b1 y8 J2 w3 w
; G9 O2 E5 x+ l# e: x7 v& E/ ?
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
& B% q; L1 R7 T8 H
+ D& \* \5 t+ b- O7 u6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
- N+ p8 R: }: ]9 t" J# {
+ J+ w& h2 w- \- C& A" [7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
4 X$ q3 x+ ?+ R% ~# {! f) b& F
7 W! B. J3 X/ g$ t8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
4 l+ K$ c, [: n4 |( D! J! a4 }; _7 p& A3 f5 t
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
* {) Y9 K( z8 P1 H5 Q# a) W# ^- X3 I
% J: G4 y7 N: M2 k- l1 g$ X/ P/ L10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。! ?; \, M& W( q
) R( `+ p8 a4 _/ x4 b" T
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
/ @3 K4 t$ z" p# p
# [2 ]; Q# d, n12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。6 F/ L/ E# Y8 u2 g
$ Z9 X* n9 u4 E7 Y# s2 A4 f
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
7 C2 f1 N) r. |8 R- ]# O/ k3 ?  ]
6 c* h& A/ U. o14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
2 E7 ~6 }# t$ B% N+ y. g回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
4 \, X5 G9 \( R- l0 [! q4 Q    function reduce_fraction(&$fraction)
9 g& @6 D8 d% _# S7 }) R答案是D。* Z& G3 e: j9 O8 Q: Q1 N  J

- y, Q9 V3 b. Y15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。# o7 f8 K; I7 x0 L+ Z4 i) i4 \
' T6 U# u3 I5 N: d1 x
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
* A9 }1 p* ]; {3 E* S
- {5 i9 Q! o; r- ~& L, x0 y+ S" X17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
5 e9 i& Y  m% R7 z
+ \: U7 U5 \- [  g: B% h- y% B6 v18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
- T- ?( d6 S. A$ f! _
6 Z0 n% s! j5 ^: m19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。9 W6 ~! \( Q' J$ B. ^5 D6 O

: U. F2 x; `4 A* E0 N+ Y20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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