捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
qL B7DB ]z PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
;^?*B%H3W r&k0f 本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。Hp"eD+`:v-IR
A/V!RyW/w2d9O#C
问题
7S(]-S4K^ q(t-K-u:u 5o&qi~*y{
1.对象的蓝图是什么?
.YD;~jh4}{9u A8F!m P WZKM*R MO
答案:____________7p9Ph,Tr

;z.mR/y3[ rK!u 0X(U6NY?kdw
2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code]
4q,?#O|h.GI <?phpPY2U-?B*vUp
class my_class-Qh0[[U ](Xi;s`
{ S7N p,q|,a)zP
    var $my_value = array();
QL gOp     function my_class ($value){7Tw6`jJ4j
    { z0W^+c@5L]9y
        $this->my_value[] = $value;![y` jH;?1ZT
    }
` ])a UAI0m{BgD0r     function set_value ($value)
V8@$x8}9R(o     { \&xa'PF;Uv
        $this->$my_value = $value;
{f|^^{ f~8w!s     }V3E/|&UW:P0u5k @v
}
R\+e?'Z I-~l {l $a = new my_class ('a');/iomMrW E8D
$a->my_value[] = 'b'; TPC.uY"f_
$a->set_value ('c');{1T"N@#A]
$a->my_class('d');.dnb$?Y2T
?>[/code]A.c
;L,ny+^:e BG'fHS B.bP q-{)F4?
C.aX2oXB,Fr
D.d
r[6o-vB/Q&hg!Y _ E.e)GR0L@n
p)on9Jf#E)dGV

TJ km w_ 3.如何让类中的某些方法无法在类的外部被访问?
Bc0e9GZ
X|7W^/c `e A.把类声明为private
7l+F*pezgWH+E b B.把方法声明为private1g!Z0IM,a-n(}E
C.无法实现5`L(ak:E`._-|
D.编写合适的重载方法(overloading method)
N*y!_(Bc4tPK5~
-I;v[#O\-S;f3t1Hy N rD/f1hP
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?L:mx__6u.V9z8ox

%T0? L A5\he A.MVC模式
+d U^d5EM)B B.抽象工厂模式(Abstract factory)A&c t[X Z/o
C.单件模式(Singleton)`peVe
D.代理模式(Proxy),Wg$d:Vnk/x9}!p
E.状态模式(State)
4d(?(d3] P f%GTH O !ry J@iNs4w S

,u lA1]tP_3r+k L:M 5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
0MScc3kmR\*f&j ~f;d/eg@-}
A.1个
bR ]i_!_/_4mT B.2个{$R-eJ-]&`%F9^H-H
C.取决于系统资源w\&OZ$M#tM8m
D.3个
S5]ru N9]s E.想要几个有几个:V$bjl!OU

aoEP:^VQb(u F;M.F+M ~"kN O%X5E
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code]
(A,S ]X0rJ,Iu <?php
!OH rN JD!D1s class my_class E {}V%`5eS
{ jrl{&W:w
    function my_funct ($my_param)I r5\+Ob:X,D F\PH
    {
-g.i1xq$x l:U         user_error ("Please define me", E_ERROR);
7B Q0qLp+oF3^X     }7GS/DB^|
    function b()
dS:g$O/mc W     {
QY luG6m         return 10;&Tc"M{({,F?am6[
    }s i qBG
}
6H%z#wvO8V[ ?>[/code]A.多重继承s^R? z[LKNr
B.接口
xJ{/ni_r.P C.抽象方法P*a[e&drd
D.Private方法Tz$S1m4xQ
E.函数重载(function overloading)
E;prfE6cV 1Y|%]GQ9Y2k
t*U9[,bpT
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
^}8}p!L'V z.G*y&O P's1|ux6Z E
A.__construct1?JK]"w/E
B.initialize@]*A,?.[%B8d|
C.testclass
~d!h Dq D.__testclass N;^RlE7D
E.只有PHP5才支持构造函数F7lu2i&U

,j@6o [ m.\N1r]U 9X]m(YpS
8.一个类如何覆盖默认的序列化机制?
t&j%k n U VJ8n$A9KHv)r.`
A.使用__shutdown和__startup方法o:g~M9E#n
B.调用register_shutdown_function()函数Ayn9oa
C.使用__sleep()和__wakeup()方法
%pohe;ED+n&YS-uJ D.无法覆盖默认序列化机制-w9z7brMy7F
E.使用ob_start()将类放入输出缓冲中
-A;\8V7sj1E "Jg$K#D$Y
&Nx"}5c4iP ?8d@
9.以下哪些面向对象的概念无法在PHP4中实现?
)w\x3B&bx`p (_ l;^3Q%K$p@x}
@抽象类#S!^ X*y5L
@Final类!_$n;J#_H3x
@Public、private、protected(PPP)方法PpLs7z[
@接口z(U?IERw
I+Gs"V$Z
A.抽象类
Z IQ6QA(X B.PPP方法{](rS(`3B$S$M
C.PPP方法和接口
i0X A)D,I D.以上所有都不可用pW%CoP@D[L&A4p+R
E.以上所有都可用
)Q%l:v.b_4i9M H7nTV;Tq0X&u

bp)P hVd!T\^J-l7^ 10.如何在类的内部调用mymethod方法?PZ/M{|m
+Qu|6T$b
A.$self=>mymethod();Pb,@ yG
B.$this->mymethod(); c[+Lj.K \K
C.$current->mymethod();kZTs7|
D.$this::mymethod()Lup#N wDu
E.以上都不对$F!m*@Z6j/F\9TE5U

;Nv z"IY-`'O ;Ps j m#b8YfPr
11.以下脚本输出什么?[code]
O|5f@C <?php YV_!j0D7S7r(pD
class my_class
w6nQs|1ZBv1X {
4J9vKI:Ev ]"I     var $my_var;I*`A!VBD
    function _my_class ($value);I5GP7}M
    {
&l8v6X]d%_         $this->my_var = $value;v)g8Od/v k)[ V$`!M Z
    }9U,GQD8G
}
~W(n \(T4hZ"X $a = new my_class (10); m@$|` bm@r
echo $a->my_var;w,E(}\ B l)G:}
?>[/code]A.10
2I8t W)qD ydD] B.Null!~(D2Vr|,m+y
C.Empty
xp$qgF u b&m ~ D.什么都没有
W0}+z5yyn@ E.一个错误B h[_1PH

A$p)N1F n0S
)p3wj9d:PS 12.以下脚本输出什么?[code]
z'O}.tR!c(Rq <?php+gt-Dn0}~ d-Rm?\%a
class my_class
Dd F;]OeH {}UEj,~h#o(i
    var $value;
)X%Z:QW!VCV }9I.P"[W1T]6|L
$a = new my_class;
;tzaSvZXp }` $a->my_value = 5;
/WO3t1c `du A,_ $b = $a;
T] N|r2Ht $b->my_value = 10;
Q8R!~']0? M echo $a->my_value;1cv(Sb?E6[:a;Y
?>[/code]A.10
-tM [!k$Bl+P)yn B.5
;W#uS_z2C C.2#w;R8w9ds P+} V b
D.Null!a kc+aJ%`
E.什么都没有Cr"{q|mB$l
4\!_}(DCv\h}u

^mfs1Q.lh:I 13.以下脚本输出什么?[code]
+K5e@(?ML <?php'O&md*uA4wc!B
$global_obj = null;W:U(V"HtM~5SE!Q
class my_class
`-cc G)Y&|R~*E {
b jQ'k'i \ dx     var $value;"bKk-I#qH
    function my_class()
4t&|(`Z*`"g%]     {qv})]z)]"RH
        global $global_obj;7`-J$sck8e!B(`B
        $global_obj = &$this;
K)}!G,l:a4w     }&H [_;~Y _dxf
}O&C)ie#x~ k#I.{0|kO
$a = new my_class;
f0kAX:Kn5Rv $a->my_value = 5;
@bH)r5{$J t2T:N $global_obj->my_value = 10;%Q0^ ]9}x'K\ |+C
echo $a->my_value;
CPC fF:E_ ?>[/code]A.5`)dO-d!Mim(o
B.103H&J3l"J9{+x/Ki$k
C.什么都没有7{zq u%]XQguF
D.构造函数将报错1R_k/XK6i pQ ]
E.510
2c$| | U6|(a.P Rgp{ Q'j~d {%?)M
g*jFcVbq${0d
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code] F1P}#u3E0}/l(?
<?php
)g'x,]b] G O class fraction {Tg$u2A Pd
    var $numerator;
+f"_Z;K7G kh1g     var $denominator;
+O0u \*\:|a|     function fraction($n, $d) {)ugZ?4e&F
        $this->set_numerator($n);K,UDd;?p:[W:E X
        $this->set_denominator($d);kD0U7F+C
    }1t3F_-q!G&z lcq*J
    function set_numerator($num) {
C/sb'{S         $this->numerator = (int)$num;
zm X,~w#vo8@)_     }8M)B5G%Dk+F&a
    function set_denominator($num) {1]*W%K NY9bD
        $this->denominator = (int)$num; aZGjV&o!rD
    }.Q%l,HcdI/U'n
    function to_string() {
&k.x&O)r-U1q         return "{$this->numerator} / {$this->denominator}";
M(U.~zEHE H;z     }
X0?3I`7o4L;["[4h2ix$a }
PdA:p g!R Kl1y)X function gcd($a, $b) {-Z@%mB*|KGX
    return ($b > 0) ? gcd($b, $a % $b) : $a;^ O.p t xM fn G
}
Q#s;iKM vI function reduce_fraction($fraction) {%~*V%N_!ia:N s
    $gcd = gcd($fraction->numerator,4Jp0}\4]@8T6b
    $fraction->denominator);
