返回列表 发帖

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。5 b% @8 N* l! s' I3 W' L% I
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
1 L7 j6 `# U. b- |9 M本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
: U+ l/ W% T- n- l$ v& D# R
+ F4 R0 I' O5 {4 D$ A3 g问题
8 ]& s, _# X8 ?: S
0 `1 k9 u" b, [1 ^1.对象的蓝图是什么?0 Q6 W0 l4 F6 c, [
& ^- G3 }1 W. \7 x& ~# p, W
答案:____________6 g! H% {8 B6 y, M

  O+ W4 O2 }) [3 {7 ]% B: j' P4 A: X+ F! A
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! B% d9 l' X  r: _- W' Z0 C( `
B.b& z8 b& @5 U7 z  b2 @
C.a
  }) I/ p3 P9 k" K0 c8 k# j% Q# }D.d3 }# y! d$ P, g; W' p6 W0 s  l
E.e4 t! S/ O/ T* f0 T+ w8 i* v( e$ K0 B

5 v1 W) Q- \% t- X. {; E& Q, [
1 J# [7 O; D- T) O; a6 g) z# F: `& D3.如何让类中的某些方法无法在类的外部被访问?
5 z4 p, m1 G5 ^* U2 k- o4 u2 `) Z% x' y4 p: ^+ ~; w: n$ R5 h/ l; E! M
A.把类声明为private
' H9 `9 [* E: {1 o; T- a+ oB.把方法声明为private5 K$ u6 {' ?5 a# E
C.无法实现
3 D' M" ?  z4 H) pD.编写合适的重载方法(overloading method)2 S( T* t) _- k) P" r: J4 `  _* v6 h4 i
9 c6 g1 m, p% |3 _% Y
. X2 ^$ j' [6 A( a5 c: {8 E
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?7 a0 @1 K6 ?1 F$ L$ q' B& A9 C% i. ]2 t# T

( ]* Y6 a: y% D. IA.MVC模式/ H6 ^4 E( k! j
B.抽象工厂模式(Abstract factory)
- }2 o0 }0 M$ d$ {4 z: y, x' aC.单件模式(Singleton)
& @3 {8 w7 q% a7 r4 iD.代理模式(Proxy). i/ e; r- ^" X  h
E.状态模式(State)& ?. H. H/ b6 e+ n; m2 V: s1 b
" @1 d+ h" a9 q% w
- r* I3 z& A) T, a* X$ V( T
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
4 S, C- D9 S9 p! T+ s; c- [& O8 I4 C! q7 O# l
A.1个
+ r8 h- l$ L% |; F7 M4 F. TB.2个
6 w) Z+ L2 N3 q& f+ HC.取决于系统资源
! \8 e! G$ m/ d& _D.3个' d" V. {/ S6 O$ f/ W  \
E.想要几个有几个5 J4 L5 }8 t+ V8 n; J6 [

, f3 P# x, d( l# U
: }* r8 E5 X9 A4 d  l1 Z6.以下脚本近似的表示了一种在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.多重继承
( ~9 D5 X: M3 S: t; LB.接口( U$ s* n9 m# Z* Z
C.抽象方法( }3 \9 D3 `3 ~) P$ ^" \# Z* s2 z& Z
D.Private方法4 {3 c/ F1 {' B5 }- I! X  J
E.函数重载(function overloading)
  b, g. O/ \- r6 |. m  ~/ x* T* l  ~- U9 `. J' f) H

5 u7 L# `$ c3 V2 ~: ~" ~2 j4 b9 y7.假设定义了一个testclass类,它的构造函数的函数名是什么?. ?2 k3 O3 C8 y6 u2 g
$ `; D) T. [! G$ Q) M4 K( |1 f
A.__construct8 l6 {: E: x( k# L% P
B.initialize4 T' G( B( _9 }; m* F
C.testclass1 L( F# p- e$ v, e" C
D.__testclass# a+ n# w5 [) x4 g
E.只有PHP5才支持构造函数. A) U6 u( r. I; n
$ O+ X( ]0 F5 G- j2 B1 _% \
- P* j) `$ W5 K, ?* }
8.一个类如何覆盖默认的序列化机制?
1 f4 R( E# o0 Q' o& d$ y+ a" D: J- [
( h, B6 \# {3 H8 S! Y' q1 C. [A.使用__shutdown和__startup方法5 d* c0 u0 G1 p) f9 Q( F
B.调用register_shutdown_function()函数
, a* L8 {7 d  q* A4 H9 Y& |C.使用__sleep()和__wakeup()方法
& ?& q7 L, i. X* ]0 X5 \D.无法覆盖默认序列化机制) m( X" k6 O* M
E.使用ob_start()将类放入输出缓冲中/ f3 K+ i1 }- q; l
, d8 u' p' e# Q2 y, q9 M9 r0 a
' F  W5 C6 W+ v2 s2 M/ f* d
9.以下哪些面向对象的概念无法在PHP4中实现?
& K% H& O/ F+ a+ g* T7 V/ _2 A) L5 {3 H& a( |
@抽象类
2 x0 {5 {' H& C7 H+ x@Final类
% h7 t! r2 T! U  @- H2 o; q9 \1 h@Public、private、protected(PPP)方法
4 r2 Y4 u8 r& b2 a  u! @; Y# h@接口
0 R* {0 P# R# a7 Q9 x
5 h" J  g/ r& o, c9 U8 w9 r7 N3 ZA.抽象类
3 P6 n3 j; ]5 G# V. g  r2 vB.PPP方法
8 x7 B/ N8 M( R/ b7 \4 j& E5 KC.PPP方法和接口
6 E7 V% r& l, Q* a5 V/ y, TD.以上所有都不可用( }" b6 J3 |; A8 W! P# z" D
E.以上所有都可用
" B: D  u$ r6 [: `
0 N9 }' F5 H3 L) {9 Q2 d- n5 n& e' S8 ]: B3 S
10.如何在类的内部调用mymethod方法?
% d' Y2 U0 K) g) p9 V9 @6 Y5 o( h1 Z1 E, Y/ X; J3 Z
A.$self=>mymethod();
7 x" F% _' e- f% V/ e$ mB.$this->mymethod();
) D, i$ w" H, M% x, v- gC.$current->mymethod();  o$ j0 Z3 p6 e* E. U% `! z
D.$this::mymethod()+ H0 f) Z4 U$ \4 ?1 R# t1 S, V
E.以上都不对& l/ O4 i' u3 M" t9 i

. c/ A( |' x1 w6 Y' U
" X' c, N6 a5 r  t. \5 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  |7 }- Z5 S) o4 M
B.Null4 `  ?, ~7 }- ]5 e7 c5 \! s3 D) h
C.Empty
- H. b% @% l, S( s. o. e1 AD.什么都没有
  c. o# i0 ~# S4 lE.一个错误
2 `- n6 X) v7 r
8 J4 A2 ]/ c# N6 s: O
/ ]# x* ?. D0 d" m12.以下脚本输出什么?

  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
# r( ?. V4 C; p5 V1 H0 HB.5
' I. ~% e% U. Y# rC.2
% E6 ^: r- F, }* E8 |D.Null
. _. L' U( \% N! l6 DE.什么都没有4 k) G8 k8 e/ o8 X( n

% T& q1 Q4 n* _4 Z+ B
9 m- g' R* B9 ?4 f: [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.5
6 q- U0 s! O. U8 BB.10
( |" U0 K/ c& tC.什么都没有4 i! b2 Q- h9 H$ p
D.构造函数将报错
6 x$ U4 d1 ]* R# l* ?8 y6 x" ^$ OE.5108 f" ]: I* p3 ~1 R7 a1 g' P
) ]6 M' s2 h9 U1 ]: A

! g& g" E8 ]  Z; l7 B$ z14.考虑如下一段代码,执行时,$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函数必须返回一个值
7 {  e6 c1 G: m$ y5 J, v$ t- }B.reduce_fraction函数必须接受一个整型值
9 [: {! \2 n+ \* W+ }* n  n' bC.gcd函数有问题
/ t7 N$ T" a6 D7 nD.必须通过引用的方式传递$eight_tenths对象+ P# {2 y8 P; j0 J8 s- e7 N
E.对象的实例不能传递给方法以外的其他结构。
# K* Q" I4 V( O. T* @& y2 k' S' C
' `4 [; p3 K7 {# ~9 e7 R1 e# o. K7 Y
15.以下代码是做什么的?

  1. <?php
  2. require_once("myclass.php");
  3. myclass::mymethod();
  4. ?>
复制代码
A.静态调用mymethod方法, r/ |. Z# g4 F! S9 y( E
B.生成myclass的实例并调用mymethod方法
5 ^% u! n1 ]7 a& N' J/ [; jC.产生一个语法错误% y, D: W% P. V3 I
D.默认myclass类最后被创建出的实例并调用mymethod()  x" {" [  [2 I: Z8 W5 q
E.调用名为myclass::mymethod()的函数
( k( h' i* y$ D; j+ C! i/ F
6 Y5 Y8 M! T9 q
- D1 W# [: S* s  x* \0 ?( C$ F16.PHP中有静态类变量吗?7 i" l8 b, C* p% r- _  o" I- D

9 n  n& W' o5 x$ H  K" G& m- e7 DA.有- V2 M5 M5 |8 u' ]) E& M( F6 D& v
B.没有
% v" R( O/ f. j9 S4 X
" Q! q2 [7 S. m" b
, o* ^2 w* u/ y( l17.以下脚本输出什么?

  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
, J2 s0 y3 M7 b* IB.21 V7 K+ b( U$ u+ K) v/ v
C.一个错误,因为没有定义a::$myvar: b  S! ]/ N' \) }. T3 M
D.一个警告,因为没有定义a::$myvar1 D( Y& w2 t, c! ?' X# q
E.什么都没有
$ Z1 R% o7 D& c4 h& e! N' O7 Y: B# n: V% c& @
+ m$ X1 p/ O! x, J3 p1 d$ m" n
18.如何即时加载一个类?  D& n. t9 ^+ }

  h% y' a! c1 ~; AA.使用__autoload魔术函数
0 ?/ _; z  _) x5 n% @$ y7 |  P' lB.把它们定义为forward类3 k2 n7 J: N$ N0 Y+ Q4 Y
C.实现一个特殊的错误处理手段3 a4 _+ ]$ ~; |
D.不可能
9 L# z1 R! D" o6 q" p) J7 }E.用有条件限制的include来包含它们4 D* ], ~. g* ]% s. n$ O
. U% B, U- i6 D( v
* `& [4 ]! H; \2 c
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?* u' N% R% n+ U
6 X; H0 `) J5 A) H$ o9 O
    答案:__________
5 b7 i& C3 l4 e3 A" ?6 [! O3 P0 o; M5 d; Q% T! R

0 ^+ {4 e9 Y: k7 y+ v* m20.以下脚本输出什么?

  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 called1 w) a/ D& N3 }! n4 a
B.一个错误
, N1 x& p+ @6 }  C: U# _* X: mC.一个警告
: _# k6 _/ G) Y1 t) R. uD.什么都没有
7 b/ f5 |6 \1 X6 B3 w" O
9 w/ j, i: ?3 a. [' Z# ?2 _/ f* F- A; A1 |' z  y3 z% t! ^

, z/ x- Y- c, x5 W% C: |. A3 ]答案速查* M* b* M/ l  m/ V, [8 i  z0 @& r
1.类
" A# Y+ u* \2 y, e! |2.BCD# ]+ @3 Z8 I+ p; Y& P: f! C& y' Z
3.C! F1 y5 Z9 t7 \7 j6 i& b
4.C6 k! Y$ h1 i* Z% L2 c
5.A9 V% W/ i- ?, _9 ^3 u: f
6.C: y) }% \0 r1 Z9 D0 j4 f
7.C" N" P1 Q: T: Y2 i% V
8.C
1 \, j7 v5 T; s$ |/ m0 R; J9.D; @1 ~0 }# [3 D/ I
10.B
; P8 L+ Q2 Y, c6 \11.D
  y: k0 ?) Z, q9 ]  T. y9 ~- h12.B
