捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。 D-HJ+_JYb(x%P
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。 F;I9[5V n#q#il ix6b
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
:gi`%\] f9B HUe "^(yG\KV)rwXYUW
问题
3L'mwfN(B$I E#o|u0V u o1x
1.对象的蓝图是什么?
8J2Ai;H6U8x5X dmH5N:L
F$o3rI6aCOU.o 答案:____________
k-I:`9^:a Yg
5]~,\8\2F fj*FpZ z
v(c0G r} L 2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code]
8tLK!V3_ C4fn o <?php
f#gB7{c,^?@W6b9@ class my_class3~W"|kr+}@|6{
{
*uBBK j"{6p5|h2H     var $my_value = array(); d;CT d8^zj(t)\l
    function my_class ($value)
1vx s*p!kw     {
m:X Yt:A$T         $this->my_value[] = $value;p:N*v$C"e}
    }Aoo([h&V5C3S
    function set_value ($value)
F-mvt9Y] |     {]q7Qb Z spR)vF
        $this->$my_value = $value;
+B\1W\z,c2Ct1\'S     }L:Dl?)e6M
} JHT#UCf W
$a = new my_class ('a');(xHw,s RB
$a->my_value[] = 'b';
{Cy1\L)^W!u $a->set_value ('c');^3e~~XeCpN L
$a->my_class('d');%^ y S5C,A)Vw
?>[/code]A.c
V@:M"pyUg U B.b
-}8LX_I'Q ^P C.a5} I,HI!QO!N n
D.dt&BMR@.L4XR}
E.eC l H.q f2g[b;R3l

h:Hs6uD LQv!O (w3QX @(m.X
3.如何让类中的某些方法无法在类的外部被访问?0IW6q&JSw
D-u8L2R1C
A.把类声明为privateA2`%Y/Jqc5l v.d;Q
B.把方法声明为private"yy"g q R
C.无法实现
?AI9n+vc(w| D.编写合适的重载方法(overloading method)
hH*^z:Z.^6P-a'e 7W7p0p)Ycv

)_0Ims0t;` D~B 4.哪种OOP设计模式能让类在整个脚本里只实例化一次? C"ZltaX

8j4}&u7H G A.MVC模式h8UA'A8~Fwy,R9qJO_
B.抽象工厂模式(Abstract factory)
1I B+O EKm C.单件模式(Singleton)
[];k J6w'Fn@ D.代理模式(Proxy)^;Zs.C!j7|5P
E.状态模式(State)r5Wm-VQ OD$U#g
;?P6F D%a,?*`%q/v!e)X
bguxB1hs
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
W)}4a7?c8X k%Tg)q5m:@
A.1个
YDTc4\ip2b B.2个
7NhC g#Ak(t}L C.取决于系统资源
%N)ATU+r(Lq~v D.3个
F+u p8\o E.想要几个有几个z/[!@!Y3_K*r{
M"W/a#a~*i&h h|
AS0i}n:CVIz
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code] $R-jvE kfn
<?phpf.`qfht:iqs*F[:[
class my_class
9VG.z6r9{0|/M { D&L~#q'[4B pW
    function my_funct ($my_param):A2v+i,^[
    {j*w R8S%u
        user_error ("Please define me", E_ERROR);
(B{4Gij!YW-E8x+~     }
9|*?a+Z%p1JCj     function b()
mGj CBV4F8Q|x     {5{7R`3PO,r(Q`
        return 10;
M:uD,r#A7?%|&H     }
.P _}kg5d7w6t }
:uB,G:H@6Dqi(l4k.`V ?>[/code]A.多重继承&f D"W*C(C
B.接口
fiX _wxS C.抽象方法
cd&_ r4Q9v X p D.Private方法
T-v3Oh{dv.Cu E.函数重载(function overloading)#lK'NF]

?(b6G5S$bl^B xK/Kt j
7.假设定义了一个testclass类,它的构造函数的函数名是什么? D[ k-i oQM
_Ea c"?)V
A.__constructX#oi)?+C/W:q*b M
B.initializee5Rc0l7Yu
C.testclassm7`"IdC Vo
D.__testclass
U({qS5r8j$R8r!x E.只有PHP5才支持构造函数~@MI)u)z3O4lu

+Kc]:aP#s hI
x~RMis${ x 8.一个类如何覆盖默认的序列化机制?
2z;?,G q;U'nR` 5`fd%C I$y
A.使用__shutdown和__startup方法
v[k b9l#Ke2J-Ek B.调用register_shutdown_function()函数
PeU;}S_;_M D C.使用__sleep()和__wakeup()方法
}.uzK7@m D.无法覆盖默认序列化机制\aTn0U0p$YW J)j1_
E.使用ob_start()将类放入输出缓冲中
]\$z(p9m:F}v
Z4W B%OO/VUnm{u +t7TGw2[Xz!l
9.以下哪些面向对象的概念无法在PHP4中实现?+kZr8`;b

6c&\Tj}!]8dB @抽象类
$xi dw P @Final类&P Q2@,Pe
@Public、private、protected(PPP)方法g!J0X2M a n!x
@接口
OUMv!F*hH yl.\ B4T DR5F4E{U l(k)e
A.抽象类
f"x(T Q2L:m]cm fn9H B.PPP方法
9K Q5UGo2@RY*his C.PPP方法和接口
H&Rm(S E%@ D.以上所有都不可用
-`2e&y3Ab Ga fA,XV.q E.以上所有都可用
0j`K!cER? ,G}S_z0h#z$J5n

5^?,uN L 10.如何在类的内部调用mymethod方法?Q6o3p/aL
2T2nINs4j0[%Jl
A.$self=>mymethod();
E,s y&}-UyPq%W,Wq$| B.$this->mymethod();
A)|x?-Z'w,\d C.$current->mymethod();
3]k0zS~5itg,k9A D.$this::mymethod()!X%JzkK5FG
E.以上都不对!v$x;Od7_

;G*p4Z`0g5F[ L*[5^3M[k#X&C2t,z }
11.以下脚本输出什么?[code]
(I}?UwuOP'[ k <?php
*W'Qs7x#yi{#c class my_class
7Fs M,{(p E8e5G {
8w v rO|*IBfJ5A     var $my_var;6\c$v$}r*} v F
    function _my_class ($value)
*O'S7k|'a     {l'b#NUy8b,I
        $this->my_var = $value;XD&s b3\&C k4Y8jL
    }
s;b_s0Qj:rh1N }
j9\P'B*GQ\ $a = new my_class (10);Vf y~.?5xbP
echo $a->my_var;
`$N[ O5{5MOY ?>[/code]A.10"g iYvG3d*nO%e
B.Null6e+vQDMY5F
C.Empty nBt2u:WH
D.什么都没有M~1@d%M!X"N6AL
E.一个错误
\']HE[Z]+H.D
{ZAWU-n9p%F2jL :|)Aj5TF,wh,JM
12.以下脚本输出什么?[code]
A,c ve u&a#ye <?php
rT FKaX-xQ class my_classOM it\Q7^
{#Sgaz/U*LES7V
    var $value;#Ts&e-r!T7|2~6k
}]Pk E T*C
$a = new my_class;
u,{7F&pb^,y $a->my_value = 5;*RA0Y.d tRt6{
$b = $a;
S;dv'YQn $b->my_value = 10; s4H5a"Q5rJ#q&N
echo $a->my_value;4Eo4T+T4?x
?>[/code]A.10(ZIe2E0j)a@J&x
B.5
/Z3L|oV]W-z @M C.2
Sl7L7_/G8| D.Null(x xE,_ H:I
E.什么都没有$p uDV}6_

7K,V2v&l1N8VN p g)cdl ?XT
13.以下脚本输出什么?[code] +@%lO7[tN k%VF
<?phps)^] mp&dUl\-ug
$global_obj = null;o9s5{id&A R @"}
class my_class
4ub4|d IKm {OuI2v(YE
    var $value;
.QP hn$Wq+|J     function my_class()
"~:fa5J r?[     {
~K^E M ]         global $global_obj;*E kW/eIP@
        $global_obj = &$this;Y ?@-Pnd:ze~+]+d
    }
\ _?6J` p }V |I1}l-jk
$a = new my_class;
`]M%`!iK;^p $a->my_value = 5;
J+y]q?+~ $global_obj->my_value = 10;
i~:CL4K y$w echo $a->my_value;
!o%S:r$E }G ?>[/code]A.5
2z&M'u.o:eg S4Z B.10
j#xV f~m-V.s e C.什么都没有?:G#WC#bB+C|
D.构造函数将报错f9DOG:}$I [$b
E.510:M)yrP,x~8JB\

^g]0U'D2GW
,Zg n+yn_ 14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code] v Aa+r4kM
<?php
Y1Is*};F9_:n3S#y v class fraction {4Q$Wz8W9_8yIFU ^Z.v(|
    var $numerator;+o*}Y8owW
    var $denominator;s0pH0~7\"Q!|p
    function fraction($n, $d) {
+cj5f:H`V:\{_         $this->set_numerator($n);
!]O%I ED         $this->set_denominator($d);(z-x!gPL
    }
^'L2dh)r9yp     function set_numerator($num) {,d(Q7NIT'[1y
        $this->numerator = (int)$num;~|!x'Wai.a3T[8F9I
    }9S:[R ~tN
    function set_denominator($num) {
1he)Pe'Y,\         $this->denominator = (int)$num;
'Z~/Uk4[nX5q     }
o3`R$q A-n _g     function to_string() {j/fuNWA5K:J-x1M
        return "{$this->numerator} / {$this->denominator}";
D*M5R7jA&N@a/Z     }
'iDnq-QK'I }
&b3P lMa(Le0~ function gcd($a, $b) {oT ] P*hg(@
    return ($b > 0) ? gcd($b, $a % $b) : $a;
W X%R?/yZ RJ1o }
TJ6v9Kj!O8aLR function reduce_fraction($fraction) {
9VqO.k^     $gcd = gcd($fraction->numerator,
-Z6g2h/H@D,}     $fraction->denominator);`j:DqwUl2X
    $fraction->numerator /= $gcd; gNwh L-{ @"hq.M~+Z
    $fraction->denominator /= $gcd;
S YP&CO#c2| }[Lz(~'K
$eight_tenths = new fraction(8,10);? ]1o,h@%o(S
/* Reduce the fraction */
0b!M&]{:b"V reduce_fraction($eight_tenths);7r7qD%A&O8|X/YP
var_dump($eight_tenths->to_string());U%lb VY1t,@;`
?>[/code]A.reduce_fraction函数必须返回一个值)U)~.[#G/Y zT
B.reduce_fraction函数必须接受一个整型值Ht0Jrem
C.gcd函数有问题
6g$T/FLG D.必须通过引用的方式传递$eight_tenths对象Y;i+Eb#_iX
E.对象的实例不能传递给方法以外的其他结构。w-Qfk@ ?.V

N:O?#C K.z zu,p7?og^_)}
15.以下代码是做什么的?[code] {(_2U+Mu;n7\X*Gq
<?php
:T2Cz N_R require_once("myclass.php");F6Q1`Ls
myclass::mymethod();9ID+kDY
?>[/code]A.静态调用mymethod方法H } Rj+N2ITG
B.生成myclass的实例并调用mymethod方法+w3K#Wgy|/TaD
C.产生一个语法错误Qz _3tU
D.默认myclass类最后被创建出的实例并调用mymethod()-LK3r@R
E.调用名为myclass::mymethod()的函数lhUo N+a5U3w
q8A*Q YR _Ad
m7vj J:Ihj+S
16.PHP中有静态类变量吗?
%a5I4k'J*dx,zg
9{uU:E5zT;C A.有+rr3Y!N5_,_L
B.没有
)F"ZB["MF `h "Q5r6c,rf)o3D
R#Ow;K4r)D7S.b i
17.以下脚本输出什么?[code] ^S6N.`-x8VB3`(j/k6Q
<?php(YZ+{qpH.o
class a
*u M]dB(jXch CE {^.X]_7YO
    function a ($x = 1)4y8\GK`0W\;j
    {
3[Q(}wf%eF         $this->myvar = $x;
\"Xh@S(u$Zj     }3D`#S5pN
}:n5p4E` u8i-[
class b extends a0Vx,E5|0~+A:i`
{
G$E,P cp     var $myvar;
y ~;Q)O)m6Kq xq     function b ($x = 2)+z:TqH:CE,`"u
    {#av$H&{L_ B1~#L@[
        $this->myvar = $x;? Wz ^N1z
        parent::a();
CXH$yf#H%D$[     }
GBEKN$sy }w!N"s&UR1^+c)C
$obj = new b;@(C_YuS
echo $obj->myvar;!Wq)]{-`d4b
?>[/code]A.19?'MQW2B VB r_ qK
B.2
!f4qGF.M%v KT(] C.一个错误,因为没有定义a::$myvar
(bi7XR&C s.t D.一个警告,因为没有定义a::$myvar5^)_{R \#G*m
E.什么都没有
.blJ4|Pb
.{!a5w H.^-I OG.D,v +x;M B"h#sLV`^ U}c
18.如何即时加载一个类?-PY8A7m r+J)xDI
fI B _{)F
A.使用__autoload魔术函数
+t`8[eS q[ B.把它们定义为forward类kG3b|~$~
C.实现一个特殊的错误处理手段3H0\%K(S2y
D.不可能J!p9?9p%Hqc8y
E.用有条件限制的include来包含它们,u%FnA uj
P H V7qz

4NcG|+A-n)A 19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
pymye Y mR
(o;` }M)T w-YA!a     答案:__________c zX6Tx$~ G
0YF0dT5wA

#dr0x5u&[:XC 20.以下脚本输出什么?[code]
/m0U _u"^QnrZ#Eu <?php
V9|5]t7i Bb hg5G class a
Gj\*fN(nk {
L`4{/_!x%f     function a();?(nOj;?$x
    {
Qn Wq#N1HT.f7o         echo 'Parent called';
x ^LY+bJR     }
@lPc5dE }eB,km$v*a:tj
class b8er9Hge'J
{ lQHZ t/x
    function b()
2e ov^5D%w {     {
u?4n+tk^^x     }u$W6iu&Zm)Dn$_,{(BJ
}
L T5N:X,WdZ $c = new b();
,e v1nwm9s6{}!|y4j ?>[/code]A.Parent called"rHCOnw,X Y&U?s
B.一个错误
.@z+\1TQBy,]q C.一个警告LVQ(q4d4|)Y
D.什么都没有V aR#sx

7Emu#DXf 4R,K:X*L&a
9S k#D{+V4prU{3t
答案速查
Sl:@s]io 1.类O `7uy,~Q
2.BCD
qLVf(P4]D7O 3.C
"LU6l ?Bc x 4.C
%x5iq oB2j%V i p5iE 5.A
E&_SD-x7I` 6.C{#B0~m,dpk\m
7.C
]hMDp#G,oN.RS 8.C
gY V$G G Z 9.D
[\1kk0l+K] 10.B%G4s [9M2w.Vt:DZ
11.D2E7A|D,]$aS!V-H
12.Bi ~@\s`+FR2|
13.A?1hp!aV ~'n
14.D"}Q'pW?_
15.A
y ^)f%I z kEVwl 16.B
Y$Q*q z4e 17.A
tq*ZGUb 18.DqTdu#r p
19.设计模式
?Y0pJ9|'c 20.D
Ta.\[ sY~ ^ Z%Ua%z-o{
(@{8S!L2SH/j6] m

N_kjJy2B#f 答案详解
5n [FW!c ]%l6s_)F/U;D$VT8h@6s
1.类是对象的蓝图(对象是类的实例)。
8g1^ k9PD c K:c-Eu v q(o"}bf
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。q4?g'F6@q`9O#]
k ^r.Gl'j$E!O0cy
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。 l3IC G'^#y-i&N
$o.B|g iE
4.单件模式可以限制一个类被实例化的次数。
9][&K t1_c
~)L9_k ik 5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。Ck+Cv#rby

p/|,eV-hw 6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。 A!E0D k u6g(_e
#a~s&~(X
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
\,[D_w r 1Ws:v.o#H
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
x!eQ pw 4U2F7Kn0M2c
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。^1{8m9N2h/D4}$UXQ;d

Eq7d5Wf\%b3@\ 10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。t(^x7w8N:L9m+N

&KG0]-rb 11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。[o"P c/L}!s
/a0fu-W4^7m?
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
\N.BUM qF R`5_)j*B yO0v
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。7d9`a,~T

5I4a.u |GSV 14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。9g/DcG5AI
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
9N7].V}N.q"C!Q'oZ     function reduce_fraction(&$fraction)
X,Xz^8w 答案是D。
6zH`N*F
7{O+m {P 15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
[5g/ZBK0fF
,gK3co{p$]pl F 16.没有。PHP4只允许声明静态函数变量,没有静态类变量。c D/t/PE},fV

f@ o%Z n#~-o/M BI 17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
&u.xX;t9n[A
/L+k fJx6P 18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。 H~+y,sy.eq

+Omk;w#@"x 19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。CV5b&l2r@

|$Zz[E/J 20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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