捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
@o5^6|:D3W7vt0fC PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
ODx l"@ 本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。p\I:Z6X{#N,v
hs9Y.[-[/w)qyw.@/~f
问题
+I(yrxG3v;ay7mp
&d[ g&QI0m%@{yS 1.对象的蓝图是什么?&r]^ @;z

t'Mo&TTAyA 答案:____________
h7[9[.l%p8w9h
8|u(?,} dl(D/^4B [^Q*?tXmEvk X
2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code] /td+{)i6D:QbF7_[
<?php4m6RiK%J~Z
class my_class
LY;n ?@.Y`0\t? {7S3dRW0ohGE*S
    var $my_value = array();
xJe[9Y7F~x @     function my_class ($value)-yIa#kG(m2X7EQ]
    {
!q&ggL${2M&e2z+w         $this->my_value[] = $value;
,Z/aG|:tp7X     }
| T;_1F/}n D3u(i3j     function set_value ($value)
5k+m`&{`     {rpyit%{K`C
        $this->$my_value = $value;n1JnqiO3i
    }c,T5xR-pIem)k:p
}
!h"L;b*p~XQ,e qU ]1V $a = new my_class ('a');
'Xl9g,s-R $a->my_value[] = 'b';
$H!S Ce? $a->set_value ('c');d9o~5C{
$a->my_class('d');)qo4MB{,QD
?>[/code]A.c
h F/IL5Df2rj;i B.b p3vxd&KR0O
C.a
PW#ggoLF_ D.dzM\X\A-d*j
E.e
:hk*K@m
qv;h(c"tI` [^e f3Y
'y'BazRhpU%{ 3.如何让类中的某些方法无法在类的外部被访问?
K EQ&ZGw
l7Cm!|'jy^ Bt A.把类声明为private%[:I!En` @N
B.把方法声明为private
pTo(n"XEC&T~ C.无法实现 UA}Mb ]Cx
D.编写合适的重载方法(overloading method)
]\/DC"]w$k
M|7I ReIHK5cqi
@*l'}?(K[ b 4.哪种OOP设计模式能让类在整个脚本里只实例化一次?z*c0Z])|9S r
*NiC1dkB |-Y~;^)|
A.MVC模式.IU(Vr5y4pbj
B.抽象工厂模式(Abstract factory)
2J0Z?:} m P C.单件模式(Singleton)
.q%R+oYj D.代理模式(Proxy)'{t}A&J
E.状态模式(State).t*p z;t#z'c.u

a9LI,H&ht s%o :ov!`%G A4J!o9R
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
@*IJ#k)z:g)@ jq
#k_A2qe!Hi A.1个pV\n7VE;~$H
B.2个e_ f"i#k;VC9}
C.取决于系统资源
v N1x;k$Ukj&aCr D.3个F2qWA)Mj(U
E.想要几个有几个P~0rpKjV^
7s\ z? A'hVf+uC8D9tf

sJ;lrB y 6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code] 2?*RF'_cG
<?php7C_9A,SL#Wf g b7F
class my_class6dsc;Oyr$I
{$m$f)Z K1mlp)TfF
    function my_funct ($my_param)
%I5pNO&qT#qh$m     {3] Fu uarJU
        user_error ("Please define me", E_ERROR);SU^8l(\x x
    }
gw)WQR     function b()
zGy;JyK(\     {:N!lg9`+f,Wt$k
        return 10;%wW&ML2kRk A#?
    }
u0]+eR:K7L8l }Q/lG0R+T'O
?>[/code]A.多重继承5k$BL&cA)o
B.接口
MFL6DGQk%u C.抽象方法
c2F B/l.LD#d D.Private方法
O/H)[b7}(s{ E.函数重载(function overloading)
}5V"@V3X1a ;~:MP|-Q3|U
!F?{dY!W
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
Y(R8^(B(LJqMc[P
T _$a M"U@ A.__construct
3z0D)N0`6i{!HET B.initialize!Z,~ VC,C1eX
C.testclass
3[.Z6zI~VNgbQY;D D.__testclass)[ H_0L]8fE+Y-G
E.只有PHP5才支持构造函数
3z@,lhW ^
}!S#RX^A+S] ZkY~I)j`%f(Y
8.一个类如何覆盖默认的序列化机制?1aW?x.u#^\E,b

9Pv v/HY3l@ A.使用__shutdown和__startup方法GD R:OY
B.调用register_shutdown_function()函数 ?GQk1]Jm5R
C.使用__sleep()和__wakeup()方法"Rd#tn)k)Uvw
D.无法覆盖默认序列化机制bsAO jh%[
E.使用ob_start()将类放入输出缓冲中
\P }4uLHV[_ r
!TRIv-Y8L yOUJ3bz
9.以下哪些面向对象的概念无法在PHP4中实现?? G3nT5s

EBmI#HL[ @抽象类
g-x5i'a#]K8L @Final类TVs/^r
@Public、private、protected(PPP)方法W8C9LU8BNQ}
@接口
*}Yn'c9N-f$v'^'Cify
.~ yUF/C!kH4n A.抽象类-_"doC g&AY4V8m^
B.PPP方法/nC)xH? ]3c
C.PPP方法和接口;l W4?~+?/@O L
D.以上所有都不可用
'x!q(My^,h^ E.以上所有都可用iL!zH6EzT

0Y.x ]'N2F1zI`iS
Hf1W;dgaw 10.如何在类的内部调用mymethod方法?m%kO2}&Ja2_
#X1|"n;[cgy2K"F
A.$self=>mymethod();.H(\-rP!y,L2@qL
B.$this->mymethod();\?'['L,gc
C.$current->mymethod();Xi0clH;C[2a
D.$this::mymethod()e7fKy V,\
E.以上都不对?.hQ/J'BkY8K x+r6})T^
4i9T;u)p(vTW O

d:k1U6_(g 11.以下脚本输出什么?[code]
6ueIL4lc!CdU E <?php
}*F7A6H/k&@2W class my_class'P ](SI*F#u
{d6t.AO,].o
    var $my_var;
0H6kh|N4Z:h     function _my_class ($value)
N1jQn*e     {
N7b| o&f)P         $this->my_var = $value;n['u,a)P3eU
    }
2a.u%Q Zj }(nE[U T P"K
$a = new my_class (10);n]R&r)o9m k
echo $a->my_var;!X._4caD9I6H1i
?>[/code]A.10A,Ldb%iZ.b\~
B.Null4e H}:oQ8`
C.EmptyK.j Q*pi?
D.什么都没有g)}&{zd$? a\-[
E.一个错误+e\ H P;Ie

we Z0s%Tu+sN ~7vauI%P|
12.以下脚本输出什么?[code] or~r ~xp0k-`CN
<?php
Pu)x6Gh"}-\8N class my_class
r9f#v*y9Qv u*J@ o {yfTX!S7WU
    var $value;
5k+Tg0W:x T#r e[3s&b5x }
pM1K4Vo"e $a = new my_class;
&BH H-N7\/PA@ $a->my_value = 5;
D aDP"Y.k $b = $a;Zs5I5Hb UhOM
$b->my_value = 10;T-E"dpFU+{
echo $a->my_value;
}!Bo0`*F ?>[/code]A.10
8xL @$A u7G(Pm f B.5s`7xG4pg&I0z8|}&d
C.2OM1g6r.Mp
D.Null
.aa(_x X%W+Ej;u5G E.什么都没有$zI,p-xl$L0s;i

p [mjO B K j6hOT_\8S
13.以下脚本输出什么?[code]
"sWb5n e\Cs i <?php
uR ~N(L!\/]$r $global_obj = null;
kf x*I0S class my_class
OVXB x v} {
r`U$~ I+Kle ?p.G     var $value;
D#O%xE&^C     function my_class()"C!H}"| RtZ3\Z+h
    {
~l W$R;en,UY         global $global_obj;
K0HD6}QI_"PV6C3M         $global_obj = &$this;C4N_U:?
    }
a&n7G;y'r.|W }
S/bv1W)P tx $a = new my_class;nJ2U&aPJkr
$a->my_value = 5;
?3nD&D uJ $global_obj->my_value = 10; k+\#~}s?$^/q1\
echo $a->my_value;Q1|l)|xj&u
?>[/code]A.5M fvH}'cF
B.10
yQ(HR4] C.什么都没有
&_"[Gd |st D.构造函数将报错-AF*u$w,KP4Xg1SpO
E.510
a:G2l$PZ%NP 6M&XKt }`v [6{
,n2xRKCY1XO
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code] 9he@j8|_|4\
<?php
h:w/`1eJR~ class fraction {o-_`9@.J H6q5d3w
    var $numerator;
O5y)C$C$@czNk4`     var $denominator;
*o'@&b@A     function fraction($n, $d) {
gIq.iZ         $this->set_numerator($n);
9oz+ZH%_$u5w |         $this->set_denominator($d); xg2Ty+w5g um
    }
@M(DTT2gl     function set_numerator($num) {
T*H*G#S7F+b$Z0g         $this->numerator = (int)$num;
,?{@%\+Z2cd:By+?     }
lA:d U/U-uK IJn     function set_denominator($num) {+d#^d Ga&cPO#z
        $this->denominator = (int)$num;'T4VH"uJ];u
    }Pz.H~ J*SZ{
    function to_string() {
np:\w v         return "{$this->numerator} / {$this->denominator}";
1o0E*?T1_RUM     }
F2V3u5|+r6Z }
6B4O8N!e6fK4R_p n#W function gcd($a, $b) {
v:X?1ae'W6C     return ($b > 0) ? gcd($b, $a % $b) : $a;
F'Ck+FpE%} }e Ck oNc
function reduce_fraction($fraction) {^'W B z1YVw
    $gcd = gcd($fraction->numerator,
%e v#N U'|!q9x     $fraction->denominator);(^7|2w:S1J5\.x M M
    $fraction->numerator /= $gcd;;n/b~"lwl }
    $fraction->denominator /= $gcd;
I!f~wbZ5oa }-]M(n:i8^B,EU3T
$eight_tenths = new fraction(8,10);
+zQ#y/M ha w /* Reduce the fraction */
HGZ7N5l5r reduce_fraction($eight_tenths);
lV |*p"}K7E%L~ var_dump($eight_tenths->to_string());2r&d!`9_q |o%P
?>[/code]A.reduce_fraction函数必须返回一个值
H`K%OoL B.reduce_fraction函数必须接受一个整型值
1~1hMI ~p dBH5?} C.gcd函数有问题HmcTg,V
D.必须通过引用的方式传递$eight_tenths对象
$B6ZQB^.o1r E.对象的实例不能传递给方法以外的其他结构。
6o|/nf7X |P9KAj;J-^@

+f4@\.wv(I 15.以下代码是做什么的?[code]
7F0ifvaBX <?php
o5eRN/B7gT%w(dB require_once("myclass.php");
#]-gUb?sc myclass::mymethod();
JAs Kg|JC ?>[/code]A.静态调用mymethod方法
b5V P9I3lE-]V`(} B.生成myclass的实例并调用mymethod方法
:O"xM J[ `G"Y C.产生一个语法错误}%X i"S g] U
D.默认myclass类最后被创建出的实例并调用mymethod().z7W0q Q-dak;OO
E.调用名为myclass::mymethod()的函数 r{ S:Wa

]4fi.D-|&h Lqk#S*s^T v"fe4z
16.PHP中有静态类变量吗?
-YNjX.K,R+Lq 0AzHh'I1m5t
A.有
O(}o!J'`;R"}-ai%O[ B.没有
vfK;w(\tCVK[
U1MbQ%D5O +SZ0V}~u
17.以下脚本输出什么?[code]
(l0P~)h*pc-Q1j Al]i <?php
M J+~9Sji R5nL3U0J,D:y class a
o;TK x4|L*i {'NVA lX4h4H:BH
    function a ($x = 1),?4Sb,WW3bx
    {!xzC6e2kM]'e
        $this->myvar = $x;
?}|w2y4H     }
9F2d'VJu J }
-h Fl-}&J,GY"U%oA;m class b extends aa0wb,@r;m
{!Z TD)Ed3Z'R"G
    var $myvar;$`c7@ySh `o
    function b ($x = 2)
