捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。h i,m%J*Q
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。}[q)Ri6ku
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
&]9u X.CCe"Q
/G-vB"Z_!}S,o Z7E 问题4HJQ/r*`
ei3Qt3A@'Ec
1.对象的蓝图是什么?
u%h#puB^J(P)iQ+E
e)eZ,g7v)UC[V 答案:____________,p Em4Ipl:@'Ck

#b.QO.y/x'@ d
`(k"m'IwO'L 2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code]
&cuo2K:\9z <?php
9]*h)W#al3H class my_classI8Qc&~9xq
{
3T;|l9XIg!`9G6J'`BN     var $my_value = array();)Cx'cD zM
    function my_class ($value)#mpx{6f ^8~ n
    {
;T(w#NoD         $this->my_value[] = $value;
A%d [.}'e)h     }
F/~)cwk     function set_value ($value)
IW(P`5e Hy%S     {ub _*Of1P
        $this->$my_value = $value;
n.Y7k-ua*?SE e Y'tB     }c/K:ky'B v+ge
}"noxEp
$a = new my_class ('a');8H-d"r"Pvbv.W
$a->my_value[] = 'b';Mjx"['NV;aY+Xa&p
$a->set_value ('c');{)v:KecL
$a->my_class('d');n0N|}6OOe)c _l;n
?>[/code]A.c
N B x#U*NSmO!J B.b
l$BuO/j[;g C.a
R,ol8@0j.f` D.dF IV.U3g F
E.eo zQ\q+{0m

5Hlqp#aEW
U(gm"O gM1B8y 3.如何让类中的某些方法无法在类的外部被访问?
fx ox@2d)r!a ?
"`*SG]zRyx A.把类声明为private
3mz e#MN}4N;^3{ B.把方法声明为privateg2g xaU&G
C.无法实现
.L3ce-uS'O&W(v D.编写合适的重载方法(overloading method)
ek*nH$W3d{
:SU2w r0tf RAF!u,UX
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
\SwZ-oE 7]F(@D9YT'f
A.MVC模式)t7X(yr'|^
B.抽象工厂模式(Abstract factory)#B u8YH+U$I,O!O Q
C.单件模式(Singleton)
xPjPG D.代理模式(Proxy)a&kq Q ou
E.状态模式(State)
5{Z9Z C&i+[5K JA6B
5|uvJd a.p6M"EZ d&[M3F!go]
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?:@8Gx'wB_Z
1E@4[)Of(ZB5v(x
A.1个z/hPLtS
B.2个
`;y7A0|"A,O&tOb C.取决于系统资源4SR#?s:UUN:y
D.3个
]z JV#OvOid E.想要几个有几个D9U} m~:Z,pE
#O)q#vs&CF)uS Y@L

#s HsD/K0b7f,?i 6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code] Q*r/j'E t KO
<?php
aUA Dk*p2s g$R W class my_class
0EfdU*P1j F5gD3z {N!q K F/e(]0F"Q
    function my_funct ($my_param)
0r;{,Uj?"np     {
^,Ai x!R7p:xr         user_error ("Please define me", E_ERROR);
Q;j3? uT5q     };hA!d1AoC-L5P
    function b()rC C@X?d.J+s
    {)wp+k[qR;{
        return 10;@ B i-iYDr|U
    }
*K,UM;}S"v'S }?6n;c"_6LJ
?>[/code]A.多重继承
#`V*[4j6ax,r]6N4f B.接口P8md_XN e:p;y/}G;D
C.抽象方法
`sr&y?\]z M D.Private方法Mi^^5_3M(g.\
E.函数重载(function overloading)z5D*p"H(O'w,ow
3R)NER|@1U5C u4c
zI2ffE#M2p"v
7.假设定义了一个testclass类,它的构造函数的函数名是什么?QV"_+@7X*|7z~F$CS
2Yj8[ ]A&dsU1a
A.__construct
?'z!?bCu5x:S3K B.initializeFq O5N{ L
C.testclass6he ICw"n~7X
D.__testclassM ebXW
E.只有PHP5才支持构造函数
0c z2^B.O-OK U5jR(ymg?

;GMJ/a*D+~R o 8.一个类如何覆盖默认的序列化机制?
5f E+U1c2YGo 2Q`{@|9d
A.使用__shutdown和__startup方法g ~_v,E!HX%i
B.调用register_shutdown_function()函数? |{'Kv;M
C.使用__sleep()和__wakeup()方法i%E,h&F g/G`
D.无法覆盖默认序列化机制?qY8k2Cb
E.使用ob_start()将类放入输出缓冲中
I CjQ1R"G
9I7iM1Z,H0y!co1i6Q @({^eT9eJb
9.以下哪些面向对象的概念无法在PHP4中实现?
L9t(L} q} 2Cff/@:j C,O's|F
@抽象类
MWH+Z"`t3^rF1zD @Final类
z?x0iw y!EFA @Public、private、protected(PPP)方法u1@/azi
@接口"U#U9Ek A Hv
!{Dqpw
A.抽象类c,f:~)qV2h&z&n[E
B.PPP方法W4T2I.[!t#a)]
C.PPP方法和接口
2n$t#o?W0p8S2S P:Z'[i D.以上所有都不可用kF0j Hn?2ox2u7a
E.以上所有都可用
({4CD Ua-V
5a vW L(\ v
,KoJ!bWb'|QW 10.如何在类的内部调用mymethod方法?
:Pt'Y%VO"fa0V
d T3?LP e"n)Pf A.$self=>mymethod();'tLp2elL[
B.$this->mymethod();
T s0M)nkX;@R` C.$current->mymethod();(t,ZC"cQI(l-v
D.$this::mymethod()
?+\f!Jj&y E.以上都不对
.^tZC*A+gp "E srYL+h,un i L

b1q3f9k ^,x5~4U,NY 11.以下脚本输出什么?[code]
2T V.?,Zjl0wz <?php
O&y#r5Z0sF class my_class
p:g"G T2O {
Q-r bb;[d h     var $my_var;
nE:Tg:B\ g     function _my_class ($value)N{ k5LC.Z3p6G:e8W}*E
    {
vi8uqFt5^         $this->my_var = $value; z0G d0kX m(CM
    }q dV|[`USJM2P j
}
*yg%tFkP)w?#HR $a = new my_class (10);)S*h+S/p,n1_on-f
echo $a->my_var;
'K r:l-pGy-j ?>[/code]A.10%J1GKPV
B.Null*Mlv1k'g-U1?4xE
C.Empty4Im!O:i0[| Gyx
D.什么都没有-Zq Z)aa]`
E.一个错误V@$\&e:bV^6a
YP1lNlnG
%Tc `$q,]
12.以下脚本输出什么?[code]
"N&m#X+H6dGG <?php,{9Ngu4@K#Gk{
class my_class
x+d:wK/D"ox.` CF {Tv*wW}*\0r
    var $value;
#EIdgZ'fD }
S%{\JcF8zX-Lc $a = new my_class;J-[#iR d l
$a->my_value = 5;
4C'[8G~HEOX6A O $b = $a;
e?7h [k)y $b->my_value = 10;b4ZXK/j&e:^BK
echo $a->my_value;
X"beB \-{ H8q#G'S} ?>[/code]A.10MFZRi?,D,A+N
B.5-Nzv2i/Z7@Ph R
C.2.|t9D+x SFd c
D.Null
? Q/Ss;N4\ ^Ab0Mg Z E.什么都没有'q/~`vz`
3hf.A$H_

O(O4SYuY 13.以下脚本输出什么?[code] V:Y1WtR~j
<?php
e)K"bts8nK.^ $global_obj = null;
-? @:{&|f;d3p:y class my_class
3it0C)t-w4A)Px,xG8D {-k"Eu?S)G/N6ts!y
    var $value;
{ Fo(bT;~3iA     function my_class() D/@z"eIOa9m*J u _
    {
o0Q aulbz         global $global_obj;
1rA)`z }zT         $global_obj = &$this;R6c{uKn{ oU h
    }e+{%M&v\)J
}
w:A9~,?'a\rO $a = new my_class;
:`i(b!E? @!SDs $a->my_value = 5;
N(? s%bIj {Q q(J $global_obj->my_value = 10;
Efz~? echo $a->my_value;
gx+R;doc'dJ ?>[/code]A.5!TZ4k1{V nbp
B.10XV)y;i:o p
C.什么都没有%eHo1e5z pKs
D.构造函数将报错9lE/};YO[x
E.510
B!xWqy }(|S~c9]
Q.\"`#K JT\ W0Y;DEIbZ'L1W3c:y
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code]
b2?/Kq} ^\ <?php5[m8o P1W%]d
class fraction {
T)Z/S'oV7Z     var $numerator;
%\z;Q8lO2ky%K     var $denominator;Dk&a7\2a nB@-x3psU
    function fraction($n, $d) { y FR6r'W~8X K8b t5r*W
        $this->set_numerator($n);
-a,b@,\L         $this->set_denominator($d);:L_!m6O'HG-i
    }
abcw ff     function set_numerator($num) {$^6N7u:n5F/xED
        $this->numerator = (int)$num;3[Z"yn$sA
    }tukm#Y,r*H4g
    function set_denominator($num) {e'vS J4_~)LKH$?
        $this->denominator = (int)$num;n4hGB2`&C.c'F
    } x5] I:_`%\yp
    function to_string() {
_zz$d7@/i.x x         return "{$this->numerator} / {$this->denominator}";
2_.P@(? g {     }
2~6q2Nhd6^:| }
W2]"\1xE3s\6O function gcd($a, $b) {F2v ?+w*K8~
    return ($b > 0) ? gcd($b, $a % $b) : $a;+]K w,Q(N%X
}
8~E^5~,Y^ function reduce_fraction($fraction) {
!o5e:WP[1mQ)P\D;s     $gcd = gcd($fraction->numerator,7z ^6Oj)e
    $fraction->denominator);
#JK(y*R!U.S*W(tA;m     $fraction->numerator /= $gcd;)EA0tT O-S(K:{ \C
    $fraction->denominator /= $gcd;7S,]N dCHsJ
}}O^4B~ Zr#t9J
$eight_tenths = new fraction(8,10);T9d yD/~-~e!g
/* Reduce the fraction */
'Vm/FcV3P&bt'uL reduce_fraction($eight_tenths);D~+J~'QS)\bo q
var_dump($eight_tenths->to_string()); ju9QWC?Z"Z
?>[/code]A.reduce_fraction函数必须返回一个值7Uaf Uxp.JdY-M
B.reduce_fraction函数必须接受一个整型值
:D+|8t2M'AxtF m t S C.gcd函数有问题'aQZXE?5P
D.必须通过引用的方式传递$eight_tenths对象P(dRg^*p
E.对象的实例不能传递给方法以外的其他结构。
~N G _f6AE5Mm +r F w Z8RX

XUsM]c 15.以下代码是做什么的?[code]
3N2V QK4I <?php
4\e'|.q*n'l7ld:z require_once("myclass.php"); wicjQ6Z*jbJ M!T9E
myclass::mymethod();
f.h%yZC.\d9Y ?>[/code]A.静态调用mymethod方法
-?H-g0s jDX B.生成myclass的实例并调用mymethod方法
u^er1DHM7Poq C.产生一个语法错误
pl Q6g_8tj L,YX6`1} D.默认myclass类最后被创建出的实例并调用mymethod()
[N3rQ+R-F E.调用名为myclass::mymethod()的函数
"Aj9?-W^!b,|*V 4Z"gBe+]u-s{ |Ua
{ o E ee.ST3M@
16.PHP中有静态类变量吗?w*Tk)wo6C t
M5D`o {G8R
A.有
,_8g'j0K|!P Tc B.没有
(YI+s7aJXx!q 4_PVGR8L6a

f`"L3P{| 17.以下脚本输出什么?[code] /L6y m] LN4G `(CU
<?php
Lw:`!N5u class a
B9L9W acV%U }4r,H? {XpbQ)u
    function a ($x = 1)
aGf%C%e,Tr(dV7c T     {
mo"~7bC;g8g         $this->myvar = $x;{p1U%rY
    }
oy5Ld? F q }[j-s~Ae,~
class b extends a,fJ@;z PKE
{
P o S/H h8G(?     var $myvar;
C:l'kHb,y7e8XGmD(h     function b ($x = 2)
y4FNw0Q`'l     {cY*G4Mida4H&d
        $this->myvar = $x;
d'OGs#NA%n"EvM         parent::a();W h#Qpz4r;Z\
    } rBhp?[4\io"k#RT
}
\&w9Sq*tdk/nB $obj = new b;^3|F7j8j~4Q
echo $obj->myvar;
s"UK+wgn^Ilv ?>[/code]A.1(]S:|vfT(c8^m!?
B.20Pq*ww"cn(G Z S
C.一个错误,因为没有定义a::$myvar&z9dr |6L2P&pH
D.一个警告,因为没有定义a::$myvart [SmR(j(x8x2jW
E.什么都没有
4t#@'df&i8] ns8LKx1c:P

6F E0N[{!v'I:Q 18.如何即时加载一个类?$m6Y)K$?5I1n!i7R

$wJ)jTE A.使用__autoload魔术函数
2zmb/x4G9w @ W B.把它们定义为forward类
R,u+c x[.fMT o/v C.实现一个特殊的错误处理手段
G9SAJ Aw D.不可能
6gp.Y_w|e `;C_ E.用有条件限制的include来包含它们
~$aZ7TX a?.c/{2_3U#BO
f?`(i2@&}v
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
^ _nilM*Se)EQ
-QSl`g     答案:__________xmd/dk
,Ox-c'i{ U

"{@J3L w9\dWz 20.以下脚本输出什么?[code] 1deB Qs
<?php
5{WY O6J HKCh"K.h class a
#L pc^HK(w {
+fn*|M3{     function a()
2uXR8bp6\)v5i T     {p#e3}i5d:e!_
        echo 'Parent called';4C(]:ta1es}
    }
-m9~8o^K,A }xh,]B rZ;bO0D
class b\o+u ^r S
{!A:wm2e;`$t l0_
    function b()0FS{-|*Fx6y6G
    {
?;w(~Z Yn9f5A     }
O&IS:O Ud*f"r0K3b }
X+t ] a:W gW Q $c = new b();
b4@Ni%u]&C ?>[/code]A.Parent called
aXg k,h%~-Sac B.一个错误2]8qlK.FI
C.一个警告~9l:g0M-Lh$n
D.什么都没有
6N/mH1t_%]-\ F r^ ]1H0F d _G%f

kGK9xE'|$z#_?y
O)z(Lw#CS$tV 答案速查
dI5XD)? 1.类9zL7g&v#c{$sK
2.BCD k5W'P1x!R
3.C
aQ?r0Ovzs,{` 4.C+A._b~$VYf
5.A
j E W$Fq0I 6.C})b-Feo
7.C9y,oexc6skZ
8.C
0B:~5g5Dt } 9.D
/Q#s7R iM 10.B@,kLl0I,U:}~ o
11.D7t6k3ya/W/H\(w
12.B
&DA,G@+m_)L r@ ^ 13.A
+az7lv9{F1z 14.D FHt9NL
15.AVa)Cp4i r)C%X
16.B
)b1zr'G!_Z$E 17.A_O"j j r^%k#S K)w2U-f
18.D6e,o,IMM
19.设计模式^1EBp*[ a~
20.D
-d n(yurH;l5zN
T6z,^3?-Hyi
k!e%~3B4vw/G+P3q $cw\[Y"e9V!~
答案详解
;gb`-NJ.z@0Ii {r [J6y,Xsa5we
1.类是对象的蓝图(对象是类的实例)。o(lI Ss%zb*Ig
L;R/h|Hq_e"a4u&k
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。#T;RU'RB8B#ti
"_`5`^(t|
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。 Vq Won"kL_!y
6T(l`%iQB V6yl
4.单件模式可以限制一个类被实例化的次数。
AKh:X @"V&N 0E1D4a4FrT Xz.r
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
'[W7JB5b"@"b'z #r$~+}~&I)f6d
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$L"cY ra m"}-t
x.L!E4d,U&H }T
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
W.v t1Tx d{ F g)F Q jDg&@ _4oj7_i
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。RrW?)AWT
#B,B y*bkrMb
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
bV(jRcb-mPX;x
N$[X:P)QX'|a 10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。#A"eZ.K B)o+T `

2`9kT6S:} N1PO 11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
&Ly9Uf)c^j%pZ
-K FfIC2Z3P 12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。U(b$v:@S)U
;q{YFo[f
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
4U2rv%tU [-{"a(r-Pj)c.O-x
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。\N2s\B7ef;}z;r
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
^4yu+K'aW3s     function reduce_fraction(&$fraction){Ler CS{
答案是D。,mXhPZi/N,s&tM
*N y)w*e z9\o'k
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
~M+eY)tr.O
}6ql&|}e)D Z-R 16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
8j&a/n5i,Ld
N D.zzOvh n&A 17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。QFT7Mw9yFt4[

%O:s|]@F^ 18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6L-PG/YG {$r` wO)kiM.SX&Z
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。p[J)Nb!PK:CF

d5x T9{!t4Ay5r0q/@ 20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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