捌玖网络工作室's Archiver

admin 发表于 2008-4-4 02:24

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
h F+q3A%[Df"U PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。5{-[O @H"E:r
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。;E6C6S:H)pDh+M^

*|`+_mm y 问题
XqB9_9{U^$o b-Y"{3y
V1l\7TY C:Y 1.对象的蓝图是什么?
z }0y3z?;r H ]w1a%v0v/s8_N
答案:____________wO@r[wd1['N`

6]*wB R [ Lx g"tr T
2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code]
x2}v(s0G8lkk <?php
_%M(|2QJ,X2J class my_classbX3k|C
{2pjO0Gq+?$C b
    var $my_value = array(); c&`Zs7z,[+N?w v
    function my_class ($value)7`b/m}*Mu
    {%@2~z2v/Q(MX9|g5r
        $this->my_value[] = $value;
sj-j6?[&j     }
)U J+V!A/]*Y     function set_value ($value) {Es4_i,X h
    {
_t3m-\:T!u.En         $this->$my_value = $value;
UT:C'H4}sIA     }$z2U{c6j$I;G1VC
}
&i m)r!W+}(T!u $a = new my_class ('a');w | ArG#wT(Tw
$a->my_value[] = 'b'; W/R/@4o|_ M
$a->set_value ('c');9Ef[4Xa8I{1j3o
$a->my_class('d');5s2Rn+Ne'@.^
?>[/code]A.c
{ o{B/L4_*h B.bdH,Btx
C.a
,j:~ ||0s4f#s!o3Q D.dU4z'CE&Dk
E.e"?kKY G oum|
0{$V%e7A0WJ*f.za

,OY+}5`)s%Z7U `R? 3.如何让类中的某些方法无法在类的外部被访问?
M)}+V7`-w)S)s`_ v-V1Wy&~
o E#i3L&Pj A.把类声明为private
TP gl` B.把方法声明为privateI#@?2t-r \j0K!M
C.无法实现
%O.gR1E0P1e,fXj3z&A D.编写合适的重载方法(overloading method)
`{Rn3\@5r_c/l2F
E;Yq"SAvM*FkN/x (Y7c.U;GV
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
xT2F'UepnO (v9e*kV)M'K(c
A.MVC模式
+Q o jB;`m `*O h [^ B.抽象工厂模式(Abstract factory)
u1|*oo5[J4~\4t C.单件模式(Singleton)
.m;f#H-f/[,f Z"X D.代理模式(Proxy)
V {8G;tp5P3lJ(B&~*x!` E.状态模式(State)
"J0J x$L"w,F3Z
5hM,T7Cu#u8S8w,@ D'C$TctE ~.g
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?nEQ"y#a _8_
:H@W/O.j c`pc9lx
A.1个 ^,XvR,w {8bn
B.2个
S5l#]w;NB9RK C.取决于系统资源wxR*V f.L
D.3个
4N$j\ H&MgJ#B+ub E.想要几个有几个
R:B ZR#k/V
7_#o1qcb\_6[%\ %ia.k V8C G!X
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code] f-hbGKtn_Mk]
<?php
g3f+I.HEn7R class my_classK DMP2p'^3U7| X
{
B9_xxu9t     function my_funct ($my_param)
o9I%o:KL!m     { f*X}1L;@C)|
        user_error ("Please define me", E_ERROR);
:dj1W1I,}(X3m5sx t a     }ys S_]
    function b()(r,\/A E"gF
    {
9CTQk*Q.t\         return 10; y1M1X;t2E]G
    }e7B5f iz!{].W P3h,u6]
}mg hp/^"_u~
?>[/code]A.多重继承
YE.G(Gl._ B.接口
yZ,Vr*d0ls C.抽象方法
^:e.{v&w8R#aS X D.Private方法
d5vdYP6` E.函数重载(function overloading)["l6Y[x

Xt4N]#vM2I?i t(n` ph~ gN
7.假设定义了一个testclass类,它的构造函数的函数名是什么?)P$KBA;STx'@6}4M
D1@G/r"{V Q,b
A.__construct
[xV Qz g$h B.initialize
:t~u v+k2o+N C.testclass
K~}(C5TAr"mn\ D.__testclass8h)q F*Ixwe]pZ o'm$I
E.只有PHP5才支持构造函数
f Yn ]H5O`;| 1DhR*a0^
G Cywh,J vT
8.一个类如何覆盖默认的序列化机制?
2Y{TZ,Ia2M N
\C*h`0q.v} A.使用__shutdown和__startup方法/d[gc^{V6\/Q8_
B.调用register_shutdown_function()函数
}e-C mO.I6kA C.使用__sleep()和__wakeup()方法e w8Y&Bj4l^/M \D
D.无法覆盖默认序列化机制0w5a'C!xA j'X,k P
E.使用ob_start()将类放入输出缓冲中 mQ/saB7PgYi

V&|x2M7A"vo P PJ
(NuC/`G[3B 9.以下哪些面向对象的概念无法在PHP4中实现?l WF,H,ST D

c$c vUJ E0rN @抽象类7qD"gQl%|+Lm
@Final类 ZC5N#]rLp"Ljt
@Public、private、protected(PPP)方法|5eC;bA HQ4V|
@接口
GR6NEe&m
+UIx'Li+uT A.抽象类
,Mf'?a? B.PPP方法
"x~5K:b&l)f C.PPP方法和接口
o B0y#Vb w'} D.以上所有都不可用 zG(];D%Y]3F
E.以上所有都可用
c u3Ul5MS*p8v7] n3V eiT1bRv-ps

0]6i.q@ M0Zi-{*~ 10.如何在类的内部调用mymethod方法?3ng3SD.uku^

6@fd q)R"tT A.$self=>mymethod();F:p zX Q6G-N
B.$this->mymethod();
J4o9X2e*z$|g1E C.$current->mymethod();
N:~wV;\6c3M?(R` D.$this::mymethod()
,?:Y sE$vM9I(s` E.以上都不对
S|Z*~.DTd
0l)?nr(I'a
kV8TD~q;s 11.以下脚本输出什么?[code] #?*a7nP:d`'l0KMz
<?php#@3P#{Q+M+LS#\
class my_classwZ{mF1qx
{
UO R8[_h(Y3bLZz     var $my_var;
:I?)h$kQ;E^     function _my_class ($value)
kS e{ I%K6Kde~}     {
8zR}:y#]j         $this->my_var = $value;
T"K%D(o6_f     }(vMx.aV5[4k
}7a*z*u#jKB
$a = new my_class (10);
%A)@u0W"A0fX:dl echo $a->my_var;DiB+m2L6L
?>[/code]A.10
v4pf&y VDl4D B.NullP J/j-^6B-y`
C.Empty
&MtL ~uL G s O D.什么都没有
#]3z%q?Jm$LQ0q E.一个错误
E%{(Bf[
_Q z`cxY+t1w`
&B"]#j9~Yz(o6zI}/O 12.以下脚本输出什么?[code]
'U#Gj~Vx`pjjI2u <?php
ZOY!P.f9u6Abe4wZ-@ class my_classO/gmx6D[6G0T
{
Y;NW[C;ia/Lo     var $value;s8koTR'MHq0d
}-V@)C5NdU1Y
$a = new my_class;
$E}(z A ?h9KN6Ux $a->my_value = 5;
s*k0q@ [ff2Kg+a $b = $a;
3}JAv;Pv[P $b->my_value = 10;8wUQd9}D?8d E
echo $a->my_value;:T%RF0|!N"Hn#w
?>[/code]A.10Ik#b XY-S-k
B.5
}N4N;mo!t C C.2xvW9o }5O \+m#|
D.Null
:[D;J)wt8d!NA E.什么都没有
I3zh!V6m j1bD
m*AA vb z*re6lniZ
IPSj ?&pLt(n 13.以下脚本输出什么?[code]
8_V9n'K-[7r-RA <?php
.G-|5\5]2uLV,T@ $global_obj = null;[,ca]9R9KE,xW
class my_class3~BA n#AB-~
{gd#^1q-qllm
    var $value;
c,_ SX~4E~(z.T6r     function my_class()
4v1jNY}"Y5@!lU$`]     {-cG%@~]d1?z8c
        global $global_obj;&M1pgb9xWQH
        $global_obj = &$this;\;rD%@2n ~E jLf G
    }
O+a x:?+e$e+j[ },_ V1o#C-I |Z(x
$a = new my_class;[7O E_+IaR0N
$a->my_value = 5; ic.x pc(^
$global_obj->my_value = 10;
%E1|+P4f#U/Zo echo $a->my_value;_&n*CSwY
?>[/code]A.5
t+El t(?6R0[)e B.10
F-T3Y&C*o{ C.什么都没有6m X3Qv2D"k
D.构造函数将报错
dnoGEk E.510
R,L4qYi] w)^ f a%rg7csz r#n
x$D idT,{:x Nm:q
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code] (R4~#C? H
<?phpX:cn q.V {$Te
class fraction {5rSW^rX
    var $numerator;1`&n ?2U*l uK
    var $denominator;
)U%kURsT4l1M Vj     function fraction($n, $d) {
roP`!Y'?1\         $this->set_numerator($n);1EE,gEqn]
        $this->set_denominator($d);
2O.X'R#?R$Yka     }
,{ D4r"u }{x7? l i6I     function set_numerator($num) {%Q0@#b)J+nJE)J9M
        $this->numerator = (int)$num;u_;klbp7[
    }
.G+o#B8x9ch|8m     function set_denominator($num) {
c Au&W3i         $this->denominator = (int)$num; c+uh _D+^,[jQ
    }
T'N'w%`pJ(g)W)]     function to_string() {mY0n9?s/h
        return "{$this->numerator} / {$this->denominator}";I8LD7K9s.j4a_b I
    }
5b6s8T c*};Y m:N*G }
,T:~+n d&` W{0r#IW function gcd($a, $b) {HQ/ba B om1fF
    return ($b > 0) ? gcd($b, $a % $b) : $a;
Kd^I.Z3{Zg+?E }
wHw4@5G1Wj function reduce_fraction($fraction) {5vn/D5U1c@
    $gcd = gcd($fraction->numerator,
v o7^{y#O4`     $fraction->denominator);2R SB-q!y}j5UI
    $fraction->numerator /= $gcd;,_m+B"m)sYA({
    $fraction->denominator /= $gcd;p*u] z'_T~
}
c[ zq7j4Z%~C $eight_tenths = new fraction(8,10);
`,~u_-] q"a /* Reduce the fraction */7cL^7i}*A{
reduce_fraction($eight_tenths);x{.u/?@
var_dump($eight_tenths->to_string());9SV&Uc[H
?>[/code]A.reduce_fraction函数必须返回一个值
)B1g z6?$F[ B.reduce_fraction函数必须接受一个整型值
C+Kl%gg ^c1XIp C.gcd函数有问题_'Fqm;S5g-f
D.必须通过引用的方式传递$eight_tenths对象
*?%s"cIB E.对象的实例不能传递给方法以外的其他结构。
#On PX&[X7d\W 4Y&IL;Ox'x

-g\Pza H/x 15.以下代码是做什么的?[code] H/loQ]a
<?php%gQw6HF
require_once("myclass.php");
:UE3x`K&S1Y8p9o myclass::mymethod();9^tg:qAg7DR
?>[/code]A.静态调用mymethod方法]].vGq
B.生成myclass的实例并调用mymethod方法
ZaU&sJ|%pK C.产生一个语法错误
|1n`9`T+i_ D.默认myclass类最后被创建出的实例并调用mymethod()jzr$N T/Y2f2`
E.调用名为myclass::mymethod()的函数
B%yb2x;W%d2wf
hAj1hgt &jQ'nA#m2yi*A^P
16.PHP中有静态类变量吗?
Q%T ~o7R!g|
O$e8f+Ga+[ A.有d U/~$]*Y|b
B.没有
1iHB-VmI 7FEBK+W%m
S2n"@X)M3waA
17.以下脚本输出什么?[code]
LP1Ikk0E&e;G <?php?0EF C1`~4m
class a
^#_ `Ji)OHUF { {N)d*r+zU-O5j
    function a ($x = 1)
!Ef \ e5s R(l     {
_[f/kmdp!_%G         $this->myvar = $x;-?xQ0v.Z5G:Lk
    }
y*J| _` MJ? }
*q)M2nNu:?]&gF4ON class b extends anm1AgU}3Y
{
$?-B&t4PHc(o'Z s     var $myvar; F3H!I w Y?.K4}l
    function b ($x = 2) u edL]
    {a(@~T4Y~%@:{.o8aP
        $this->myvar = $x;W4U4Yq:\ PQ
        parent::a();
1Xb0CD o     }
Om.d+q bX M3cx }
dN"aF2`}5wF\o $obj = new b;
4JiS)u)F echo $obj->myvar;8R&q/i/IWb8E
?>[/code]A.1T7g@/Z kNzB%?)w
B.2t1X[ `!p+t
C.一个错误,因为没有定义a::$myvarV8R8k j@ r(VSK
D.一个警告,因为没有定义a::$myvar@)b"e d'L
E.什么都没有3{"d%B4K7f
+{~Wz3}7|No
](c$vZ7r.P
18.如何即时加载一个类?`b:X$yG8vn

yWSK#y m#d]u A.使用__autoload魔术函数
n$op9v?&Vl B.把它们定义为forward类})NT8y(R7n W
C.实现一个特殊的错误处理手段/G&Y*h d,v'z*Z#c
D.不可能'b"D_B#OT Y*kl
E.用有条件限制的include来包含它们&GB l"ms%P;TP9p \

L-h.QuGwrC6H A,Rc AP p
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
&VI*is @ E Z#U
X4n J8h%C[     答案:__________(DsuA7x5C
Vf%YLx!H
3s\;l;yH|
20.以下脚本输出什么?[code] L e9~6d ~
<?php~,_Kl&k zF
class a
F]nTiJV {9nm|RCS
    function a()uZ({/KM(}
    {
n/J"Phl)K:w0K         echo 'Parent called';3fa$OrR
    }
_;p~kh,}x4x }
a+z*d\)j5hEs1Rk0O class b A"] S:j~L'R2AJX(R
{
x5U3`/~C4` JM     function b()]v(b:H~#I'y&F
    {XR3Y6k.Zcz#L!KW6ep
    }Z)ZN0OI)E,u9l
} CYPXC
$c = new b();E4C1z2s J
?>[/code]A.Parent called2UE6|(p%x
B.一个错误 Yx:BeT1^;f
C.一个警告/IoL3K6[
D.什么都没有
*R XO4Y/zR
+{5IX U V V -Af a:{)g A

@3A}[(D}2D 答案速查
]r2J7p;C&@q 1.类
.x P8j:h^;p 2.BCD
(\"E#wm_ B[ 3.C&Zz cT'P:~
4.C
w g-S$SD(s0kKp 5.A!sx1pe;Lb
6.C
9e!\)ak#u/|sz%J Z+k 7.C
_3f@ nK{;\ 8.C/Zd9p2Wk@0l+].B
9.D
p ZX&C{qP 10.B
vs!A)b!bZ@ We 11.D4E7x*P,AdN[7Em j
12.B
-TQP%Wh&lmS+A 13.A
`oq?#s 14.D
u6C[ ~DWp8T"D7Ub 15.A,~ Ecqo
16.B?$l+n*T Of0Sw*O!O
17.A s#n0JY5@M:y
18.D [9Du khb
19.设计模式1Q7vYhY-O9N
20.D7y{Tl%i1M6m{E
Y&j:IK%ry2D1F*o H

BN:hK,O$\F
i$[`ZJT4K 答案详解
:[ G m!`,O F#z#q? `K1yG%^(Y(P
1.类是对象的蓝图(对象是类的实例)。
Y AeP'@#eXj 5?%G2FW&t/M9y*g
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
8io;@ QZ&W+]X?
h5k4i(T K/u yF!g\:a0^ 3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
hAXg.flc
dB(Em)O {qf^ tZf 4.单件模式可以限制一个类被实例化的次数。9|&U#g^!rG ?]I f;z

ApB]1ia0F"x 5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。 y&m8zB,x/C

f!I%P3tR+KHH 6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。f6p%id*Yhoa9v
|M8o3kd
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
uCp&U,}^\4{
DI%r}dm._] 8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。$cD1yB l0J Ei Z,Wi
#gn S'h4VD!`(Ch
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
0Uo?2x m;N(U'T#{
%z I jXK 10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。~Zfa@1_

O3Uz] Mt*]G 11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
7J+rs7|(Vqr
tA Pv}*} 12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。Cl4l;N[%hy

`q*G]:T8V 13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
!SjE"ZX"t3F^e rt'r9aVM
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
} n8^3@Ap8U 回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:zp3L-njF&Co
    function reduce_fraction(&$fraction)}3_b\%K#} [
答案是D。
-ZCJ uF.Uh
!J\E;B;?(` 15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
4XIQ"O#l p-Rq *y_.k"zn/G
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。\"e%i^Ep;u7i0x
En8\%x*|:s"TE
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
N7ru9y)Q)z5VO 9h cpX;N0b.D
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
7C4t0X9@-cg $W/d D0@ YW
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。/Bz uD:d^+}

6Gx`&u} 20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

页: [1]
【捌玖网络】已经运行:


Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.