/O!f4TXz     {8C(?'@y:rV
        $this->myvar = $x;iKn2hr8U8o
        parent::a();
.Ba5[:iN     } Po'{T0aL_eBI2Xk
}
1hj#FWC O $obj = new b;~Z/@X-D
echo $obj->myvar;6E g-[^ZL
?>[/code]A.1
$l r"MPe0ehCcc B.2
^#?Wv[-Afk&Y C.一个错误,因为没有定义a::$myvar
-Ye9p#oHd({B:\8oz D.一个警告,因为没有定义a::$myvar#r0t2SL?4{
E.什么都没有
`*{oU\+b&H0k0x6Ly I;|#vE)y
7e"vS!DZ`g
18.如何即时加载一个类?2Ta G+Zs2H5Q|%a|
C\7sbm!x
A.使用__autoload魔术函数
b.oP+DS B.把它们定义为forward类3t4[R ZJI1K
C.实现一个特殊的错误处理手段X3fY1r#@)J
D.不可能0Xy eI+Y%E X
E.用有条件限制的include来包含它们
c/BF-j#w nW4r8n(m.S8~,I

*jK5F.BgY'kC? y 19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
^$S;n J%war
t*F0x nX     答案:__________}T4Xy~8BWL#D8F

g+R!~4Z+Jb
1?+yaf;@ 20.以下脚本输出什么?[code] .J0|p[D\0z\l
<?php
:}%ZF4X Z|AT L class a,}'u g!z.eK2j
{4z4k&R:y#f
    function a()/e3@ l_]
    {xr3s[&i#TO o1h
        echo 'Parent called';!J&["\;X3rT'zC,z
    }@3[ WPxFf%aKQ
}pr7@f,k |^P
class b~hQ:A4I)Y;GI
{
-e$WS0XbS[ ~"FN     function b()
qm Bd'd     { t7e&dt"r;E
    }
&],oE$@4PD'w }vs6q%nYY Ns
$c = new b();
\4K}5mZ+cAu ?>[/code]A.Parent called'n!Aw;}l%~R-e8S
B.一个错误{p_(]+S
C.一个警告
\(m~4~w#l4q K D.什么都没有E(w'd$i M `e ?2{p
zR)i ]TCv,[ b

%~ mx(}t] ].u flQQUU/jF;`/c
答案速查
E"E4TnO k/N;H 1.类
D#q{&N#e 2.BCD qbS#VCN
3.CD6[,w7y/P
4.C4q"q \7]n*d'F+Z5Ud
5.A
5Vo0A)W8LJ 6.C
8qkz `0d 7.C'r c X|hs ^^
8.C.X7QW9ol#Dvf
9.Dx{-He0Q E9W&x_5W4CT%{5I
10.B
[/u&?hw6wg ~ 11.D
L]"N#jS0[+F 12.B
E7R PG0bvU 13.A2X5P __m
14.D
tVrj6x-oFJJs 15.A
}r0WQ;U5\P 16.B
7?q:I-Q%Ka 17.A n%h*N9?Z D-h!LXV
18.D
-wQ'bl l 19.设计模式6Vj }&I9\F9B
20.D
%C3`;@I_!? z^-|!x ZC;v| @Y1t){

G6_%A,e z^&\x8o4y
!QOD:h,IxDe 答案详解
IN6m pM:w2XYw dU [5kh"e`&X
1.类是对象的蓝图(对象是类的实例)。jIn e.b

1}zXQuN 2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
&iO5Xu(P`~ !D gd*TvQLeH
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
5C$s!OFy2V RN,U`bgH)LX q
4.单件模式可以限制一个类被实例化的次数。z&q z Zp]0?+K
2wR\2u B%t6KF}
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
kxsT'JCo v7E rel`rD
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。5`&zG+R#JQ c!k0v
TD0@;X%c1X#}6lE
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
\b&C5L xN
i!U9l)~-W`/UI0J*v 8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。L3v7n XA:m]ch

(Z s5YnvNE;d 9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
OK ~*}b2j.b:] )Gy2bd H+d2r mE\
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。k%{\Sfb$MD{-N

*k|(l.WDI @ 11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。z \1j%d l&]
g{{o4V FA(E@/]#Hy
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
$k2@n^db
BKwrybj|#l 13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
P;lm [v!TgR"Le0e 4N:@$U'Y*X(@,G8U1s
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
'n(F0` fQU,g6l 回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
|)`c"OLA4C.M     function reduce_fraction(&$fraction)4J"i1O8F{#]
答案是D。va1f[:R [F \
o1[.OyR Dv/r
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
$_,?([.Z;zHh+n%_ 8We a Zdwe
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
-] s*A7Y1v
y{0_,I g aBN 17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
9oT!eS?QH#s (H4K:}0ca `*og(R
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。U F2_ l3}

4wM yi!r:I7?g 19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。#F!R!k kQHv0M'a;l

B"l]Wa[w"P8g 20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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