_W&_rq1m'n     $fraction->numerator /= $gcd;
g(t'vq|'ift-Z     $fraction->denominator /= $gcd;
4ej0J!v@#B:y }J jf&I(V;B0W0g
$eight_tenths = new fraction(8,10);
1Yf KXG+Q| /* Reduce the fraction */
QI;M*s S2O reduce_fraction($eight_tenths);P ]+Ur `&f
var_dump($eight_tenths->to_string());+M)K(ha$Q3M!i ^.z7J0y3Va
?>[/code]A.reduce_fraction函数必须返回一个值5xQ `2J1P i)_
B.reduce_fraction函数必须接受一个整型值
~1a m*?#h UU(P C.gcd函数有问题
7T.f's\h4dQ| D.必须通过引用的方式传递$eight_tenths对象yQ3K7Gh? r&tMh;R
E.对象的实例不能传递给方法以外的其他结构。
no#P`wIIj
L i e5is/A9R:Lc
l"od |q5kE 15.以下代码是做什么的?[code] [BYMp[1u XM
<?php
-n @w8Nr require_once("myclass.php");
ev;w dfY{ myclass::mymethod();4\UO*E4?.M
?>[/code]A.静态调用mymethod方法hC2Hw z
B.生成myclass的实例并调用mymethod方法
$yJOUfB1hw C.产生一个语法错误5I%ro M k
D.默认myclass类最后被创建出的实例并调用mymethod()4_R6s T*M.E{Ja#g,b#k
E.调用名为myclass::mymethod()的函数
6eV"M@&d}%T6BE
/D2A,j(zst+y Hm0DC'\#SF$}z3p
16.PHP中有静态类变量吗??w;n'j,e"FQ_ f

EU/D] X8P A.有
ht7t!_6BJ|m0z B.没有^*C(]}o zgn(j
@"_Wj\oH dF

(|b^AWQ8P 17.以下脚本输出什么?[code] )KU%f6q _6Jd
<?php
'd,m~p+Ta6?q class auXw6L K?5ir VA?
{.X'F^]Tv%I M
    function a ($x = 1)
ot'\L1X/i$x3c A#C     {(S$P(r+MsJ `+F a.@x'M
        $this->myvar = $x;6i8I:y g],M D
    }
Ja+s%i"J%F7Ola} xD }
.c@B2W(XPvP%HA class b extends a
t%TzXr+[.A8?V {
\j!\!O7]F/Tb     var $myvar;
7v(BlFZu     function b ($x = 2)
H/U:~7U'v `$V     {)vD%r0Y%n ?W5i
        $this->myvar = $x;
$P8x?z T*u         parent::a();
W_3Uu)L m7_     }+t A6botq;|2wo
}4ezG)Jj/e
$obj = new b;
:SuOs$qk echo $obj->myvar; \#g n-`HYY'v
?>[/code]A.17q8F;su3y2k}7Fg
B.2&c3J PA8CX*aq9U
C.一个错误,因为没有定义a::$myvar
3iv4|:}(B"f7K6o D.一个警告,因为没有定义a::$myvar
/?A1HM6Ko%D E.什么都没有
6k:nl8H,r-P&CC #|u-j:A\?*^
$tVT.B)[$l#k/I"k3j)D
18.如何即时加载一个类?
&j#XsR3[#SI
4Y_aA{.R A.使用__autoload魔术函数
}!W8D$~9H e B.把它们定义为forward类
X2GH"C7I/i5QR w C.实现一个特殊的错误处理手段
-C$pU6H'V!InFe#R D.不可能
+h'@6i YvV E.用有条件限制的include来包含它们&K?3M IC h1uF DyqfM

R sP%D.?c*v9KZ:L \7g l4fa"k8S3ER
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
jac Dx&w"VxA
G_k0q1T r pk.x4}g _     答案:__________
0byZ\&l/g
lqa&R7T7G
"\}-Y#NHXC)C7} 20.以下脚本输出什么?[code] lh~y'] K vC W g
<?php
Z f^0J.cD class a.]^ [0b$D0B
{
YQa V fQL-q     function a()
sa2F}-Q/d L     {)A_y7Z V&y G
        echo 'Parent called';
K%{%L/|F;a`X     }
*I7tRt U"Bn },H9T L @)J/l3p1kq%G^
class b
-~BIiX? { e gR"DV'_Q
    function b()3Rc)]cu&zs:mY
    {w:i6siL2{pu
    }
g{|2N)e3GX$yvQb }
d2j.ql }+B#^5{L!Q $c = new b();#q8eV |rNcz
?>[/code]A.Parent called
,m8b @ B2]*Y;JVQ B.一个错误V"ie6| \%n D
C.一个警告
] zu$UiL+D D.什么都没有
tqn;y9Y)D'a } q-Bk g gIWK

,|J%Y`-Y h
%oI,^"Qa4{N 答案速查-A i ~9m%k.~:\t0R u&A:k
1.类6{-` X A[5mf-^
2.BCD*M,Bga4P:pH wK.z/xx/o
3.C P8Z_7F1T
4.C(k:L5g!j|({
5.A"U(b^(W!_'^{T+p O6e
6.C-_3iF5I9q\3j^
7.C
%Y:ED g-yU!Te 8.C
5^Vt/p)K? 9.D
)op HL TECcmW 10.BK nm5Mcf2]a.x
11.D
*uf#H(u M~\ 12.B
&|5x*dNlu 13.A
uoV;zQ0m2uD k 14.Dm5I*v.uVxf
15.A
[T6L_R+Ah 16.B
jFW~b)d 17.A!Vn4?D!{)e)P
18.DqrBm rIS"s/B
19.设计模式(hu1K5xxRN
20.D
4ItD%dx&b_.p,J
N}m3t#P toD
%g K z-lf6X(m!V
e/Yh(@Y 答案详解
3V#H5M!J:I:y &oCQ L @F&^Ub
1.类是对象的蓝图(对象是类的实例)。
\ p2JN/b!LB[q7P
wV+Z,g |m 2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
Zj {8j'y5~B/c0w*EZ
%A[&z1{)]?i-z 3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
b}R3gqAlJvS7t
?)D8G]+p _"k$lH 4.单件模式可以限制一个类被实例化的次数。
W;C2n^B7U7U"T y+byi | o
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
vGt#K;U4o,NB$i
/y*i/C&k8x*X+Q 6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
p'z?&Kd Ww iUS0ek
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
6P[k^{D0f7[X
5Q(P,nz9c9\L 8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
[;h-nO(ED
+k0ibP2w5Qc c 9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
9[3^Vgww
:M,U0hoq)H3I 10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
b lRVl,t P7L;@ TV+q6U [-Ac
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
+C,] M1i\7Df"p _ A Pnq0V n5| k&K
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
+G-qVV} yc
Rf+h3T#q 13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。/CHE'|IR!li7N.I3O)qz
luH!EWQ
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。+i9v._C#Y
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数: J'M0|js mh o
    function reduce_fraction(&$fraction)Z s'K'V&fX:\.G;Ui
答案是D。 Z Yf0tW)K@7l1o
:i{3U@-B6a
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。3NPv]A/c$?V
_b^ sj)N
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
M9Wg%E,S4T)p
6A1GH$Gk#h4`%j 17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
)Ge8kC$x_\[sc 8P9i5mm|/|$B#Sx
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。&A2| bdMx z/U*Y

l E+G7K;U-NZ 19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
({a Q(c5E^ Y
{"c H7b/cNV 20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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