捌玖网络工作室's Archiver

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

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

尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
@ W9O5c:H g;Up3` PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
!Gm#n-`5`4z 本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
*E'c-T\,IB
^#k{I |,c&h,c5e 问题 \3C2|+BK8H.iIIU

b C0i5Ey&q$jp 1.对象的蓝图是什么?
'tL[-R+i 5M3l;z/m_U
答案:____________
mE,UG&Ao g!h(rG~yw

,q%[2Jb"D'p5jG^ 2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)[code] ~;t{+~+B0o
<?php
\(}FJ7jw` class my_class
"o h2Wr1\z;u {c9hM!i`[
    var $my_value = array();
_KO9~4kfa6E     function my_class ($value)
D-eN~:x     {5uc{gdp"n$W B
        $this->my_value[] = $value;!|ys!Ke/g*GR1C
    }
_,@)o~Bt#a}L(J     function set_value ($value)
JnLM,K,t#i&M~%\     {6XpiGW[TxO
        $this->$my_value = $value;M[/U I.J4w$y$@
    }/R2]UiWB
} F,zl!AfQl*RU
$a = new my_class ('a');G9yE(NI;Cde-E
$a->my_value[] = 'b';
)_t9s7v!nuG@ g"v $a->set_value ('c');
&pa[8DvAqZCs $a->my_class('d');
2f ~:gs ^$Y ?>[/code]A.cmov?:E/`'I M6O/|&c
B.b
1E!EZ Cwf8Ks C.a
#d4bEn8S D.dPO'R0A!{!t&J
E.e1X1@'xaOr0u@
2I"^Mcibk{7n#s
`f _;`~9s{_[
3.如何让类中的某些方法无法在类的外部被访问? K/P5]$]9Jc8ZJM3l6?3l
{rK|(A+z%n"K,?
A.把类声明为privatef&Hr(NQ1K1Vm`
B.把方法声明为private
PD:L({)t?{LSx$F C.无法实现}V"o1{R.n
D.编写合适的重载方法(overloading method)
'mW:z {!i+M
XQs)P&S
XHR"Q\P 4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
Vj!ep)F4id"E \l F&I tX@y+EZ_E
A.MVC模式
Y2vp+|dL B.抽象工厂模式(Abstract factory);_!g6n z7U8b3?%v/`
C.单件模式(Singleton)j;R3N-|"`,t(E ^T
D.代理模式(Proxy)
%r'XL b9S$~ E.状态模式(State) h;H P@U(a.DQ rU3S
A OHA C-Ui9a
N+} B)r YC#a
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
#u!GR;N u0Y|)[ 1H$c"z(fW}
A.1个
6Gf"z?2{x B.2个"md'b1@ iRW"Bi
C.取决于系统资源
9le*To? H'mrb D.3个U,z VJ y["X
E.想要几个有几个b&hNP3wt3o/H

