  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14189
- 金币
- 2385
- 威望
- 1647
- 贡献
- 1333
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
* H9 P0 M) I! h2 RPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。" D/ ]* m2 V+ Y. B) I) l$ Y( n# D
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。: c1 |4 W7 B9 f" u
% }* S5 ~- L) x$ ~/ m9 N7 a问题
2 T$ p" S& O0 B' S* U; _# M6 y0 k
- }5 b7 ]- C; `5 ~ @1.对象的蓝图是什么?
9 u# O4 w+ G/ b, ]) W) z5 b W/ k! y- Q7 P/ B
答案:____________$ Z1 ~, S: r" I8 [8 d
8 A' J% w% q0 U' J- I7 C: [" _( h
. j' I. H7 o' B2 v& s2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)-
- <?php
- class my_class
- {
- var $my_value = array();
- function my_class ($value)
- {
- $this->my_value[] = $value;
- }
- function set_value ($value)
- {
- $this->$my_value = $value;
- }
- }
- $a = new my_class ('a');
- $a->my_value[] = 'b';
- $a->set_value ('c');
- $a->my_class('d');
- ?>
复制代码 A.c# a4 r7 H r% [) y) t
B.b5 J' [3 P* \% ?; U4 D4 T
C.a
! l; v; L6 a$ DD.d
0 j% j% ]/ Q2 i3 J- J7 K6 gE.e1 P% K6 g9 z. L) }/ Y$ j! U* \
/ J! w1 f3 p: }+ D3 @
. S$ E' m. D( P3 x# h* P# |3.如何让类中的某些方法无法在类的外部被访问?
' \' w# H, A5 J2 n1 O- p
1 f# }% {5 {( }A.把类声明为private
6 I. U& l* y7 A# g! E# ~1 HB.把方法声明为private; G$ E# f" w7 y- k3 F8 K
C.无法实现
" d+ R0 n# k( ~- d# x/ d9 Y- ^$ W5 jD.编写合适的重载方法(overloading method)
6 v6 y8 r- Z' b* U1 ?) b" [% }) F! z6 |6 X
0 G; Y# M0 T$ ^% R4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
, E* N- @1 T9 ?4 B C2 ]# }! \4 R
4 I* w; a8 v* g* u3 e7 i; ZA.MVC模式 m* z2 b3 t# M% x2 N# l5 `- i8 T
B.抽象工厂模式(Abstract factory)
" L' D7 }+ D; D( I$ G( c6 [7 ~: oC.单件模式(Singleton)" ^ J( u1 _; A0 ?1 E7 ?
D.代理模式(Proxy)4 Q6 Q1 P/ H' {. E+ D3 X" D/ F6 W
E.状态模式(State), P+ f. u6 M$ z8 j; b
( S0 I' i z0 M" o: b
2 q+ g7 J* n5 R+ F
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
5 M, j5 _% A5 W. e, n, W. f
) p+ t* l1 H: d! [: F0 XA.1个+ p- R, U L) r7 @- h0 T: y
B.2个
+ T' U. b- C( E- c( s$ G$ gC.取决于系统资源
! p5 t7 H3 b% k: j. \6 ID.3个
( H) ? \" e4 c5 Z7 w0 gE.想要几个有几个& _" ?' \. A* J2 a/ l, p3 R0 O$ T
3 ?8 L7 B2 l; ?5 t& w9 q( k. r9 |3 n
+ Q( z3 i3 | y/ _6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
% e* }1 A4 D* C, _& z0 f% fB.接口% G2 r3 Z( I3 B& ?& f
C.抽象方法
) W) n4 f3 V7 g" p* N& ZD.Private方法
9 ^% g7 |! _; Z N' G7 @E.函数重载(function overloading)6 L3 o1 `5 D* O0 d. T
9 }5 d+ e3 n+ m+ B# t4 _3 B
6 I1 D( R4 G7 ~: Q' E4 l% W" Y7.假设定义了一个testclass类,它的构造函数的函数名是什么?4 P M0 }# Q0 \' F! `0 N& n
3 \' l; B/ ^1 FA.__construct: d, |& B3 p; d5 X2 U! A# F
B.initialize
! j! F6 Z7 h% q2 C- a; I* }C.testclass' N/ O( f8 L% P0 O9 w! H
D.__testclass
* B9 i8 N$ G. u' i t+ aE.只有PHP5才支持构造函数
) f4 u" L. w2 F( ]
. J) @5 K- y4 U, A( p' t: `* g* m
+ O+ P; }! w4 k. I# F7 N8.一个类如何覆盖默认的序列化机制?: E e, s% S b
; h& s: d# Y2 M- J& [+ s5 A' eA.使用__shutdown和__startup方法5 P$ s* u, P# Q0 |& S
B.调用register_shutdown_function()函数
. `+ i2 s- H+ v3 H% ZC.使用__sleep()和__wakeup()方法
! n1 @. V( a0 H1 H, YD.无法覆盖默认序列化机制! b8 Q* Z" |3 s! c
E.使用ob_start()将类放入输出缓冲中
% }7 B5 Q; }' x+ S9 V1 K
0 R0 p/ b. r1 P' Y* O
, O8 I- _, t% d9 |4 |9 d& V" @9.以下哪些面向对象的概念无法在PHP4中实现?
/ H9 a5 r$ l/ E8 u3 t9 X [1 K/ @/ p1 p
@抽象类
0 g8 d1 S, h- w- v. u; ?@Final类
' ^" x3 U" t G) U/ B6 c1 u: ^@Public、private、protected(PPP)方法7 m, V: Y, Y; E$ n7 W! Q R. i
@接口, H) L# O6 u6 L$ {! \& P3 p! r( j
6 V! m: ]! g. s3 _% ~A.抽象类
8 ~; U! M+ l3 z$ LB.PPP方法
+ H/ Y! z! B, ]6 L5 AC.PPP方法和接口
0 \5 x- M6 D7 o# @& yD.以上所有都不可用
/ e. G# F6 z5 A6 M9 SE.以上所有都可用# j- ]. j5 U% Q. [6 [. e
$ ^( F; t5 v4 H, t e
# z) @% h$ o, X t) X
10.如何在类的内部调用mymethod方法?6 |$ e6 y( m) q+ l% j+ g0 O
0 }; B4 r0 M. R" d! DA.$self=>mymethod();
- f. l; @0 u- D+ KB.$this->mymethod();( x0 r6 D1 A _* h* F5 H- o J
C.$current->mymethod();6 Z1 S# q i* h% y9 v) K# V
D.$this::mymethod()! n; e3 |9 h5 J) F
E.以上都不对
2 a. {& Q* x6 ]9 c( z6 |% |
5 U" s# v8 b7 n x$ D- k# J+ I$ X, {2 x' ?' v: ?
11.以下脚本输出什么?-
- <?php
- class my_class
- {
- var $my_var;
- function _my_class ($value)
- {
- $this->my_var = $value;
- }
- }
- $a = new my_class (10);
- echo $a->my_var;
- ?>
复制代码 A.10* e) @; u4 }$ I: n
B.Null) q' a* E* v9 t1 r& H0 j3 L$ h9 {
C.Empty
0 _! P9 w/ M- k; A5 d$ lD.什么都没有6 @0 c) H! V# l1 Y
E.一个错误+ ?4 m) A( u! }" m2 R a/ L
7 i3 A3 i) g$ U6 ~/ l% v9 a. P* w t2 L
12.以下脚本输出什么?-
- <?php
- class my_class
- {
- var $value;
- }
- $a = new my_class;
- $a->my_value = 5;
- $b = $a;
- $b->my_value = 10;
- echo $a->my_value;
- ?>
复制代码 A.108 z6 a8 c; D/ d0 s) |* Q
B.5
7 K5 h' L# [/ x- L2 pC.2
1 o; u4 ?! a6 j3 Y+ j4 Y( VD.Null7 p3 O$ t( j( l1 W5 `( O6 t( c/ K
E.什么都没有 U. c, n- N8 b* j* k
9 |6 N- `9 B8 P$ \, y( N8 S# l' S: j, L! Q
13.以下脚本输出什么?-
- <?php
- $global_obj = null;
- class my_class
- {
- var $value;
- function my_class()
- {
- global $global_obj;
- $global_obj = &$this;
- }
- }
- $a = new my_class;
- $a->my_value = 5;
- $global_obj->my_value = 10;
- echo $a->my_value;
- ?>
复制代码 A.5% K9 z8 U$ v% Y D
B.10
) V6 ]" z: o9 [5 { m4 _$ x oC.什么都没有& n4 B& m! ^( e5 p! w
D.构造函数将报错
# Y1 c* Z/ F, r1 S; KE.510
S$ p; \0 u& K* S. R: F2 p! X) Q+ O
# x6 V. Q( a! [! M& y( [) \14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?-
- <?php
- class fraction {
- var $numerator;
- var $denominator;
- function fraction($n, $d) {
- $this->set_numerator($n);
- $this->set_denominator($d);
- }
- function set_numerator($num) {
- $this->numerator = (int)$num;
- }
- function set_denominator($num) {
- $this->denominator = (int)$num;
- }
- function to_string() {
- return "{$this->numerator} / {$this->denominator}";
- }
- }
- function gcd($a, $b) {
- return ($b > 0) ? gcd($b, $a % $b) : $a;
- }
- function reduce_fraction($fraction) {
- $gcd = gcd($fraction->numerator,
- $fraction->denominator);
- $fraction->numerator /= $gcd;
- $fraction->denominator /= $gcd;
- }
- $eight_tenths = new fraction(8,10);
- /* Reduce the fraction */
- reduce_fraction($eight_tenths);
- var_dump($eight_tenths->to_string());
- ?>
复制代码 A.reduce_fraction函数必须返回一个值
: l+ u# F$ B* HB.reduce_fraction函数必须接受一个整型值+ I$ g) m5 a3 D; d
C.gcd函数有问题; \, v# k) x7 ^% t& u' o
D.必须通过引用的方式传递$eight_tenths对象+ t, S r) f+ ~% u' i' [
E.对象的实例不能传递给方法以外的其他结构。
3 L6 ?. u+ n/ z7 W8 I6 V/ Q1 @( A7 n7 a; ^( A3 S! R- P
- f" h5 E3 L# M6 |; I( [9 C
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法4 O; R7 t6 y3 [8 Z* E5 V6 b, E0 T& ^
B.生成myclass的实例并调用mymethod方法
* n! b# u, s3 ^# }/ v8 L zC.产生一个语法错误! i5 u0 ~9 O. [/ `4 s. r9 i
D.默认myclass类最后被创建出的实例并调用mymethod()% l- }, q+ J* H" K0 _
E.调用名为myclass::mymethod()的函数
" E, d7 J& j. e% l. ?0 b7 E
0 i7 ^: A) E( Q X1 M8 P, ]3 P- X
16.PHP中有静态类变量吗?. M4 @. Q5 c' L- A7 ^
+ r1 {; Z3 z2 a! A: B: q4 V; OA.有
6 t8 {, L2 a6 [% UB.没有; N2 i* o1 j6 _* H& K( J6 s# e
$ j; |! N' j! R2 a3 ]* K- g* D
" U3 c: _& d) w/ i! p. s4 ^+ Z
17.以下脚本输出什么?-
- <?php
- class a
- {
- function a ($x = 1)
- {
- $this->myvar = $x;
- }
- }
- class b extends a
- {
- var $myvar;
- function b ($x = 2)
- {
- $this->myvar = $x;
- parent::a();
- }
- }
- $obj = new b;
- echo $obj->myvar;
- ?>
复制代码 A.1
- T) N3 K* G4 C2 l8 l/ Y1 RB.2
7 z2 C% m$ E4 |$ O% VC.一个错误,因为没有定义a::$myvar% a6 r: `* v7 u0 [5 A6 F0 I, n' Y
D.一个警告,因为没有定义a::$myvar
) R9 \8 M+ H9 D- r% _& aE.什么都没有( u, c+ o/ Y% U8 i7 E9 K) {
2 r! M& ^4 L- @' A5 b1 I
8 k) F- Q/ Y: _5 i+ t Y# \
18.如何即时加载一个类?
1 z c; S: ` J5 p
' j. ^2 B2 G* ]A.使用__autoload魔术函数
0 E+ O5 j% f5 A, |B.把它们定义为forward类* l. h4 D6 [- d. w" U
C.实现一个特殊的错误处理手段
0 f5 A5 w& w* ID.不可能" h8 x7 B0 a5 ^& O
E.用有条件限制的include来包含它们
3 M0 K- D' q7 i) K7 R$ l
& F7 ]: Z3 }7 ]( z5 } `' K# g, X6 W* z8 v& o4 @, x$ c
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
0 `4 H% D8 }8 ^& s
, U' g' D8 U& K1 R; ~$ g+ A2 Q 答案:__________9 B# X0 Q6 f& p5 ~! s/ g4 [& J5 K
% `6 `. L8 [ f2 x& \' \0 i& z
4 r; {1 q6 |/ B% y" o20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
) l4 @0 b$ Z; U+ r* I$ G) h: `7 YB.一个错误
& E. t9 p6 R X6 Y. C+ sC.一个警告- [( \* U& |' r" e* R
D.什么都没有
$ @9 Y0 Z+ k4 [/ {
3 a5 `( ^( K* B7 q7 I9 _
0 ^( B+ q. {: O7 ]
9 e% S+ Q7 n& k2 O5 i6 @答案速查
6 ^. {# G4 K+ L$ ? A) E* r1.类
3 i- E, S S4 P; _2.BCD
: ?7 r4 G+ }' S; T0 i& w3.C
; v2 T9 |, ]$ }) E3 M3 |4.C
7 `. B, L2 l. a1 h5.A
3 ^7 S9 U2 G7 `. k; H6.C
$ t- W, H8 R x6 h# |# [+ V7.C
6 n x3 H/ [/ H) c6 @ O8.C
! _. e$ x) [% v8 Q, r3 Y, q9 L# u9.D
1 j1 s g6 t6 a: I4 a( Y10.B' f- Y' a% T- a& m4 Y* F
11.D
- a$ ]1 a l1 R6 |- y: t12.B5 b2 w6 z7 g* M% D% E
13.A
! }) C/ T9 l* R9 V; P7 |+ @14.D. x% k) U. N( }8 J+ P0 r
15.A
4 ?. T; v, v. ?; S d: F; f16.B
7 t W/ e) M6 i% s2 N# [' F: P- h17.A5 M$ E3 ]/ ]3 T. P) [& ~
18.D
6 S7 P5 s9 w- j19.设计模式2 |( @% O$ M- ? v/ e
20.D
$ ~; l5 m" F! ]. t4 m( n# p; r+ n" `! b: o8 o& @9 v) e5 N# j
$ {: U9 N" ~* v9 H$ F5 g% S+ Y' k9 D$ s) T- u1 S. W
答案详解
8 H7 F9 _ p: V% U
: E9 v2 i8 b' c: f1.类是对象的蓝图(对象是类的实例)。3 U9 E' N0 h. D0 g. {9 E; M
6 _4 `* |: D3 S" M9 Q5 J2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
) d% v: k7 Z {" E) f
0 G) e5 R6 @; i/ J4 v* u7 V$ N* w3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
( Z0 W( L6 n& F3 ]. Z, l0 W j; o
4.单件模式可以限制一个类被实例化的次数。
0 g7 Y+ I+ o+ y6 i
5 \5 O! G2 u+ F1 N( x/ \5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
, N5 T' @; i( T3 O: F9 r1 y
* E! @7 O9 P1 Q @! u2 H6 U! R6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。2 ]0 v) c7 S7 p% j: M
4 O3 K# z* K& w( n, `( C
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。- r! B: w( k: X; V2 h
: k0 o' ^2 G% Y3 S) h8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
2 F2 X4 [- Z' w- M% ?/ t* q; B
. ~* e! O' E/ t$ z( H! a7 e) i9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
7 u* w$ o5 J: I2 m9 y7 W5 S& e" b i; \7 z4 D0 w
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
8 v0 V7 b& z0 Q* {+ l; G1 B$ X5 ~7 i4 r3 t3 p* t5 P. {
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。5 f2 A; S$ ?2 ^" I ^7 k3 E! b
% O0 j2 G; U F4 Z( s& i! h# z [
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
1 x6 E5 b- T4 {5 a% R& D
, i$ P! B" B3 U3 h13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。7 T, V% U( ~. `5 R& Z
# ^8 F8 u4 F7 U4 X$ o5 l
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。) C/ V, ^7 v1 `3 N; [
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:1 k+ Y- a$ E( @2 D
function reduce_fraction(&$fraction)0 c: S& S5 T0 h; h3 ^
答案是D。
$ Q& Z/ J( J0 e. t+ [% i4 a. |$ m$ s4 t, ^- A/ y) `
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。! E" @3 ~( _) F- f3 W
3 A$ _$ j/ }5 _* o5 K; Z$ W$ E
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
* ]( l T& n3 \) |
% }7 D4 X. O1 f- |" ^* h; c17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
# C; Q W2 |, F& L
Y/ w$ |2 t8 K+ Q$ `18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。; T) Z. H4 E% `* C6 t+ N- O8 ]
, y& n) Q2 ~" T/ `* L7 A7 c
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。. {/ h4 H" [( W
6 j) y! g L5 a# ?' v( k20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|