! b5 t2 X0 z) H( S% u0 e13.A
3 {1 v  z! Y  {) {: d14.D( u* W' X2 }  w0 [2 n
15.A+ f9 L6 y$ r+ ]
16.B/ S; Z/ m/ a  j! Z- j
17.A
3 f+ T/ ]. q3 ]. N18.D+ L/ M' ^, N+ l& m
19.设计模式
4 p" y9 \0 k& I+ L20.D% }! ^3 g$ a; d: q! J- j5 @
1 G% ]+ l) e$ [/ C0 t$ Z

: C, i! {4 Z% N+ s+ A* q: q! R) P. D0 S- P+ @
答案详解: O  U: [' V: O6 r3 a3 a  W- ]# j1 y4 O
# Z9 V8 \% ]' p
1.类是对象的蓝图(对象是类的实例)。& Z" V+ w$ p" X* O, M
, ]3 B3 O: \; T' @# U
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
+ s6 Q0 A; z# s% x- p' }9 \& z5 B) x/ Y' {* q: L3 `5 T
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。- M" w* M( \* y2 O, o

* t/ K1 N* b4 a8 {4.单件模式可以限制一个类被实例化的次数。9 k# y7 t  y1 j, I/ E* I! m
8 U% ^7 U- J+ F/ `) g' b
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
4 J& H0 G2 S9 l6 \* W( m0 Z# q! O5 H4 F8 A# {5 V* B
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。9 }! y4 w3 G) @8 T3 Z
2 z/ p" A3 I) I) z$ }
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。! q7 U- {" S" K6 }( O" i5 s

, d" j- Z0 c- ?4 U' y8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
5 |- c2 K5 n+ D& Y3 H
$ K! \) l; {& ~4 X3 _3 k9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
/ P" b5 r! K9 F. D* A+ U& `" ~% A; v2 x: a4 i
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。# v, Q2 z3 a/ C3 I3 ?& y

: r: N4 r+ D$ o11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
+ w3 M8 V1 w" a9 c2 m* K2 H
  _0 r1 \/ W) h) p12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
1 a; Y' E. z! l  @1 `
1 F3 U$ ]& S& q6 x0 i. @; ^- l13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。& G$ Z* D( X' w7 f
3 V% E' x7 S+ m3 b, K) O) o
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。$ M) }. k5 f1 v: s1 k
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:- h$ s: g+ q! X" a% u# y# I
    function reduce_fraction(&$fraction)& E* a1 G; t  @" k2 z' ^
答案是D。8 M; g0 |- S3 S: n% e

$ Q) a6 D7 O1 ^, \  z15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。& s- }" Q1 g* O* @6 h  ]5 n  x/ l4 W
" v  j! S: c' S
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
" _5 ]5 B' f% E) _$ A4 c% V$ a. y- v; k% i4 D1 d1 \6 C
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
: Z% n6 w: Z+ z7 e  R3 a% B
5 ~  A' C! ~5 t7 v  t5 @4 H18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
- v$ O* c, E0 ~+ o2 N: }+ U$ D" f4 ~+ B7 a9 X% x( |$ P% o3 D
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。( X3 Q: [$ `. l1 H

4 p& a* S6 C& H2 c( t6 @6 G6 J20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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