  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14159
- 金币
- 2370
- 威望
- 1647
- 贡献
- 1318
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
' W, o% z% R7 P- vPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。2 T5 T% o4 B) S1 c1 |$ q
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。( a3 {! ~9 ~. P6 m; T4 j
5 Z& X6 [& v( Z, g; J% L
问题
9 m# y8 m" Q6 B5 C! f" m1 X C
4 [3 l% j/ {0 K7 Z; w* l1.对象的蓝图是什么?4 O5 v* }* E* E; W. o
+ V1 l M, U7 o4 ]
答案:____________
; a8 ?1 v0 a- b- X: @. q# `$ j9 p# I
5 r2 @ B1 Q6 l8 b. m2.以下代码执行后,数组$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- t, i# N9 j2 c) V6 E# w3 Z
B.b) a; S) ~! f \" [# y9 g
C.a0 z1 M1 w* Y* y( y" C/ x
D.d
# T+ F: `7 d' m, a2 P* N: G% }! p1 kE.e
8 _& D/ y: t3 c9 G3 m* A; Z
3 {0 [1 w) G% ?: ]* V2 k' v6 L/ N$ q2 e
3.如何让类中的某些方法无法在类的外部被访问?
8 e; f9 w' Z1 S0 r, g X& A; u
9 x' j* B c- y' |. v, f. Y# DA.把类声明为private' x7 R# \: M+ q3 P d% S1 Z0 _ p
B.把方法声明为private
! F( v! b" ?+ k9 PC.无法实现4 Y( X% X# F% ^ U" |& ]
D.编写合适的重载方法(overloading method)' p' k7 _3 H' z# T1 C( h8 v
0 I7 v2 \7 U( l, M) x6 x
6 T/ q) u9 w. h1 n6 J4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
) v; w8 g' R# Z
2 T e2 }8 H1 {A.MVC模式" { s+ r! F3 j: C' V4 M
B.抽象工厂模式(Abstract factory), F8 T' y) N. Y) Q' U1 X
C.单件模式(Singleton)
+ r( S8 f+ g l! U( V; D! B ^( u: L: CD.代理模式(Proxy)
& G/ M1 j8 A3 h2 D: \E.状态模式(State)( k+ d" }6 Z3 a5 k- y
: U" ]9 b5 L. g% u* e, B' _$ ?& u) U
! `, K5 I' ]6 `/ q' U5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?& g- u |5 H* \8 N% i; n$ b
3 |2 ^ o9 U7 x; ~. z
A.1个
# x, b" k5 ]" ]/ Y( EB.2个0 \4 c# R: t Z8 ?4 J; w
C.取决于系统资源
2 N- n9 V" q3 `# H. E% DD.3个7 V, p! i1 J1 P, _
E.想要几个有几个
# z- R) ]# I' ]' w8 \, j2 a8 D0 L7 d1 A( @2 t; j
$ L6 |3 Y2 `1 }2 Y9 C; w' s" }6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
: G. }1 o! K0 E6 ]+ Z! b' MB.接口9 `" e# Z1 O& T5 I8 `) H
C.抽象方法7 V: I8 V6 E3 _9 h5 b
D.Private方法5 [# k$ a* N/ ^4 Z5 Y/ y
E.函数重载(function overloading)4 [, J. `: D) N( t4 s% p! e
* P- v+ T M! l+ ^
$ z* X% n3 k/ N7 O1 b7.假设定义了一个testclass类,它的构造函数的函数名是什么?- b; {& ]6 A, s/ }) ^
9 v/ ~) S$ P4 _" s' y: BA.__construct o+ n R3 C, Z* e4 `1 y3 m
B.initialize' H$ ?3 S" [) ]& [1 y% N( }
C.testclass0 `& r, x: ? L7 M
D.__testclass) x' F. z ^6 k* s
E.只有PHP5才支持构造函数0 v D9 z; L+ Y
4 z8 L3 ^) b; s( V) G$ k# ^
' k) d3 j4 `/ E9 T( y" x/ {' ~; j' k7 z
8.一个类如何覆盖默认的序列化机制?1 M: O( i# W3 L' L$ t1 }
/ F% [3 Z9 v+ Y) a# k! Y% {8 m- LA.使用__shutdown和__startup方法
- ~+ T7 O* e) r! s, B5 a* n- N, YB.调用register_shutdown_function()函数
6 W- F2 F+ h* q& uC.使用__sleep()和__wakeup()方法
8 Z) L$ k. c2 t. g3 k! AD.无法覆盖默认序列化机制
: U- t- t4 i0 f+ O2 Y9 N$ j" C3 ZE.使用ob_start()将类放入输出缓冲中4 j+ y0 r3 _' O2 `/ f
. ?3 M* m6 s k: u; s5 r' _4 b2 q* W+ v. h T! P
9.以下哪些面向对象的概念无法在PHP4中实现?
7 S% s% Y2 F& w) M/ j
3 p) N: w& o9 g+ X$ Z) O/ R@抽象类# {6 b" F8 T7 l$ Y9 d
@Final类
6 ^! E4 |" l7 M4 E* U% s! s$ r8 m( m1 c@Public、private、protected(PPP)方法0 K5 r" |3 ^& ?! U/ s
@接口: m' d$ o% l; n1 m/ I8 h3 C! P
9 H; Q) F$ x GA.抽象类
/ U# k, k8 m) |" KB.PPP方法
( Q6 n- S/ B1 `C.PPP方法和接口) q5 D- [4 i$ V3 {* y
D.以上所有都不可用2 N3 R4 Y% Z7 F( S; g! q- ^
E.以上所有都可用8 e5 V& k8 s- ^! c1 b. J( d
T" N- ]3 |. F) t0 g' l$ F0 E0 j1 F
10.如何在类的内部调用mymethod方法?+ \; @" W' _% K0 d0 e3 z
, R8 D$ m, O* n
A.$self=>mymethod();
; {" ]3 t4 ]" `& H Q9 a+ jB.$this->mymethod();
5 _/ b4 Q0 a5 T& B! CC.$current->mymethod();
: S9 E8 {' q3 G/ m- ~0 q" _/ gD.$this::mymethod()
}9 W$ [* B2 I* d- lE.以上都不对/ F& @0 N- e$ j' z6 n2 A
' n8 W5 y! C$ Q3 C2 k+ n1 ?
% Z" y; L) D. B9 @! V11.以下脚本输出什么?-
- <?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.100 T4 P' k$ @; w; f* e
B.Null
7 }6 u% Q8 A" Z) f* P7 mC.Empty
# j- ^: g4 Q& b5 Z- Q* HD.什么都没有) d+ H b, N7 e- O' B/ F
E.一个错误2 O3 T/ A% p; r$ Y2 ~9 o6 @7 h
) Y) Z6 S6 @/ U! r! Y) O0 c: w
# @9 e+ N- J) R" f9 b" W& g/ e
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.10, Y1 R5 e3 m$ P4 ~% n
B.5
# e! v, \( v) r, TC.2+ G- ]: h/ N5 {* t- f) {+ B6 h
D.Null
, c2 f7 `6 O4 d1 n9 Y$ ?1 KE.什么都没有8 @# K. `( V$ q7 @" I
+ m" O" p/ ]" `; M5 w- v' j! D
9 m4 ?8 L- {1 h1 l8 M4 n13.以下脚本输出什么?-
- <?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.58 o9 P0 f9 }: J& B1 p
B.10& K& @0 _0 g8 `
C.什么都没有- W4 S4 x% i- k% Z5 P
D.构造函数将报错- q( a% [9 b& v$ r& _# [
E.510
( Y, E0 w: _& U# X
$ U0 n a! o* U! ?6 D3 L9 I5 B# n/ u/ z! h7 F: {
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函数必须返回一个值6 U; D" {. Y# |+ Z
B.reduce_fraction函数必须接受一个整型值5 f4 X& I1 Y- ]2 W: x8 C, Q6 K. v
C.gcd函数有问题
2 Z) J4 [- m6 S5 XD.必须通过引用的方式传递$eight_tenths对象
2 [. V" w* ~1 ~) o5 @E.对象的实例不能传递给方法以外的其他结构。
9 r9 M; E0 U- S, }: r7 v2 s, U- a6 @! |
7 K4 H( f( N$ V& O
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
) @/ {& k6 K5 Q/ B1 B7 {% Z1 S* YB.生成myclass的实例并调用mymethod方法' A; w- Y; D( i" H, U
C.产生一个语法错误
3 _% |+ i8 f/ B. e% P$ t+ c0 R( _* sD.默认myclass类最后被创建出的实例并调用mymethod()
: q" u$ d# Z" n# N5 BE.调用名为myclass::mymethod()的函数& I1 O8 \# x3 d/ L, O" h5 M
& C2 h# C4 I+ W* E
& T9 L# ?; y4 H, u0 w16.PHP中有静态类变量吗?
2 o" C8 ` y' p9 L; `5 `( C
) l9 W( i9 H$ ?A.有7 R, u6 ]. n' w( O" f! ]% \7 ~
B.没有
2 r7 }4 e5 l2 w0 K( M3 J6 h, s, ~7 F) X( n9 Z# T: b7 {
; T: x: n+ ]' c2 _9 }% c17.以下脚本输出什么?-
- <?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.17 X) n0 F2 B$ h! t6 J; g1 {
B.25 Y! T& J7 X8 @6 l8 n
C.一个错误,因为没有定义a::$myvar3 Z( }6 O! P) x' ?; Y6 j
D.一个警告,因为没有定义a::$myvar5 F; L8 F; B! @! b; W5 P7 j
E.什么都没有/ H/ F0 [4 T7 H& U* Q+ E' \: @
+ h8 W- ^- ^5 H' b$ w8 g( }8 b- z5 S6 g
18.如何即时加载一个类?+ t7 v L! y- h/ ~; {4 p* p
) ~; s3 D' J; o# R. t) U" A$ i5 W
A.使用__autoload魔术函数5 c' L" n5 o# i2 ~2 o6 ^
B.把它们定义为forward类
. D4 Y% l! D r+ ^C.实现一个特殊的错误处理手段
7 b" c. Z4 `2 t& m6 T5 N: k1 N& Y7 vD.不可能1 D% n1 y- q0 S4 ^' I
E.用有条件限制的include来包含它们+ W' ^; [9 E& a3 |
$ q4 o' f4 I; f7 k8 ]2 q- i- N2 c- P+ X( v3 D5 F
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
t2 c4 Z& U/ o& m% Z
1 a, S \) Y" ~5 y% ` h* E6 w 答案:__________- }# c+ v: n: Y! F$ ]# X L
( D2 t6 P) ]& ~, q# A: g
`: T- y% s2 w( a' g+ Z6 K1 X20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called, o- L- X7 |, W7 o. @4 Z9 G
B.一个错误) T" b. {' f3 ]1 ?) L/ z4 e
C.一个警告
' ]# _/ Q+ J) Y5 W% a; D8 l6 CD.什么都没有3 A' w8 }: D* i8 a- V' S
' V" G4 x/ ~, v
* w' b; I) ] Y) u. \& M
; r% I( K5 D6 T/ l% G答案速查
) I3 h9 v0 I) x9 t1.类
" A% a/ a! K% F) m; K& f2.BCD
. q+ o7 ^) s0 N3.C
% `, R! g! ^. X8 ^ M4.C
# z& g U) X q7 a5.A
2 {0 X; b7 C9 W- m2 n9 R* [1 F$ |6.C. Q p, L9 Z" x7 h/ F
7.C, A3 F8 L& M+ `, J) [/ P+ g1 r- n3 s
8.C
" o; p$ p5 G3 Z. ~; J9.D
T: L8 k w* }) n' [# I- P3 y10.B" D7 l. @# ?. x6 _7 U8 v
11.D+ X3 s0 \: Z+ b7 M1 t7 D
12.B
4 c+ L! o' u9 `; t. O13.A: {8 T7 n' ^9 o9 L
14.D
7 u) }! L( K: V( v' o) e: r+ V, r$ P15.A. U4 P/ S& N4 J& O8 R3 J! z
16.B
9 `6 ~$ v. k5 ~* T9 [17.A
8 n3 l& S6 H: D0 s18.D
; k4 a$ v' x1 A0 A% R; G19.设计模式$ \7 Y& A. W# J) ?7 P
20.D/ m# R: P/ S" ]* K& v7 h
/ O9 G8 _# C& N+ [6 O' X/ d) w3 g. s
/ `: n0 ~0 D F' |4 N0 D! t7 l# C, v- R, k1 f
答案详解
0 P% ]0 |9 | r a5 z2 ?# \* K( m9 f. N1 d! u3 E2 ]3 _
1.类是对象的蓝图(对象是类的实例)。
3 a( q5 K7 K, Z* |# \3 ^2 x
: }+ \, j/ q8 w8 j" d6 L5 A3 e2 I2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。5 F" f6 Y! {+ ` `4 P p5 M- l9 O$ L* ^
' R/ _# m. ]2 i9 A2 U' P7 x3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
% }0 d& J* S/ g) X S6 L) }9 A" h
4.单件模式可以限制一个类被实例化的次数。( b0 A& Z0 s& W8 ?: `. ~+ X
+ N) i/ K$ o$ h1 o9 d
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。$ d0 g& @' B% \+ z' M5 Z/ H
4 {7 i) ?6 A7 ] z6 m8 D, _6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。7 s; q* T" F/ A- H9 K2 n2 g
" {2 `$ P) X6 J2 k5 z8 ?: Q, t( V W
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。* Z: h. L. |& a8 L: y1 L
$ Q6 N" v( `) ~" w' l1 Q. T8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。, ^. ~, z! s/ Y! x! L! y; c& C
5 L$ f2 `( w! V& w9 h: p4 n$ v
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
' y; Q, v& K: G- ~" N [
' k+ d. B; u2 s10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
$ N7 W1 b. P9 F# Q& O0 K7 H
+ Y$ r+ k; f6 u- S11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。9 {# q) \9 V" M# H, w# t
, Q. b, r4 a# y/ T
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- d1 ]9 {0 O. n$ C/ ]0 I& v6 T
" D9 |) p8 i, A0 |$ _
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。* L3 ^ k/ @# L. P" {2 O( F. l
3 b% R' `( }8 C0 o2 T" h4 f14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。3 C4 v- ?3 S& L% ~5 p
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:1 F5 } X- F( B, n" ?. a1 M
function reduce_fraction(&$fraction)$ d7 ]9 |, Z" Z7 U) @5 c* H! t
答案是D。
' T4 W. d7 d8 _9 |4 Z: F( F) L( P. m
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。+ @# j: N% g4 l$ @( T& N0 S
' b* b- t. v `, _: ?$ @
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。; y- Y ^. w4 W# o
+ ^5 b1 ^, m3 E1 {" Y17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
! y+ |+ h: g' y# M5 k8 ~$ b9 K
: O6 H9 N% [! h2 w: s/ c' _18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
$ k7 V8 |8 C5 b6 g% l& P+ [6 ~+ f2 v S. F w" m/ G
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
. I+ n+ `5 N _/ _
6 X/ g" v! f0 v) U20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|