  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14191
- 金币
- 2386
- 威望
- 1647
- 贡献
- 1334
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
: K- ]* H4 G$ E& i/ M; f4 W! _% GPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
2 C. C( S* e' |9 R# J本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
% [# q8 J' V( ?& ^$ A' d
$ m# K+ [9 y m3 R7 d7 Q/ [问题
! y6 p. Q' B5 T. P; F# [* q4 s, l, _* ]0 s+ `# `
1.对象的蓝图是什么?' H$ V/ A# d& B0 A2 [
* O* ~8 o( w! v5 f答案:____________
7 p+ ^5 e8 e: M! j3 v+ b0 ]( {1 \$ F# t0 h" Y
" q9 {" q; K5 N3 J0 k2 F2.以下代码执行后,数组$a->my_value中储存的值是什么?(三选)-
- <?php
- class my_class
- {
- var $my_value = array();
- function my_class ($value)
- {
- $this->my_value[] = $value;
- }
- function set_value ($value)
- {
- $this->$my_value = $value;
- }
- }
- $a = new my_class ('a');
- $a->my_value[] = 'b';
- $a->set_value ('c');
- $a->my_class('d');
- ?>
复制代码 A.c; u8 q! x" k7 O, i. Y
B.b/ _/ X) p- ?- E
C.a
5 t9 g: v! r. E1 m7 \9 TD.d' L ~3 }, ^2 c1 W! H
E.e
" C4 _) s1 \6 B# i2 a( N% v* a5 ]8 O2 z* R! Y$ \7 F$ ]/ @5 o2 `
. v; O( t' F+ `/ F6 B- E1 i3.如何让类中的某些方法无法在类的外部被访问? G* H% ~# K; S- t
5 U/ L3 u o. T1 }- B
A.把类声明为private
) |: D' t; K1 J- ~; wB.把方法声明为private8 o# n: w1 S; u* \. p3 }" o
C.无法实现
7 H8 V$ G4 ^4 c+ N( l( P* hD.编写合适的重载方法(overloading method)
$ R1 ]: e% I& v( U9 [+ G
" r1 ? e4 ]7 V: ^% v* R- a% H7 u% u' V6 N+ U, t
4.哪种OOP设计模式能让类在整个脚本里只实例化一次? ~- u' A. G: P3 w6 G5 {
% C: |0 K. X& I1 a- e s/ _A.MVC模式* I6 N6 G& O8 d3 }
B.抽象工厂模式(Abstract factory)
' k* ~6 l' e8 T9 E6 XC.单件模式(Singleton)
8 B8 G! a( X; E( M7 TD.代理模式(Proxy)9 a5 B* f/ q- {$ Q9 h1 n f
E.状态模式(State)
, s# g" x: X7 w( F `* L
# X8 R, k9 K/ G$ s5 r' R j% d3 ?1 @
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?5 q: @1 L4 E3 e4 ?
" q, n5 w" Z( z# b' @
A.1个8 {* I, F0 G9 n$ S$ f
B.2个
. w, Q1 V6 y$ l: o8 v, hC.取决于系统资源8 |4 Z7 R3 p; F3 A% ^" h/ z
D.3个
9 \2 k+ N2 |0 ^: x0 UE.想要几个有几个$ L2 s% D& | |
' p* }4 q! x7 @
' _2 b: n# m" A3 a* l: Z6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承' O* W8 O3 O) v' j+ n' n3 e( ?
B.接口( U) p+ ~( q ^
C.抽象方法: ^: P3 t: H* m; t
D.Private方法
2 y) d: S& H, Y( r2 @5 {E.函数重载(function overloading)
3 q: v+ Q2 z+ x7 j" l; { G1 P6 Y( t) D# S/ `& e
. e; h& G3 F7 _5 f7 I9 n$ n# ]7.假设定义了一个testclass类,它的构造函数的函数名是什么?
! W# k. [/ C- n/ e5 `* z
5 \0 v6 X* a$ @5 J: sA.__construct& R# O1 O8 i' Q5 Y
B.initialize
. B2 R. J! w6 a2 I: {* yC.testclass
7 L( |: O1 p: ^, ^D.__testclass
- D, V3 N2 R' X" X5 T: vE.只有PHP5才支持构造函数' b/ a, R- s" W3 r5 b% i; n+ ~
d2 b8 x" s0 A7 v4 u
( k9 r* C$ z( r1 W* {& u/ l9 J$ V0 U U8.一个类如何覆盖默认的序列化机制?( p$ V4 F$ T: ~- `
4 @/ e5 |$ c+ F% n+ G- x8 C. SA.使用__shutdown和__startup方法" L5 u( I9 v; k }3 ]" T- T& P
B.调用register_shutdown_function()函数# L2 P, q6 U$ N
C.使用__sleep()和__wakeup()方法
% L* O3 e, s. {2 u& L" p. QD.无法覆盖默认序列化机制
5 E. n7 \ T! ?# A# v8 N rE.使用ob_start()将类放入输出缓冲中' A- [9 r# [' P! |; s7 ^
8 }' w. W2 j3 x$ U5 A! K
. }( I4 f+ u( j; k: M; `# e% N9.以下哪些面向对象的概念无法在PHP4中实现?) q4 m3 b. z( C* U* F. _" I
7 n4 `. G8 b7 c@抽象类* A# o, Z4 ]) e( N7 q% y
@Final类4 C1 c9 P/ D9 J/ ~4 F3 l
@Public、private、protected(PPP)方法
; D0 z1 I H6 f' R W@接口8 B7 v1 P, U: ^. P) u5 E% J' t
. t# O+ C5 N6 X/ V
A.抽象类
" t0 U6 a' u# W- Y4 k2 LB.PPP方法/ R1 y& S( d- m
C.PPP方法和接口% w+ _0 w- Q' X3 R9 P0 x' m* T! D
D.以上所有都不可用
1 e7 e& K H, _3 X$ r2 yE.以上所有都可用" d- N w+ S% K& I
; m* z5 T( n6 P- }; A
" F3 L$ V* r3 m3 O10.如何在类的内部调用mymethod方法?
5 E) D1 Y A8 N% x" b: z6 u. q# _* C3 g c- K
A.$self=>mymethod();
( V8 a4 B# ]2 T" r2 n! h: T7 _B.$this->mymethod();+ d( U2 v2 u) i6 ^
C.$current->mymethod();
/ ~6 l( {4 V% {' |/ DD.$this::mymethod()4 Z. y+ a& T) U. _2 A7 |% o+ W
E.以上都不对
4 i6 ~8 G1 _; F
( q& ~9 E' c; }$ y8 f
; U J1 y7 e% I8 V11.以下脚本输出什么?-
- <?php
- class my_class
- {
- var $my_var;
- function _my_class ($value)
- {
- $this->my_var = $value;
- }
- }
- $a = new my_class (10);
- echo $a->my_var;
- ?>
复制代码 A.108 z; P0 p2 X. F
B.Null
$ h/ Q* @, @. f; u: y5 s- wC.Empty
' ^! K7 ]" b, B0 H+ [D.什么都没有4 J8 M5 G0 d! A4 y
E.一个错误
/ m' f& d! }5 S" w3 l: H o5 |& r9 f9 H6 ?& I& y
- n2 }+ @- t8 d0 }) r! @
12.以下脚本输出什么?-
- <?php
- class my_class
- {
- var $value;
- }
- $a = new my_class;
- $a->my_value = 5;
- $b = $a;
- $b->my_value = 10;
- echo $a->my_value;
- ?>
复制代码 A.10
( l5 f X! ?6 [7 {; VB.5- ?! S z* p. p$ u3 F' z
C.2
. A. W4 f [% v) XD.Null6 \$ ^3 X% M# k
E.什么都没有- Q; H$ E/ k$ ?( u( I
3 i# G- G: e+ z: \( X3 _- p
$ H. C J# J5 s% n! m
13.以下脚本输出什么?-
- <?php
- $global_obj = null;
- class my_class
- {
- var $value;
- function my_class()
- {
- global $global_obj;
- $global_obj = &$this;
- }
- }
- $a = new my_class;
- $a->my_value = 5;
- $global_obj->my_value = 10;
- echo $a->my_value;
- ?>
复制代码 A.5/ ^, |. ~4 n+ U' C, B. M
B.10
- f7 g+ P# F' ~C.什么都没有( J2 x3 i9 Y( G5 g
D.构造函数将报错
" G. }6 S# W0 s0 S# W1 O* CE.5101 @9 O5 Y! l; c$ a7 c/ U
7 k8 _7 t7 [3 p. w" l, {
' h3 C7 W1 I8 x- t0 Y
14.考虑如下一段代码,执行时,$eight_tenths->to_string方法返回的字符串是8/10而不是希望的4/5,为什么?-
- <?php
- class fraction {
- var $numerator;
- var $denominator;
- function fraction($n, $d) {
- $this->set_numerator($n);
- $this->set_denominator($d);
- }
- function set_numerator($num) {
- $this->numerator = (int)$num;
- }
- function set_denominator($num) {
- $this->denominator = (int)$num;
- }
- function to_string() {
- return "{$this->numerator} / {$this->denominator}";
- }
- }
- function gcd($a, $b) {
- return ($b > 0) ? gcd($b, $a % $b) : $a;
- }
- function reduce_fraction($fraction) {
- $gcd = gcd($fraction->numerator,
- $fraction->denominator);
- $fraction->numerator /= $gcd;
- $fraction->denominator /= $gcd;
- }
- $eight_tenths = new fraction(8,10);
- /* Reduce the fraction */
- reduce_fraction($eight_tenths);
- var_dump($eight_tenths->to_string());
- ?>
复制代码 A.reduce_fraction函数必须返回一个值
& z7 Q2 d6 d2 m* @& u% A+ VB.reduce_fraction函数必须接受一个整型值! t1 e4 q. E2 _: f# a+ ]
C.gcd函数有问题
3 b$ o* k# E. [8 C5 r0 \D.必须通过引用的方式传递$eight_tenths对象) R. _; S$ I: v# \
E.对象的实例不能传递给方法以外的其他结构。
# l( \$ L9 M* @ E9 i6 y3 O5 f1 V7 j& a9 |
0 e! b' O2 j. A" |% [& X: {, B15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
5 n& [; r6 S, d) w/ O" DB.生成myclass的实例并调用mymethod方法* h& s( L$ M$ k! W! E; I9 I
C.产生一个语法错误
( e3 K: r, a5 pD.默认myclass类最后被创建出的实例并调用mymethod()# f- f, j! [9 k4 a7 T: Q9 \' C
E.调用名为myclass::mymethod()的函数/ [- v) ]+ X2 ?% u. g
* W& ]2 [% Y6 c9 j) |% A$ v
" K, L" V6 @/ S1 k: ]6 T9 Y
16.PHP中有静态类变量吗?* I: u. ?, b' e; v
7 a& N. x; n4 i- y# R
A.有1 k8 g: C0 h$ L( k
B.没有
9 E- G4 j! f! P; b' E; \* l7 K" c- [3 i4 i6 c
7 e! o8 V" ~( b1 W( F. [
17.以下脚本输出什么?-
- <?php
- class a
- {
- function a ($x = 1)
- {
- $this->myvar = $x;
- }
- }
- class b extends a
- {
- var $myvar;
- function b ($x = 2)
- {
- $this->myvar = $x;
- parent::a();
- }
- }
- $obj = new b;
- echo $obj->myvar;
- ?>
复制代码 A.1' D$ z; v+ f2 N
B.2
* ~; ?5 O* N$ l6 MC.一个错误,因为没有定义a::$myvar
4 x" B r4 |2 T5 d# x& j" ^5 k( Z' fD.一个警告,因为没有定义a::$myvar) v( x# N% b8 E$ X
E.什么都没有
* L I3 D! ^3 E8 ~7 c" r6 }, ^) N+ I8 L3 t6 a2 U
6 N7 T0 g6 k8 Z# s! k8 ?18.如何即时加载一个类?+ U. y6 b5 _5 K( R1 f4 j' a
; Q0 Q+ L# E) r" \! L
A.使用__autoload魔术函数" T% q& c- c% Q6 P e$ d2 P8 e
B.把它们定义为forward类
' z" @1 m) ]3 ?3 GC.实现一个特殊的错误处理手段
b9 L9 I9 h) Q* D: T$ [D.不可能
' d3 s$ X. [ A0 w% B. o4 `" B9 {E.用有条件限制的include来包含它们
, v1 l/ I% P$ B. ?) _4 F
/ e6 `- a/ H5 H1 [
1 F, V* o! L2 a/ w- l8 l0 U& @% n, E19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?! b# M$ ~# r6 W5 X
1 `! Y4 N' s8 l/ I; x& Y N 答案:__________7 x0 k( L: b$ b2 I
/ C4 j6 G2 G- `/ l
7 U- G3 x w4 W# }$ r8 [1 X20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
! \4 `/ B( [) z2 P/ qB.一个错误
v4 Y0 C: x3 f- {4 j9 T0 DC.一个警告
: k- J5 v D8 W: ]" ?0 FD.什么都没有
4 ]4 i8 S9 a3 ]/ a9 u" m2 a, \# r. z. j6 Z7 Q8 A4 Y& d3 @
# J1 Z( I: I7 T% i; [. T2 A3 ?
# m1 u/ @ n8 u X0 e0 d
答案速查 X( N8 r1 i* k& P/ N2 u
1.类
$ p0 b1 k( \( T8 Z1 e, [9 [( p4 F' i2.BCD
8 J5 g. @6 r) ^3.C
, M% v- b% x- u3 _4.C0 Z9 V' |: m- Y; j# B3 g
5.A" j& M$ y1 c6 _) w! J2 n8 ?
6.C& T4 H# |' f4 N
7.C' b& B) R( G2 a% H, E9 u! T8 h
8.C; ? ~/ v- t6 P2 L2 H
9.D
$ [1 z+ L8 K1 ?$ I1 ~10.B# W+ X0 x6 }2 l7 B' h8 N: t
11.D$ I' r v& k8 ]4 ^, q2 T/ p
12.B0 M6 M) y+ \' {
13.A
8 W; [: W! P' n* {14.D, T) x7 [3 q5 A7 e, T5 S
15.A
% w4 m) z: d( y, _( ]5 v, `16.B
6 p w$ s5 v/ ^% L/ B$ I) q* A17.A: P* q8 i- g Y7 p6 d$ a+ j
18.D8 ~! {, y" `- e, Y! F4 c1 n
19.设计模式
$ |0 G( {! M' j V3 A20.D% W% f$ A! ] u! w6 c
4 ^# v& K p# M+ k
& R4 L! c5 u8 w* e' R+ I9 R
- S8 H$ _0 S7 r9 b) k7 j答案详解
. j* E) f5 k5 z" P0 n4 f, F; T
n% _ M& E, C2 Q: K# k+ H1.类是对象的蓝图(对象是类的实例)。) x. ~* c! M% t+ F$ u% P! s9 i
7 J' y z8 e# b0 X# C2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。( |- a& u+ {7 L' s
0 k% r7 n# x# Z8 G/ j ?: a; R5 e
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。4 T B5 e4 h5 p) j
" w; w1 U: B9 V; c, J. |6 o! s
4.单件模式可以限制一个类被实例化的次数。( V8 t- b1 Q0 f- a% { y
% w# Q2 d2 T% f2 f0 E+ g5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
3 D" V8 J& o* J$ ~2 J2 n& c
4 w+ u$ _# a3 G5 e* m, _% X$ i6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
( f" f3 G# O4 l$ U$ X( o3 V
# G+ H6 t$ R7 p1 Y7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。! M. A; ~1 H9 n5 U
" k( J5 Q( l1 a0 d
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
8 m! S+ t" {7 N* G7 D6 R7 l# k$ |$ \: F4 s
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
6 e6 a8 T* [6 c0 x% W" g) e# @9 @; ~) C8 [
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。 k; \5 e5 I# A/ m* X* Y0 [
% D1 K# s* n' |& d! j11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
/ U) ]7 W. y1 Y) [ m* ^% ]* d! V' V
# Y" ?( G( r# A& d12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。. v$ M7 V4 n5 x' ]. u1 I
1 z- u3 e0 i0 Z8 w0 y/ `13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
% ?9 G1 n* w9 r( ?4 w1 U" g" o) d# ^
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。# M8 C8 W5 ^; y$ F, g, i: H( j; ~6 Z$ M
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
- H( S/ X6 K# m0 X function reduce_fraction(&$fraction)! X+ {9 t# u4 l# i5 \7 ?
答案是D。
/ L+ C1 h6 \, E+ u, Z) N7 o3 G [. v0 @/ I3 y8 q* z: r
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。% h* M v& L: n% L3 d4 n
( d& l% Z) m1 _' M( }# x8 Y2 E16.没有。PHP4只允许声明静态函数变量,没有静态类变量。7 A Y u1 f7 g6 {- z0 f- o
& o- x& B" Q7 z, G; ]% i
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。0 F2 {6 n+ g$ E: [" }
1 {/ q" R4 J; s. F18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。1 ]9 L3 M6 @% A. W5 Y5 k2 N
: }$ [8 n' w$ ^! L& j% }3 a% C
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
+ o& n9 I8 i( }$ G7 _- I
; v) x0 f" X$ `% D3 p20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|