捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
vOj8t:yIG` d PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。P4A DE/ogw
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。 U]#| md_;A,nl
EV oe| f
问题 ^a0m5un#F$K

A&f~2o8Z n&L] 1.对象的蓝图是什么?
`_l%x2@U![E }$hy m([
#} _9F/YY%o2~ 答案:____________ s"eJL#B!n u0q p
sW)V/Q]6k Y
w_+ZR,K-}0G
2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code]
8HZv'Rci <?php
7P?`/K J H*^ ne class my_class[\n"MA*d3|4S
{CXQ'S8y-cvC c d,f
    var $my_value = array();^n]5[+L5R
    function my_class ($value)
G1Eb,Iuf     {
.Qg1Kr:n         $this->my_value[] = $value;
&j$d;Sv+uba     }
e.sj\8Lwugk;k     function set_value ($value)
} \'\PFc uGkb     {O:LzB0POt@s5j
        $this->$my_value = $value;
P*@~3O2^     }e;}?)Y%L"SN3K/ZJ
}0C8f(`.GN"\
$a = new my_class ('a');
$fp&Z[ g $a->my_value[] = 'b';
"~$C,CW/r"B SvW'u"P $a->set_value ('c');
HzHLF'U-tANTK $a->my_class('d');
~/^\bv ?>[/code]A.cU|t~| ^vK1g
B.bm:[CY"I+b,K8O:Uv
C.a!rr&JU b!Qx Hw
D.d
w mE#C4us2i E.e7fbrDu qS.w1O E8q
Q?!w+WJKNM7E

I^nbP/X!R 3.如何让类中的某些方法无法在类的外部被访问?j/k yCH ?P cQ*b
c/n UeXT
A.把类声明为private
*^)zt b9E B.把方法声明为private
\2Ig5X K6[ C.无法实现(V)v.p7tA+B
D.编写合适的重载方法(overloading method)jj%N/Q3x

kb#z2t$yz7}%[k
;X~X2jiI$K 4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
+t)l,sVr-X H *s"o)S/ZaN
A.MVC模式
3_!iG%xyMk.K B.抽象工厂模式(Abstract factory)
`;_;Zj v:|a C.单件模式(Singleton)0jsp m5q.c zR$j L#B~ G
D.代理模式(Proxy)W`B B+f[1X/TG9[^
E.状态模式(State)r-j$P v|Bh"a
Q1R EazE?

G_ M;BpZ8Bf5J 5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
mAK&p'aDu
/P.wsMR_*_ A.1个-Pr(gz2X3Bc6@ D
B.2个 h n3H)\!l&}y
C.取决于系统资源
*JvZx_ A P+^a D.3个
U,YR8X"ER E.想要几个有几个
AE%b?!e W
D"@Vd3UO7i-Y&A 4g-KC9gtrk
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code] 8a%K`ig|o$G|
<?php
|:}%_+to7?L class my_class1N p8DH+Y:nI i
{
jP)w U)~X0{lj'w     function my_funct ($my_param)-nF3X)alU*x
    {
'NL'g9Rq w:?]F         user_error ("Please define me", E_ERROR);
9GZ/syq'HLA$v     }
MG%yp)R.O     function b()
jg+u.^FX?^^     {1o l0TUZ%`,R$M7]9`:} s
        return 10;7ebQ cR)?
    }
Y]%k ^9iZlY }-~1Syc|&e
?>[/code]A.多重继承
W;c4z`5JL{+V B.接口
D7A-[i7@4P C.抽象方法 l{N m$U H
D.Private方法
!@${;k p7c\ E.函数重载(function overloading)z8o7\l3a;f/S}7D
0p6p Jv&LZ K

-UjH3P3@4NNKS&z eB 7.假设定义了一个testclass类,它的构造函数的函数名是什么?'E)z$q{:J"Z
qw1A+s9x!oL
A.__constructb] y_M)] ~
B.initialize
![4|0a[^*?$f A C.testclassY#Cd:Q$y
D.__testclass
S9~n|'X uu E.只有PHP5才支持构造函数
N,B A&T9^0T c!Y v'[Ma5T2k
"C2`D1M7t Z+P:W
8.一个类如何覆盖默认的序列化机制?
$f _2_$V:rr |dM0a g V.a u;f(J*o.tI6q0m5n
A.使用__shutdown和__startup方法R1P;rx+F7?7x
B.调用register_shutdown_function()函数
2Z}6v+Q,lvL C.使用__sleep()和__wakeup()方法 e5C-e` F
D.无法覆盖默认序列化机制
6fSb Q^,R'R KG$}!\ E.使用ob_start()将类放入输出缓冲中"i WB/fLC0C'?

!R_Tx&l7m
?n;xP%`u@ 9.以下哪些面向对象的概念无法在PHP4中实现?m8X-id8b^P

;hpuCY8@8B^ e K @抽象类
*~-{ H\5j ^o @Final类a-g I${@
@Public、private、protected(PPP)方法
3j7{4MAA(A @接口'gZw6mC1wE
0Ybs7e(_k
A.抽象类t dY9Y:_4}
B.PPP方法!O'^$x2XZ7iu
C.PPP方法和接口
9kp xY RPK(a D.以上所有都不可用/w T#ts:h$J
E.以上所有都可用
o(dv gd+{'A*p
^8pAL%b7k2CM&m V pz(\b wsO_
10.如何在类的内部调用mymethod方法?
!RqCPbt@-dg@ %n;v'g0b ?Q
A.$self=>mymethod();
.G&|#R}d B.$this->mymethod();;~I'l7[8]u?O`
C.$current->mymethod();
e+Y bj;W;b:ox!T(K D.$this::mymethod()
kN8M lBYX E.以上都不对
e_[%fe(t
2_6tS\0w1FX zK7[+J@e'G
11.以下脚本输出什么?[code] M)vt\nZ"C'rO"y
<?php
mig8ff.A$nEM4a:{ class my_class u @s)r0R4|.c;n
{
9VyCJy/X r|2un     var $my_var;
1r(j/Ur7F8B$q     function _my_class ($value)
q0l H G*B4pr4t     {
h'`9[.U2YH5O0t u         $this->my_var = $value;[j3y`)t0c+\ V
    }
A? c#a|/n }
8NCj5A"J-i_5riojX $a = new my_class (10);j$M c9\ie[
echo $a->my_var; QN)Ot#^
?>[/code]A.10!_)n{w_`c#W)yK
B.Null
+gU B IM*c C.EmptyV)qg|5R3Q
D.什么都没有
T3@g"HE-[FsH+k E.一个错误"BhAs5qiT[
3f| v rlP ]&bP
`by.a`K
12.以下脚本输出什么?[code] {C[fL
<?php
9W$d8@7rH\'w0L class my_class
^q/J:Ko2m\ {#Pu2k2a1c1{,{
    var $value;
:rjwnDE9^ndS }
s D{rst $a = new my_class;
:s6mx@;Ls-M $a->my_value = 5;d:z!x`2q
$b = $a;
6ni _(}Hq ?*J3L0` $b->my_value = 10;
A&_rs!Y4f ? echo $a->my_value;
dr7fttZ:x$h#u ?>[/code]A.10q {5K{"Uv7xE?3j ^
B.5
!xU1|+h%s{9H C.2
]s0f-A6O? D.Null
&n7lo(p-e E.什么都没有
^ M$bit6c c.o}eo}n Y U

1B'R E8|(TZVDc 13.以下脚本输出什么?[code] 1X|.GEo
<?php
n:?1Q `@QE p $global_obj = null;7[[#e#p_:m/R
class my_classC.m` {#OSW
{
z;Ux.C3A7Zf7^%y%|     var $value;%w[W;@a-K(Q7Xf
    function my_class()P%o D9QH;U{1Z ]
    {5v#wm(_.J(oz*W5Q
        global $global_obj;
7d!Y h o{$iK         $global_obj = &$this;
VkZ8m8~     }(Zk-YM V?n
}.M)t%Uf;? T7n] K
$a = new my_class;
T(Y6{t~9nl8B'J On $a->my_value = 5;8f smh8D*p&Js&rn)C
$global_obj->my_value = 10;
5`y hc7lp5}NW \{ echo $a->my_value;7p W\bwi8j8?
?>[/code]A.5
)I+D^8Qa8p gs p B.10
R&[1u$gL] C.什么都没有
/h3@'z gP,G Ng D.构造函数将报错
Ba;i4Fa b%| qjk E.510:Nx Q}\"{J
q I%zp-[-WdoZR

Z5RCz}{.n.ton u 14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code]
){JmEv.V#~5s <?php
3t7r'S nO2}:q class fraction {
ba G"Aq     var $numerator;
P+j#`BD jS     var $denominator;
:o-A l/bB{w     function fraction($n, $d) {!k_g}9D6DR&R
        $this->set_numerator($n);
Dr5k!l4?D%@`         $this->set_denominator($d);
'beF-G i(k     }
-Me QX;m J*L     function set_numerator($num) {T8@m"mKa
        $this->numerator = (int)$num;Q+Q ]!Y8G"y'S,T(_
    }3r&_%D t~r
    function set_denominator($num) {(Pp@^O v Dc7y
        $this->denominator = (int)$num;&K WA"e O
    }
0N/W]z n,~X\     function to_string() {M K1l#Z)j$P"}7p p
        return "{$this->numerator} / {$this->denominator}";Y`+]Pw j;RY` t
    }r }$Zt1q"n:i+_
}
+E!QLTo function gcd($a, $b) {
&vO h2p-B_     return ($b > 0) ? gcd($b, $a % $b) : $a;
Z n&VAQ1q dIm }
&N9C^&E&owT$tQ/l function reduce_fraction($fraction) {D D)x \yU
    $gcd = gcd($fraction->numerator,
0\BLCds [     $fraction->denominator);
"S:FS,xM"H2OR     $fraction->numerator /= $gcd;S!l8B2cV.q$a4l Qy
    $fraction->denominator /= $gcd;.V Ymi7z+`y ? M7^
}H/K-n5E\4W5j r2Mt
$eight_tenths = new fraction(8,10);v e-x5{ | PN%t[
/* Reduce the fraction */
\])Ez b3^ DG reduce_fraction($eight_tenths);
d#y3M$Qk var_dump($eight_tenths->to_string());
'k5f4| Jl%Z\2i ?>[/code]A.reduce_fraction函数必须返回一个值R8n4F$fg|!Eg[
B.reduce_fraction函数必须接受一个整型值 C\#vQ#h(vH:ds
C.gcd函数有问题lJ h/cMV+L
D.必须通过引用的方式传递$eight_tenths对象:cAWCa K
E.对象的实例不能传递给方法以外的其他结构。2`S^2j rn

(|TwO @%u s h|xz&DZ
15.以下代码是做什么的?[code]
-u z._frw <?php
VZ*x!p4]J require_once("myclass.php");
UA+rd#v}i o myclass::mymethod();
)q`b+\!kZ+MO ?>[/code]A.静态调用mymethod方法7B,b8f ?_&g"C `T&g
B.生成myclass的实例并调用mymethod方法 [ m%yq`,T/e#c
C.产生一个语法错误;~ RYMy
D.默认myclass类最后被创建出的实例并调用mymethod()9xT-r2w7Bb9{;m:x2HM*`
E.调用名为myclass::mymethod()的函数3g(lG)@Lv/}S4I m'|7y T
(rin;b#?5q
`"Cjj&bE?Q
16.PHP中有静态类变量吗?5uNW;C)n0V3}rhX&lL|*l
dz]cy,i"GZ6YS
A.有
(u!\GlG^!b~ B.没有;Wl w+} hF fI\
+etxm&Y3d
^uw*?Gl lA)gb
17.以下脚本输出什么?[code] Y @y\v"W{
<?php
.SV+l0N6O7U{ class a
-{!{!t@ GD|XI1F.W {%b+KLJt5a/iqe\.C5pT
    function a ($x = 1)#a3wvq8g$x%S
    {#oIP|3xP%I
        $this->myvar = $x;T W'^vQrB z,f
    }
2foi8ec8P%n9yU1` }
'k0u"jU8s class b extends a
7T`(D"?;Y-` nt D {
9^'F2P/P*~/Wb X     var $myvar;
O^hP?g'c     function b ($x = 2)#C'dZ TZJm_ F
    {
N"g#p9u Emy         $this->myvar = $x;
@q Q)G(q         parent::a();$w"XyfL\ P!u.~8w
    }#Y zh#C X-n sO ~m;L
} Ri)` oc7N
$obj = new b;/n3d\)UEL
echo $obj->myvar;
P,|A!vh e%s ?>[/code]A.1
_ Wc.c ~YDj-e!{jd B.2k;Xa1YF1y
C.一个错误,因为没有定义a::$myvard m ]5o^i,M
D.一个警告,因为没有定义a::$myvar
H'fd8Txd[/j kJ E.什么都没有
)Z I(`q%eJI
QiK'|*LQ 2U5m#d?{l8kQ
18.如何即时加载一个类?*Q,N jeA.u
:Y.`R6G i*_;[V
A.使用__autoload魔术函数
VSUO u(iW;Z B7H8@ B.把它们定义为forward类} _)Al^)Q
C.实现一个特殊的错误处理手段!Uv7mc2J1l$V$x[:}
D.不可能
['`ki~5M7rqo ]'M E.用有条件限制的include来包含它们K t(@'oM gUtP0d

Q:F K#]zR 3ws0r-J)N4c6K Ot3d6p
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
i2]1C Q5Vq !i-Tu&] e qvQ
    答案:__________?6]y_ch,lj"[ E

Hk@[-[1IQ$W_
u$M(U)Ik 20.以下脚本输出什么?[code] 7r?P1Y+`
<?php
_ Z9@Y[-J&?k T class a ]5\ E"f'Sd+`,N$b
{
-d/[#}Ob|     function a()
#O}Y(h7Q:{     {
,c4lI#|X/d!G`"e         echo 'Parent called';UKQ KNGx\:g-ZO
    }{ quixk F9xG
}
Aw+J*O3J6M class b*_&_&d6jS]m^*e
{
A1t(eX-xA,x     function b()8}2B-S T$Qq
    {
5J L#@PGO6zU.u     }#n2Xv,UG:fX y
}LkO}B_#D)z+VG&kH7W
$c = new b();
G^8\8|8}W.t ?>[/code]A.Parent calledm5Ym-x,g9t"Y:r
B.一个错误|WpE Y$w;l~
C.一个警告
X,v7Zryi:]:Z2E _ D.什么都没有
1u h2AO.y8PPG
HG4ao gA]7lto
#ugo1Tgf.Tj af&h#GM\(K \
答案速查
/xa Zx"X3LOp 1.类
P ]5V*@B 2.BCD
!F9Ap,Z,bQ 3.C fej6Q.]
4.C
5Ik? [&xi-u Z%vm 5.A
4p\$H:mp8yb 6.C@-PR Z2Qu&F:F z
7.CG"z&v7W!y^
8.C8VwN x,A9N%E t G-Wn,|,Ng
9.D
1o\&DRf"^R'n 10.B
9IuUl-I#oF5J1I 11.D
(VprRez y 12.B
n]d#am?+P 13.A
T*UaJ-W[a 14.D)t7J&p&W,rqp!v/o
15.A"_-y,z)VY:dy
16.B;]L!ed/x
17.A
E?~W l%q3Z 18.D
X&r%so\4z2{ g 19.设计模式
/Po&L;U8Y.^.}I 20.D n'm%g!yGu4bW
M%^MS&Sc
#xrr)r5`D

(Js R}e&T 答案详解e+Q1}iZF
W;zk:{/@(s3N L%oS?,|
1.类是对象的蓝图(对象是类的实例)。O pO%H,wR1^#e1f

:\X/d.om B 2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。qNS-R;J-no7|kN

DRyd/S4@1O1E 3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。R{8z.i6h(z!@w
`xk"^ w8O4I
4.单件模式可以限制一个类被实例化的次数。
.d,D6NM&kO |;Q5x|,D
#T,zO N kb3[Y%X'u} 5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
q*xrF[/i#r w9deQ.B9zw Ja tp {
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。U{#V/Tr n/Q

7iWzQ1pE,I 7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。%c Ze+s2p XT3e

6j-l;se z 8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。EG8\2u)e(Q}}

gwFI;~B/t'H 9.PHP4中没有题目选项里所列的任何一个概念。答案是D。'U2U7UY{K M/lI
[cS I$A$eKF'p
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
:C;VdZ&A6l'Bj 6X}*D:j e `0l)Y
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。Y.hV6J Px@{n
pyi{B:X'W~
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。(Qk(uht Z.|

MF X1U(\@h 13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
|:C$n? kLR K} Y]$TQ,FN${
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
4AYg-Wz-L Y 回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:2_ I0~&x%Q\-J
    function reduce_fraction(&$fraction)
Ru*j5z X'O 答案是D。
2v#d8h"r*W!TN Cy ^!I!P 2u1aKq8?}(eS/u
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
U#b3w5PH vV k /]b.}!O's
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
K8l eH;}!W[ v0HLo6V eZ s"iv
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
5J(x O}5mc[5s@
(}vW H*X&}%N1Gp 18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。#j+J$Q%A3TR!c
l.Wu1]Hfq7W
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
.`epF1b_df o?)?(\\.^
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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