@k"znwPe0^ (E|"S|F&o7o sI
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?[code]
2C NrX"w`mg7Y <?php
p2Z1@6i+m4B class my_classaI/])r8w'S
{
%O5`{#n ]+T W!^v     function my_funct ($my_param)
1}`7`8H \ q {.j_     {.kCn&B\,Lc
        user_error ("Please define me", E_ERROR);ct1es)Ie \
    }
x4U&RBhG     function b()t$N8^ Vues-r5[:n }5k6Y
    {7c)Y*|o&T"d,B,|
        return 10;["Iq5W p_F1m&IP
    }
.O&t/G2C)@8G,x qI }
4e}(Pt.iN ?>[/code]A.多重继承
E |j+f4x3sWfB'a B.接口
q PP-j,][V Dv C.抽象方法
{)d x$\0lu&B D.Private方法0SF/|#YYa.G C.{1G
E.函数重载(function overloading)"L+Kv7D9y"de8C0I.H\
~kO]'YDV$M

%UU(f(AtX 7.假设定义了一个testclass类,它的构造函数的函数名是什么?yX(C&z^Gy

[J0e qTn6}z$p(~ A.__construct
IAW3f}'d.O0F6C B.initialize
-}Z"\oU&M I C.testclass
9yS U2G%o_*c;O D.__testclass
;qsl*Y8kU ?i E.只有PHP5才支持构造函数0Q e#F*b'L(dom6@y
j0yIk(A

)i z/o&w{9x&mK6`6S 8.一个类如何覆盖默认的序列化机制?
*@Y)Jg6Q;\W
U:Z9lp&_mR A.使用__shutdown和__startup方法
&]{"Dbb zYcQ B.调用register_shutdown_function()函数x ib2}cgy\/z[,_
C.使用__sleep()和__wakeup()方法
)d;D8Wu r7u D.无法覆盖默认序列化机制
.p4e_%[c'D:S E.使用ob_start()将类放入输出缓冲中
LzP\Yd (?:x N5dr"\(_#Z;Zp
zG d[Nk0Fce
9.以下哪些面向对象的概念无法在PHP4中实现? P(?/d }'lK

jD rET6^,f @抽象类}9H]X0A
@Final类
%Nh:DjxZP5ry3q'yu @Public、private、protected(PPP)方法.D7q1TkLI v7[
@接口;ku R.Voj c9] H
o(d lm*a,T
A.抽象类sUt2l([m
B.PPP方法
)ye3v;Bj:v*c \ C.PPP方法和接口
M^%|6x n{ zbL D.以上所有都不可用BRLF1h%}
E.以上所有都可用LBfXOE \ O

x6H(~B c 3q r8BI"pa}
10.如何在类的内部调用mymethod方法?*\LQPae
a)s+Ib"D;e f ~&hxt
A.$self=>mymethod();,NK3Ay)A-x_
B.$this->mymethod();3},na&~?P
C.$current->mymethod();
S }!J CH)s2u D.$this::mymethod()
{iC!A^ E.以上都不对{:`p)pj:J#f
R;Wn.|XO0Xvi
)xo+v#GN7Jk wn
11.以下脚本输出什么?[code] 1H5|/g[j BN5?
<?php+AduT-d9r,V J{$?3I
class my_classL3CE7g e
{
l6M+k0bjX},e k     var $my_var;
i_#]_@ z8wfX     function _my_class ($value)
1if4xZu~!Aoq ElW     {Y1C%F&[(lW E
        $this->my_var = $value;#AU Ffuk&cbw
    }
,t"CvXp-U9x })q!\)u a0A
$a = new my_class (10);6Kk0W K2Rd m
echo $a->my_var;x)c:G"Q.w
?>[/code]A.10'T9o)\_|eE(c(n
B.Null
m E$Eg Y v C.EmptyN g7Z0A9^ k1vGc
D.什么都没有
h3F"f8}ER Z E.一个错误
e\/o:q4q/Q M9D7Z6M {)e^w\3Mr
'fEH8VG%V5T_G
12.以下脚本输出什么?[code]
LI(CWl4jcIE <?php&p,M0{2c"~r
class my_class d,rGB}
{dx%a/ra.p9W`3dH~
    var $value;
} O#M*di~ }
3{TkeVL)p0P $a = new my_class;?$QXqP G9h:eD
$a->my_value = 5;
:p+Q"g+C}!b $b = $a;+k/T?@%@J"Cx_
$b->my_value = 10;gyN pM
echo $a->my_value;
a$i'Fq]|'W/vD)BV ?>[/code]A.10B nc~ Q.s/`K1UP
B.5
Y#Q7Jg ],eyS C.2
4LD)CT C Emy-B D.Null+AYUQ?J1J%ij1J
E.什么都没有 p M2{5uf*o-E
6_ k7[]+K!H'Z
p8F~#S$\ g
13.以下脚本输出什么?[code] 3xAR4r`/`C
<?php
-[F&qm'` $global_obj = null;H~P$I+SeY4BF
class my_class
a {&]]Sf(af {
&?Rf_0S+P2Ln     var $value;
dr;IDN'tsUu Hv/q     function my_class()
.rUQ_By6|5N     {
6sn N ~!ia         global $global_obj;tUKd5o)Jk*H.E
        $global_obj = &$this;5i!v/Z5qA#@]
    }.c1oRq1L1V
}
V'j6C&z9Aok e/E $a = new my_class;
CcD5S'dbE{'pu $a->my_value = 5;
%\ZQ:`/Gv2B $global_obj->my_value = 10;^z,{ rI+[(^5|
echo $a->my_value;I`5XO!Z;i9W j,~4{
?>[/code]A.5
!V nR-ph3j8chw7~9Z B.10
@NEl+tn S'gF C.什么都没有
"s_(V |X D.构造函数将报错
i!tC(D+a[HxV:Np E.510
%l,_ vz!q-D6UE pi7XztB F`:` @S
-sr HM W I\C
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?[code]
F n6Y&ug-DX*f <?php
)?.x@*d/vA$KE]K class fraction {
lH1W ` `&ivG     var $numerator;'A_ z+\!Db(aY
    var $denominator;t*e%R(F6O+{
    function fraction($n, $d) {@{+w'P Am-g{@
        $this->set_numerator($n);4tmd1?.} X#c X
        $this->set_denominator($d);A.bcEGC2I;L
    }
F"h%j1DY6o1Aj     function set_numerator($num) {5F-{&mZh&d,w r\^;w
        $this->numerator = (int)$num;
CO9aHc6OJ     }(]5D/N-v%s7INK(f
    function set_denominator($num) {
j-fw.Oi         $this->denominator = (int)$num;.\ V ^ ?En r_
    } uew/|*^J
    function to_string() {4|,Pi Zm
        return "{$this->numerator} / {$this->denominator}";cH0Ib$VV G
    }
e*|S o7\C }7t8]?a1g7RY ^
function gcd($a, $b) {@a!D+E\)O
    return ($b > 0) ? gcd($b, $a % $b) : $a;
\P*u|E&{ Du }$K/ayP?%fm hT{
function reduce_fraction($fraction) {
-R udqjM6`5]     $gcd = gcd($fraction->numerator, c)W }r1vA"U2? d
    $fraction->denominator); u@1[Pc NHuWW"^I
    $fraction->numerator /= $gcd;,rvVJ7{ No ~ k
    $fraction->denominator /= $gcd;_Y{]`Va
}
;w @Pp*e'Ed $eight_tenths = new fraction(8,10);
S/A{ C5p UB%Y:F$D /* Reduce the fraction */
KtH3~jeeUe reduce_fraction($eight_tenths);LYqGV6p6[.dx
var_dump($eight_tenths->to_string());]O`z7@(A|
?>[/code]A.reduce_fraction函数必须返回一个值
6b2f*f;}o'gi B.reduce_fraction函数必须接受一个整型值
0A|8dZ9n(|2} C.gcd函数有问题
v Pk`X3C*jw D.必须通过引用的方式传递$eight_tenths对象
sfV8~I(c^t3es E.对象的实例不能传递给方法以外的其他结构。
(zz*r%x'j C P\R &n6[2N:Rh
dT2eW0O0qrK
15.以下代码是做什么的?[code] +]%t!S/o-kQI#u
<?php
&VNLP [N;sWf require_once("myclass.php");
/P6Y}][ myclass::mymethod();
FX;bd!{5v ?>[/code]A.静态调用mymethod方法8R"o`EtBy-?9d
B.生成myclass的实例并调用mymethod方法
RG*U{MNq C.产生一个语法错误$Ug:P_&t3D9t
D.默认myclass类最后被创建出的实例并调用mymethod()
CZ3WM8\h5|?;t%U E.调用名为myclass::mymethod()的函数-n)[%fln;Y i
!D9~2Plt \\

}$cXJ1X ZKq 16.PHP中有静态类变量吗? ?6?.s:M b})_
"ML2gl+GH oZ
A.有 UB"R2?f!B$Ly.BI
B.没有
n Z$Kj z/h *} JY1O?Q

k3S-DW4lm jS.I 17.以下脚本输出什么?[code] 8o7~*RA z*rR~
<?php+c p1h4N:b7oxr
class a
2e:CG \|1t b {#WU `)?C;K!G2Yk
    function a ($x = 1)
8O| x!z+a     {g,pu&rN-i
        $this->myvar = $x;
,XZ(]b%d1jt     }5gt}7am?,o T9s
}
)Cy$UL^4~ class b extends a
aY9J!Z4i&@E(?A {Z @|X f:VbE$V
    var $myvar;R:Y8o5X(g[8x4yw
    function b ($x = 2)6{n*@l9yQ
    {XB#T;gpe:uym6l4c^
        $this->myvar = $x;
3kk"c~s9|y`7l9O3U         parent::a();
3^c {;Q&P     }QA$z:y$~'b'E
}
V'\B O]K ~"O $obj = new b;Jg(s{,xn#s
echo $obj->myvar;
"mykaAuF@aN ?>[/code]A.1
/b.u-N\*fsW B.2uLx.Thf d
C.一个错误,因为没有定义a::$myvar
J6Yyk3N5SO D.一个警告,因为没有定义a::$myvar{'X v:}'W,^F
E.什么都没有
4n ^Fu0X7j0@
7`+CY'L9[7w)]&X
(_ O%ulW8@!x+IG_ 18.如何即时加载一个类?G/N\E0c#rh*EJZD
G4g3Gj$wF4M1W4{E
A.使用__autoload魔术函数
AQ@L Zw$z)UGK3E B.把它们定义为forward类)P_L3zQ
C.实现一个特殊的错误处理手段
;sId CQjl D.不可能 FYW[K%pe}{"?
E.用有条件限制的include来包含它们({!WZvK

2S-A4Y c \.F U3K]JB+?;Lx
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
{$QD'pco S *{;Q4gKe4r
    答案:__________
{;Ix&EM-n-w
h3N!MI~ 9mc7|T/N'ck [
20.以下脚本输出什么?[code] F t?t/|}
<?php
d.Zje ~ i)},Xd class a
w _"Pp8^ {-R WOL| U e5s-d@)o&};\
    function a()$~2xa.m$r g y9u8?Q])~
    {
@v7x&T5w?         echo 'Parent called';
B?"M9Ey     }
P ^M8B4@W(O1Y*H*@ G }
? hKw9\t class b
'z n6[s9FZC | {
'KC'\s:@#f     function b()
"PW:qSg}qJ     {#|9v cve6zn-F
    }+X"zmTAZ
}
v$h x/qH[SG $c = new b();H6cXFq&q`wxF
?>[/code]A.Parent called
!H2w6D ~ZD Y1g B.一个错误
T BZO]3tJ$W,o&T C.一个警告
s#|] A"G \l D.什么都没有"tx~j4D

"]j%t? M0G p%T
.EH8^#}:jEO{
1k i Qlxs5\ uV L[ 答案速查]$QW\6^2m2Y_ V&G
1.类_"I.NUW8Z5?:Rq9D&d
2.BCD
3g'yw1e }|"p\2{ 3.C
3T#s"J q;D9tXU 4.C*Ht,L s0Ja
5.A
Hr.gUJ;y1Er 6.Cp-Lw\ Kj
7.C
#a^1yi"T/^'{jun 8.C)s&k-Xsj1r8w7F
9.D
lg4q0f z3OcU 10.B:YW#~1k7y_,Df
11.D4CeC \4p$Y
12.B3yz QQ%L Yo/s
13.A
M(yE N+U&Q-D 14.DhU:|?({8j#z AMYG}
15.A
Lt]W4|+].PqlE P 16.B
}%?5| fO y e-C9`*y 17.A
9[fa8KQ'{$zUI0vH C 18.D,hLdA#z
19.设计模式
^*IM0p1I\ 20.D
'h;a+K/De3T b f{w,|$CD;ll
"xV2Q.L9pG!TqA

-r2fQgDq$^3f-TW 答案详解
k+Q&sWC*{ _ z] d4X0[zX
1.类是对象的蓝图(对象是类的实例)。xl1yo'Bv z`2xQ

5~%c!R[pZ7c 2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。fSx9L#OuO
;N4p0C^6r
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
QqI5m,[+UU9c$a9e Q)}_-sm2I
4.单件模式可以限制一个类被实例化的次数。l$n9Yo P7BQ4a*HzE
fHD/QE0Pi#iA7@
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。U}dk&H4a4l

b%g;~*O@Q|b 6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
x2PWYB3G
@ d,m$kr.]h 7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。l$H E5Z~!v`
4vql$EbL}A
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。9m,fw'oNr'Ro

){%db,Lo6q:V+F 9.PHP4中没有题目选项里所列的任何一个概念。答案是D。PF(MU.\&v+X
Oq/SAD$K?N.]*y{
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
G*thm G
@:|%x3`0LBtEb 11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
\\FWJx[ -ju/l_S0C]b
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。hBrYe
o7B)Ln sZR`P
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。_/\oF~9uQMN

8Vh\D7RkSX 14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
f,\#K]B3jZ 回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
p-|7Lup6D5T     function reduce_fraction(&$fraction)atIsB2V
答案是D。
$\V)_%A L;L"g y/lN ~;_V&FFX+]7}
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。3},vj-Jd+Q `)x[o^

L)AQ(`/g 16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
"U"yZ a(PW,\ z v&e&_1`+Y7r(b)r$[
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0qQs4}8v"J!iA
w-cVPU7_ 18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。3F+Gj)d,w9t E

YH6U)IM\ 19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
K8?:{'M{6{7nI
~H7G"yt 20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。

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


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