捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
t(k[_)bu PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
YL@go 本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
8Wl(~5eQH3P oA'_(Z s U{z+y
问题
XkUb"V X 4[&Dm,H9dwe6BK
1.对象的蓝图是什么?
%[J!ej[%oH{
"y,A$X+SB ["@u 答案:____________
my(x8e1Qii hC *Id)@n&r2Z:v/e

)\7Ul!?R nM 2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code]
#x4N jE C!d+?"Nf <?php
[Q%?Jfd class my_class
QKSi)_z)q)h#~ {
u JxG"^.r*y     var $my_value = array();
S"~_!@ti     function my_class ($value)1OQg T7Mi-mKE
    {x!t$T6`X
        $this->my_value[] = $value;8a&b4tne|&F p"T
    }8{$\(p&Qxv(Z6]
    function set_value ($value)
l)g7R1U@9\;U     {
g/dB8Q.[2s`%j/g l         $this->$my_value = $value;
!P_ n8p`-L     }
o9x+`K[2q;xug }
? PK?(w2w#Z,G$T $a = new my_class ('a'); A o(LX,i0I o]l
$a->my_value[] = 'b';
;M:[I/W-i;Y$~.t $a->set_value ('c');
{%g@*d(^,w $a->my_class('d');
l#}?J.O WWuV`I`:w ?>[/code]A.c
*Ugzr ^0Uh B.b
^$qn(~;?Y[1{ C.aTQO4@URpa
D.d2]jV?Y#s"Q
E.e_D s/N$?/c:Vl

X9D8q`,`(Q9E+l Qh| N9s;YZn
3.如何让类中的某些方法无法在类的外部被访问?N P2{3[FD |r _
7ycjgY xOT
A.把类声明为private
h@4@*h0~J!@ B.把方法声明为private
6d6H*K8vT!E9wY C.无法实现
6q-onFi%pB D.编写合适的重载方法(overloading method)&@Ia0w \1|t8t P

;K_[I p nb;h-XxI I +V?FT2kuNs$b
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
gy%d Br\ ,|hG%^-@-t$HC
A.MVC模式.t[-d XR2}3Le P*J
B.抽象工厂模式(Abstract factory)
9RK%O kKA u(CIS C.单件模式(Singleton)
t&N Tme D.代理模式(Proxy)"Q\P'pt v7C\`e3f
E.状态模式(State)
2M A#` hM {!Nk@l.DV!p
'SC/K2Rz wRI9i
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类? S,fE c)gw9|~L Vu;x]
8~-@s}8Qg
A.1个
6OBYfR1bC B.2个]%?Z!a1x(h {&lN U
C.取决于系统资源
d%\ y7P8x D.3个
!bX.Ay}N7O E.想要几个有几个
}!h{-en
,B+J1[-w.m'? g ^g9bJ}mE
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code]
8qfJd-~ g U8O(|%EL2T <?php
}(}$QJcC [ class my_class8E4~6j&S4coFz
{ f*eeLc#U*[I%^
    function my_funct ($my_param)+oB;dew0Y.HW&k9R j
    {
5B![6feCw1m+kbs         user_error ("Please define me", E_ERROR);
vh-^UWs     }
v;_c9C:C)ap4A8^     function b()Km$Ia8bi(A ~+X
    {v\M5|M-|i,@
        return 10;6D*Bw3Tl*|9L
    }
xH4aycV }oE1J|'nh5?"_ n9T
?>[/code]A.多重继承,l8E"]` h1D ]$UzL
B.接口!Y_%am,?4S'H R
C.抽象方法
;uL gg V ~m D.Private方法
h%F(Df9e _x E.函数重载(function overloading)7QpS%a5^+Q9U3[8[
)O G7lH Sr!mK
f-R2U"c.L6sG*g
7.假设定义了一个testclass类,它的构造函数的函数名是什么?GUm_(\I^%AJ

'Ox-_"S%e0f(m A.__constructY)^,k2j:IB0zprkuW
B.initializeY LM/_P&oo)n;m.W
C.testclasssCt5eq6DB
D.__testclassX6P$gjg:X!^5_7mS
E.只有PHP5才支持构造函数
3GI+R,xs5b5D-Z
%MReB4G6J&k9Y
Z6b@7}OF+X 8.一个类如何覆盖默认的序列化机制?ZD,v%j"\)V;gd:dD"g
d)T*E Ie` kX
A.使用__shutdown和__startup方法M!Z`IB4K~[
B.调用register_shutdown_function()函数
`u7x\6r C.使用__sleep()和__wakeup()方法4M A'z"gP*oR4U/O
D.无法覆盖默认序列化机制3k1IF3x` g$i|9uX
E.使用ob_start()将类放入输出缓冲中
`G#g|"q]'H+l%t ;U dS/m+m"P*X
k%E5Fq/]YH:f;X
9.以下哪些面向对象的概念无法在PHP4中实现?
"EH;x&^;LY2B E;|B
H,e+c ^9oH i)[C @抽象类
M!cU)~;U A @Final类
+V D}Iw1UjzO!UK @Public、private、protected(PPP)方法 @ zd)v!B?:?2p
@接口
v8E:O4f![5R'vMm+V _
pih]UG!zJ)A"G A.抽象类7GP/UTt
B.PPP方法;D/fQe&D`4x
C.PPP方法和接口
T:B&@+VP Pwo+v D.以上所有都不可用1I_)AV1L2X(r*X n
E.以上所有都可用JF)O4Y#|

)Iu!uZF z{
Q,wNu0h"Wb|b 10.如何在类的内部调用mymethod方法?
7s/ZFB.Jw iRpf7L1q` lQ$J
A.$self=>mymethod();
T{8S~#dsG O2x B.$this->mymethod();9u2~fr{.Ujs F*O
C.$current->mymethod();
eGCH+|`*L;oR5v5p/t D.$this::mymethod()
J,j6op)fKy3T:T5J? E.以上都不对;a-T7Y@;J

1t"w6|I&S0hV h2pz sD%W w `QXN
11.以下脚本输出什么?[code] *o6j*A FB*j e
<?phpQlI A,a5w;q p%O
class my_class+S2z.`^]-M!J
{
&w4v L4vxI"DM6Dcu     var $my_var;
"V2l4x?{:c     function _my_class ($value)
t]i/q4e*\*I     {kbovY:g-W_,H
        $this->my_var = $value;
DL;Q~b     }
9Vp2G6x/YJ'vN%E }
|Md` M1k $a = new my_class (10);
|5}Lx'R echo $a->my_var;
*FZ"Q7jml(w ?>[/code]A.10
,t*[\lO@*H B.NullQ$?I(ed[V_$\
C.Empty
+m?^Zre@ D.什么都没有,N~;T,H@'x4[
E.一个错误
*F9L},[1hmc
8|1zn)`,Zux!VN S
~"Ka\!`Ao ]vc 12.以下脚本输出什么?[code]
a^6z*C!N <?php
Z.S.u*yZ |@5?"` class my_class
oJ+H'P/a"T {
%y0[zO3Fh e/]*bs|L     var $value;5}_r1Gf dts!r
}
V@2a:v`'W(D $a = new my_class;~[6q0J@*u*vil u
$a->my_value = 5;!UH:n4B(q]
$b = $a;m^i#U:oz1mg
$b->my_value = 10;0s er6pH4G_
echo $a->my_value;,b"E9Dj"}M|C
?>[/code]A.10:Mn&_$Bj3N7f+GW
B.5
O-Ww+y%nK^ C.2![o!c8|\ V/\
D.Null
8LG"K H-[R$?$lU&Fa E.什么都没有
W_gL{C%f P#g m(N:pyv&@W
9RE iJ1Ct%u"r;a
13.以下脚本输出什么?[code]
&}-kO{ H!u+GP <?php$A8f*F v"G+Z)vk
$global_obj = null;}K{5w5f/}
class my_class
2V vf@!_7k {
[ r#D/u P8p     var $value;
AS^1R!H/B"w0VG     function my_class()
(su/v*l;Y6m+`^s ?     {
Bo8X*?Fg~         global $global_obj;-n5Qq&jp,jt)RR
        $global_obj = &$this;
j$T:ZzE0h     }
yI$Xg-C:a{-F@Yj }9n:eK#i%\d G
$a = new my_class;GpwJz"I
$a->my_value = 5;7l HTj1{-R9lg-K1U P
$global_obj->my_value = 10;:b CE_pa"q_
echo $a->my_value; o^ y6j"s9j hy
?>[/code]A.57z?-ch`Q U7PI;C&rE
B.10
Of0d,s:xn q C.什么都没有^.jSAP)X{
D.构造函数将报错
/vZ"@_pu$yn E.510
{)m1uAS\
x7r!K` { /txREzCsABJ
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code]
%y6iFt @r7rxB <?php
1QZ*?~vBA3y"E class fraction {uIx*n[,G1H2r5Z
    var $numerator;
[ID/`'SmOy]p     var $denominator;
&{o o6IwZQX0U     function fraction($n, $d) {
a7w^5_ ?d         $this->set_numerator($n);
W4U S GH o2P[         $this->set_denominator($d);!D#g-OZ|[2q
    }
mMR&io#L     function set_numerator($num) {aL^[;|dT9v,}
        $this->numerator = (int)$num;
8NERS7Iv~r(I;?4u     }
+ZS"S G {Ytm     function set_denominator($num) {Lw \/o,J
        $this->denominator = (int)$num;
7a/]d$i#r[ o     }
A&`7Pw{^,E|     function to_string() {a%U0gN}|B5q T2O
        return "{$this->numerator} / {$this->denominator}";W!sc!|"^cCv
    } c~!m9xrj
}%J8zESRh \"edX'Gcn
function gcd($a, $b) {
b+j1IHi4|b     return ($b > 0) ? gcd($b, $a % $b) : $a;
_U,dtuz;g#kG(fC }#A$F\ \C8ePm(d6?s
function reduce_fraction($fraction) {$g"NTd^ SN;{2~^
    $gcd = gcd($fraction->numerator, LVw&\W/F{i2}
    $fraction->denominator);^tGX9o`7G6j;W
    $fraction->numerator /= $gcd;6M9FR3A/lY4ZIYzpY
    $fraction->denominator /= $gcd;
7C,J:}WVH}-s%R }l V"u v7` F7i[
$eight_tenths = new fraction(8,10);8a,jsA5|E)}P
/* Reduce the fraction */(`{p8_.z-z8X
reduce_fraction($eight_tenths);j4U8m}e bt Vy^%{
var_dump($eight_tenths->to_string());
M)UjZ5F9`*v"]v ?>[/code]A.reduce_fraction函数必须返回一个值
]+q+]*E}X B.reduce_fraction函数必须接受一个整型值4@%t7bE,g b-Te/z
C.gcd函数有问题
d5u+N"fya+ah!j D.必须通过引用的方式传递$eight_tenths对象2K$pV ~J7^$j^U S
E.对象的实例不能传递给方法以外的其他结构。
`$WYY.q%Y
F.zwZ{l9W
h4N%]*_e;X 15.以下代码是做什么的?[code]
$[ K)w_V^8}CtV <?php
7Cl`R#J Y require_once("myclass.php");6q#gcK9Zyno8Ad:J y
myclass::mymethod();
[-`U'v.ta8_ ?>[/code]A.静态调用mymethod方法zKC#W-w
B.生成myclass的实例并调用mymethod方法ZL8ie8P
C.产生一个语法错误L*XOF8\2M6j
D.默认myclass类最后被创建出的实例并调用mymethod()%] EcK?8OJ
E.调用名为myclass::mymethod()的函数_1u5WQ1@fU1h
_YX&J-?]

9y8f$w\.b9vV q(C 16.PHP中有静态类变量吗?GSO KF6jTgu
1B/V'WZ kT
A.有
w5R T+P,eH!XNo!\ B.没有"G'Zu(L,A
f-d5tO}

B$jX!bk&k h1l d 17.以下脚本输出什么?[code]
W~-xZ8y7et.w-S <?php
3|-[)ixY%M@ class a!K3zP^f@ |
{
3`y"[;i ZO6L,|     function a ($x = 1)aX$oS,X\^V
    {
b9f[6mY         $this->myvar = $x;
0m|u:`_%Q     }
v:]N2VS W;l8_ }ceqH|)yV@
class b extends a G%{+ZK8h2l*R R mK~
{dx8i9C t&H#[4B_
    var $myvar;(i6H0a V:Ko
    function b ($x = 2)
l#uZf7?K:ra@jn     {
7PX'Z }(u%wFK         $this->myvar = $x;Q:eJZS*XL]~
        parent::a();
xof9zh0zx     }F4ss8F*bbC(ogF L
}
:vx8[,k%k;P $obj = new b;
;tL#V pSz h6c echo $obj->myvar;$H3l |1C"Y p~ jU
?>[/code]A.1 |[5Wv]Q Q&cY
B.2
x6w&@ I%nknu6j3J C.一个错误,因为没有定义a::$myvar
0R ueK)s D.一个警告,因为没有定义a::$myvar
P+sg4sB3i_ E.什么都没有
s^4o4H;gH
7b/s*mY[tO
r.yM3T!g$t 18.如何即时加载一个类?
Zvl l'Q+r
e_!r:w9Hdo A.使用__autoload魔术函数xpzI5V-z2U+`,O
B.把它们定义为forward类O*o{:Gt
C.实现一个特殊的错误处理手段
3Mfq \ k[ D.不可能
$XX msH@ E.用有条件限制的include来包含它们9l/oA(C~L$i
-v*TZ`8R#w,r

~3A~K&H6{}h 19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
)Elu;TiN^D/q 'A!v Z_l#l
    答案:__________
^!upG U!r gK
.} xG7U ?%G /J1s-\4}bs
20.以下脚本输出什么?[code]
5QA S@/fJ]!DI <?php
g3R,UHoKB class a
Z x*X:q3Jh+r6f {
6c3qL+^;p!Rl     function a()Q2R7@ j@(s*cM5?}5[ N#r
    {
x9? e hf}j I@         echo 'Parent called';N({UD w].F3^[
    }5V/OhEc(~6O4\+im
}kw{(p+L(}8Aa X9M
class b
r8n&k%x5_&Sr h {QKJsC}:v4I#`
    function b()lK9orT.b
    {
&~ E(y-S:b1B ?_ _     }Xl+nj _s
}
Z1RE[,F/U $c = new b();
-g1de-kulHE-F ?>[/code]A.Parent called
qsC(C$I wF.@"Y @ B.一个错误#v^e/{] {2LP
C.一个警告
x5[? K1K3t]J K D.什么都没有
:P ^M-z:~E'mS \AQv9L)ayy
2mh c g"?s
(J4bf5hA1?V
答案速查B+O`?k/q"q
1.类
X${@ z U+m @ 2.BCD
X/xCBA'k,O 3.C
_(D1wQd yYRE 4.C&IX(oX$[ M
5.A#N|%?4Txh
6.C
!vJhP T,L;xe7F 7.C
"^@V_&C;co'X 8.C[$mj"bB
9.D
I7DIW.`]$se 10.B
)@.e7t3E.xWd 11.DK4s6}%a ?K
12.B
,[%^ L%F5[ Q 13.A1`6x'e-V/z3@
14.Df(K&})@qIX_HN
15.A
3Ci&x8jQz 16.B
7}T)gcP5Y 17.A;`)QZ&p$S.`_
18.D W Qu4_]7G
19.设计模式
)t;u j k?Ct? j1@ 20.D g8Vb-AR4R3N6yl.{
2i"_ uAj9Dz5j3X
NY8M2y r

*g,P^o+Qm!R 答案详解-Jn$EFnJphLJ

6x%iKO c,?x*Lr;E 1.类是对象的蓝图(对象是类的实例)。j2~y h ^!Q3F3j-GM1}
)x8M;M]RL1AjzP8X
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
];sKC%E[o&e%n ^6gPe,T
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。$uMo"mv:xYB
](Sx/D!~b0^[
4.单件模式可以限制一个类被实例化的次数。4X f@4}!^2@cfl

Ju*G})V7uN0`%] 5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。#y1{[V w5z4y
|F4X e5Z*b-U
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。%B D;tIk(N
H"b:tFn O J;PnU
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
+j8y#H4yn%z&i2u
3|r!l;B+[4k!uY 8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。3I;x:xd+}DKmq
8Qn6RAcgI
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
8Pvp d ~6WK
1EP,Z,y9S jF_ 10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。|\%J0f?'X CXAS
Qfu*~@+h7~e0VX
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
|m4Qo"UT2FF P B 4vBTc8[3]R
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
n yN"JqZ
1t P(t^plNq 13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。GBR)X:?#_0~h
fm9o8z!kef _9PK
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。8d5?Q1P,H9h
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
_c [b` c     function reduce_fraction(&$fraction)%|*s[aV5}5}Y
答案是D。%\Q!w&AC|
!S3^+\"zLn4kC L
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
%J*ZI&oKT;V1c H'X*k'Po1HN
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
/}Gm-K1[n
W7CL9VEg4_ 17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。~"wGe0}4}&hT
:g0}jC UoGu;d
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。k9p\3YVv^0^{-s

|~$`N!}1[h/[*v 19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。N.wjgf+A|
:d3Fzc"k S%G
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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