捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
O9Q@\/d'Bv PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。NKc3PXV_/i
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
7|2Sv3?6Y\6})d H:oi2y x o Z7bkz W^
问题3N(CCkx%X ~_#S
0[;ZcU2Z&b
1.对象的蓝图是什么?;J E7R uBh0J\*I
d7T[1M+z
答案:____________0Pz+k w(E p
a2A]&NX0@;q
/t{z|2voE
2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code] ow o(^Q
<?php
3d ]Y ui*F class my_class
4a'u}6a+| P@ { Z)l4Z0xpG\ t
    var $my_value = array();1K|5VSu.QJ R3g
    function my_class ($value)
E1G+a(?H)l n     {
k1~)K#V%z%L(@9H6h3I @M         $this->my_value[] = $value;S"aCpyuy9I)cI L
    }
&}6a%bk)u AU     function set_value ($value)
Z'n JO*{     {:m.V3d \5gkR
        $this->$my_value = $value;
%d9t nax4A-h:RW     }J;[`!c2a7B*JHU
}
7s/Xgs(e $a = new my_class ('a');B/E qwM
$a->my_value[] = 'b';HDo~6G"am Y
$a->set_value ('c');
EdsV i c $a->my_class('d');W;Pt!sq`6pi
?>[/code]A.c
$B Q)SG)Z;AQx B.brx(i{1ljF7K
C.a
c*hM8HO x D.d
YJ~(uYKP E.e
.Jk)G4Ok(G-C
,p3\0Ue M v+R
P)o za;XKb I K 3.如何让类中的某些方法无法在类的外部被访问?$B_Q `,o };s#KJ_._`:^

xP9N#V@Wp!BU*] A.把类声明为private LpEw\L#{*N
B.把方法声明为private'o!r\?|1M
C.无法实现
VG1b1xZ/eJ D.编写合适的重载方法(overloading method)|6L v-kf
.d~#VB$ej
dEws kC_
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
%|4o$k ?Aji
M O+RD ll!kOtY A.MVC模式o?+B rC!a^/X
B.抽象工厂模式(Abstract factory)
B(yPAP;s$~ C.单件模式(Singleton)ziXI1x1t#Az
D.代理模式(Proxy)
WOa-O7{ ?t E.状态模式(State) F.|ll;Y-\&~j
5D;g"od4Z x%O2D
`3h H?Sl)z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
#@\6?W+Q K,^ [(PQ W7|h
A.1个
;r*o.S [ ~ f%PuB%c B.2个!U}2m#C,x2cah.f
C.取决于系统资源
%ED m0x8^'aLt1lrA D.3个)Ub.`2E5W[
E.想要几个有几个w`,?qX o l Y
.B9QN8P+\;H-| ua
5gqzn A k
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code]
MuAJ r%t I$n <?phpR GK H1{oR$nx
class my_class
1Kz(o"PM/J {P5|2Q9]~G;n
    function my_funct ($my_param);?fNc0w
    {
;LXl+GZk)Y         user_error ("Please define me", E_ERROR);
GSe2sb[6]     }Z(iWU}*Ycd1Z6Z(X
    function b()
.t`/LPNR.Z     {^P$V~q tK R']
        return 10;2gn4T_6H)u,k
    }N9~ K+Z%} wF fYT
}
lT0eY"u ?>[/code]A.多重继承
za"zBDg B.接口
2JJBW6L&_^3u/C C.抽象方法
7^u3mb a\M\ D.Private方法 n(Ul3g}7c/a%t
E.函数重载(function overloading)z*]G/C&lZX

*E(dgj+PY3V f c@JvN
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
:S"k(H`?V8x:yt
LL WR"uA A.__constructglrc0QF? t5Q,b
B.initialize
l`C}l4RvO g C.testclasst-B&S%Bh3_Nal
D.__testclass pKY ^9Ei&`
E.只有PHP5才支持构造函数k@5L3z}k5p
{j._K X3{,{:A'e!K

#Th'[/m\+~(h&n 8.一个类如何覆盖默认的序列化机制?n(B#_\Q,mZ;~
Y;sk_I u"G B.WD
A.使用__shutdown和__startup方法.V^9|r-ZrF%d1^
B.调用register_shutdown_function()函数/DQ`b%yv
C.使用__sleep()和__wakeup()方法
(^'}5eM+ms y D.无法覆盖默认序列化机制AN`sa5Gu9n
E.使用ob_start()将类放入输出缓冲中
$c*k^s^#X1o
$z ^n6n/sby1a w#l OJP]-w R
9.以下哪些面向对象的概念无法在PHP4中实现?
i'mL/b#vh2f ? MuDCV!MK`(wh
@抽象类#s S7Z2A6fcf;D)kU
@Final类
gML%s0}1N S s @Public、private、protected(PPP)方法
-R/O7h~G\ lU^hX @接口
_ Dz|\/z O
5@$Ly6C"N)A A.抽象类z^ru X"aV g7x$U
B.PPP方法
6p*@!@WR*Y@E C.PPP方法和接口
#D&@$Oh'H D.以上所有都不可用
C$~(P#j"X{Z E.以上所有都可用(r ?6K^?/N p&~M8o

[$gF/Q U2L kIVQ 9{o ap;e
10.如何在类的内部调用mymethod方法?
TYv4Fd&\ i8dR H'h8Y
A.$self=>mymethod();
#J!G5W-o&Uh@9|5k B.$this->mymethod();
+]2MRoIgC6Z C.$current->mymethod();:kJ.Z#xP6\ t
D.$this::mymethod()
U M;Y3Q GS{'ob%a E.以上都不对!U`i^,X
ct{3b qTMl*Cl

c[#g,r"ir0q7o8a-V)I K 11.以下脚本输出什么?[code]
d{%aL/t <?php
8Q$s \!L:S4r8X class my_class
zH5ZGW3l;i:s$[ {/o)P8]$jp
    var $my_var;2|Jv D!C$gS
    function _my_class ($value)"]8@8m Qe/?(e
    {
h3cM(ZM         $this->my_var = $value;C/t!k%R*{;[
    }
'o:EY iw%H/Z*v }
LU Qj0` fn} $a = new my_class (10);
_7`Ome%n echo $a->my_var;
W*v1Z%_#g'{@ ?>[/code]A.10
i'jH\Y B.Null ~5q7N ~A)R9B3f PS
C.Empty zeE \3GO5C0{'R
D.什么都没有b$Yr9A*z EK ]f*[
E.一个错误;vi+gz5|;Y
0wASAcn [x

&j GHeuQ'A1fV 12.以下脚本输出什么?[code]
R S!N GJ _ <?php
"l.Fb-M$s class my_class
xr[ cV$|r-P)P {
p^x5C.n1H8d%vpA/i     var $value;X"Jf,Z}G1]i
}
~-zW{\h}]S $a = new my_class;5tH"eR8Y0@
$a->my_value = 5;yy:M6vm EEL
$b = $a;/GWE!ZdNA6u*`
$b->my_value = 10;
-Ro:jEs:Q)t echo $a->my_value;
V5\;AN:guv0Rf ?>[/code]A.10
v9\.Sz1wI%a(t B.5
Z1} Kh~AfU$` C.2c2P*D9D_#@n(V
D.Null y,? S NWcp
E.什么都没有r9R'r4\l{
7QD yb*O*y\B/H)O;[#P
? s8PP\&LE$I
13.以下脚本输出什么?[code]
#|x3Q!Y2{5^J}} l <?php
f,EC wO P`2N $global_obj = null;
wOO K DBiJW class my_class[iI+YLT ?
{,zf1kmZ;Tt"u
    var $value;
5W/n(hY2F-b9s     function my_class()
0_'\:D,y"By)wW     {
8}7Y9v j \G         global $global_obj;Va;lb qz
        $global_obj = &$this;e)a4k;aO'rH!E
    }%Kiew"QO Q2J(X
}9J6kVA"D
$a = new my_class;
f3Em5PR N $a->my_value = 5;
q%|f$\Q.B.}N $global_obj->my_value = 10;P-hA\L^
echo $a->my_value;
9xbBSB9R1N)v ?>[/code]A.5
7w!U|6| t ^ B.10u3_Td?C8G
C.什么都没有
qk%|RE"[ D.构造函数将报错IU"d"p3^'KA
E.510 [n A;{ztO
r;@ n9jjlN({ WQ.l9L0e

;YY1E+Sly W 14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code] Z*D-a9{$GM.@
<?phpu | T D:Mgv
class fraction {nup}l;dz(r-e6k
    var $numerator;
:E G*Vae~+x     var $denominator;!j.`p3Y8d
    function fraction($n, $d) {
#wOT&M-[         $this->set_numerator($n);,r p[ R6bey,h2Zl
        $this->set_denominator($d);;evlp"d3N.Y
    }NMa E(B~^I+C~
    function set_numerator($num) {ohGD'XP D
        $this->numerator = (int)$num;&l/_2f h!Axn
    }
.c2d6qc^     function set_denominator($num) {~OD1l*i
        $this->denominator = (int)$num;
qy,j"~:M Al }     }
Qh5P1klJ0^d     function to_string() {8@l4n VN*|
        return "{$this->numerator} / {$this->denominator}";Kk}"@\
    }(y x/|3jLz
}
$TX$D"V6X!R)wc|+y function gcd($a, $b) {
J%?-|F2y4] v2Q(eO     return ($b > 0) ? gcd($b, $a % $b) : $a;
b&]5R(T6W }Moo}2yRT
function reduce_fraction($fraction) {p z:WD5Wx2U)j:Q
    $gcd = gcd($fraction->numerator,_~@ c @S]S
    $fraction->denominator);D%BiH;X5z;ja
    $fraction->numerator /= $gcd;
&U.X\M S/nS$Z     $fraction->denominator /= $gcd;RcQ2D ?oX8yX
}0L W0n6@Z \ p
$eight_tenths = new fraction(8,10);:E.uP^.bov
/* Reduce the fraction */
!~]!W?e2K!X reduce_fraction($eight_tenths);#\'R/o!}?g
var_dump($eight_tenths->to_string());
8\N)egP,z8? ?8r#d ?>[/code]A.reduce_fraction函数必须返回一个值 U*u:ZLQ2vf"ia"v
B.reduce_fraction函数必须接受一个整型值X o4O`(]3G_&Ya
C.gcd函数有问题
zZ/~ U r g? D.必须通过引用的方式传递$eight_tenths对象pot_i0?Y
E.对象的实例不能传递给方法以外的其他结构。'X4Lu.D|o{

} tX/K H$j8Kj 'yA H K B/z)?K
15.以下代码是做什么的?[code]
m(?;eh Q@ j <?php*@.^rf E"h%Tx1nW7iN
require_once("myclass.php");
,~,|rrAu!{ myclass::mymethod();8R\'Z+d7M+R
?>[/code]A.静态调用mymethod方法
qRSGBM p_ B.生成myclass的实例并调用mymethod方法
V9x j`g1swK C.产生一个语法错误
EI_.~G!d D.默认myclass类最后被创建出的实例并调用mymethod()
RO%[j;t)b-S E.调用名为myclass::mymethod()的函数;dI$U4Cr5|
2p9h4Q-NG%wh` LB
/Y6Y8JAA_
16.PHP中有静态类变量吗?
7j tqn r
M&W,x^hG+S A.有
/G0y?I'j] k jvX B.没有
&g;J"Fb3CIP._P #h7U][s0SNQ+u;Z0OmU

{z$XK Swu7[ q'U 17.以下脚本输出什么?[code]
P*t'VMz!mc'Xvr8v h <?phpR:ls8DYx9o"V
class a9^#e8?#mw^l
{NWJ_"D(C!L'V#k
    function a ($x = 1)NcP)]9^j_0F
    {
5A{SY&ij5ua-E         $this->myvar = $x;1r\7V]Z.a2`
    }
J!d3r0o$F'H }5`*b [1z2E#qo
class b extends a0A!hh-|`sR~E
{
/hU/jj` Rb/b&l     var $myvar;
l%b$[@8d%p"Fg     function b ($x = 2)
&d3k-M~"E2y cD(g)R     {:S.m$GNz!|S9p/^*e
        $this->myvar = $x;}-P1j5Q%Es3K0az?
        parent::a();
x2i-PEE@'OP     }-zW:AAz(c}d k
}
&b(]Fk @;g $obj = new b;
1s:@[5RM/D.v echo $obj->myvar;;]"?2G1s7h Ei8{4U(V
?>[/code]A.1F3X)d~1BzU!\
B.24mE;FC_EAhux
C.一个错误,因为没有定义a::$myvar w3| { V f2bO
D.一个警告,因为没有定义a::$myvar
J$o3h.C,JQ{ E.什么都没有Y3VjR$D#G

,mk1Q$LO
7h,P9v$fERs Z 18.如何即时加载一个类?
i|dHxY;_S
R f4[4_pe A.使用__autoload魔术函数 z.x+?vXO Cme0{e
B.把它们定义为forward类-x0pp9O}:`O%p4T
C.实现一个特殊的错误处理手段
?S ux@CNX9` D.不可能6M1Mw}Z1}P ^P
E.用有条件限制的include来包含它们
GIrN(K3z U!CW2N }m#QD%O3J
.?N$B |!Pg"CD
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案? Yo M7N:ql6dQ

W-n]Pb^(h)P     答案:__________
"\$S:a J6bfY`I Mg|8B ?AG"^K&h x

&]],kZ:w0u?8H;r&t/|*M 20.以下脚本输出什么?[code] v\.Hf m@(R
<?php.R:Ham?@5x
class aS#B%S!|V6~7E tu\
{T6_'o!Y1j3C!v
    function a()J3?)Oh:R0k4} x
    {
6D~5Sbo5mJ         echo 'Parent called';
.]"n@[D'Ygj"[9u     }2P1H#v)rYC
}
{] `%ZN)IT class bK(e4@8co[8a'iR
{
n})f} X     function b()O(i-ljK
    {
agM0dF'fl c6M     }%W5g g:S9@3KM.rM(n
} J*Ds2_vfP%{
$c = new b();FZ)qu|d J:z
?>[/code]A.Parent called
.T*])Zf zk4P&y5LH B.一个错误*N|8p3uk&^
C.一个警告C [y`/\:t&N
D.什么都没有
:sX:`2}[Ac]
.?$a/v"l.M$].j
@O?nO7A%r ^Q!_mJ/Be
答案速查"dL6et9y
1.类#b ]'BD]{
2.BCD
9W&f.J&A"i 3.C.z(TP9} Y] T"C
4.C
B@xIg$|9V 5.A8it,o?4W
6.C
HvOq5o 7.CA pA?K[3I
8.Ci4A R}'maf"Q
9.D
[W7@ Wv?r 10.B
D0a@l)l t+T 11.D
N ]{P)? O 12.Bn s,M]"C-wW]@(X
13.A
:D3P(NxK+] 14.D
`A'H-w)z0~.\(o,O 15.A-d$QM0h;g
16.B
7rS_}3{ 17.At2~ UQ&WyU;[
18.D
s S%aEC+M8\(i;W 19.设计模式zkY`'x;?{;LL6Y
20.D1`+s;L]h1N$fGV
} w LdB%~o

N0e`m/|;C#c4XK o%e ;`d,[:p?G.p&g
答案详解$OI,d3P?A7]
d@$F(Pq#ID `
1.类是对象的蓝图(对象是类的实例)。k~:bL"wFp }a:H

GoDS)y }7@|%S 2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
#^l/L(t$C;^;}h'[9dV :m_g0N;EL
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。U1Pr*{g M~
*TZ$Q9K8I2n,J
4.单件模式可以限制一个类被实例化的次数。aZP"r&hJ b w]&X
U5E SCo1y6N2[
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
J?!A4[+L%Z,vF3I7o] h$\]5y d8V_d
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
3Mw-Y\[dh B~&W
cR2?(PYn 7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。!q&cy X9un+D,D

hO$\/AHi%I\ 8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。f1e:e&S u g1n^!\ C
zv5| a*k9^+}d[aM
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。[7NlP9w

"{BZ2EI 10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
^7G3?,x CMQ
0lr\rL*mzp&t)NQ 11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。-FPV Zl u1c h y

~2U T:jy!w)@3F 12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。S;_1k_cv-zQ
*H Ajn6F{
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
7~]&~I#pb;v7e
M%q*K%oYYR 14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
+MA@ ?$?ui)^ 回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
-Y#Y xi1hS-M4|     function reduce_fraction(&$fraction)2VB%gt1R
答案是D。~;l&ns7d
~^x(z,[o*aV }
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
!R7SC&Q2G2Y BD z,n*A$Y H]N
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
8n6gw9Ot
uJu3e6q 17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
m8siU.h*j g`Kw!O)w:Kh0F'c
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。H)L!l J x)WC4La
r N7q { {yn
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。2H U'^{je P
9aqvmi1oS(}%y j;Q!fT
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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