  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14171
- 金币
- 2376
- 威望
- 1647
- 贡献
- 1324
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。" V' N1 @6 E" q* N5 q1 k: f
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
* i. b7 j0 b* V. J0 V$ p本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
3 E: u3 t' t# N" w0 _- |6 s6 P: h* H' ]
问题5 H3 Y4 D X" _8 g6 J
8 b+ _; e' s% e5 q* e' K
1.对象的蓝图是什么?- A* S* c# q; x6 R! @9 r# q$ z4 `( j
8 T/ `1 U& }6 a: ^ Q
答案:____________6 }: O( D t. r' w8 [0 W, w7 Y
- T! A# _& \/ n5 U2 e
/ J; b' x1 \1 b1 ~( ^2.以下代码执行后,数组$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
$ ~2 a2 G4 ?6 U( \# }/ q: n CB.b
9 I6 g% W# e3 M# I* e$ O, A4 PC.a1 u2 ]% n% i& y& R
D.d! h3 _+ |) ]+ M3 r8 m: I5 z
E.e
7 O& z3 \+ t# v& L
- m9 X0 [- _ Y$ C* I/ o2 S
5 {+ Q; d0 V( U2 _' L* D+ T3.如何让类中的某些方法无法在类的外部被访问?
v9 _ t" m# K& D. w# Y4 M6 o; f
A.把类声明为private; Z$ Y: B6 t4 s' g* c, h& t
B.把方法声明为private
/ A2 h8 N1 p" L8 T1 U NC.无法实现& }2 x4 Q: r, r2 V3 R" Z- _, }$ k" ~
D.编写合适的重载方法(overloading method)
, U H- y- }- ?- S
' \* W! u9 @ }, W: M2 N9 S+ [; \( [8 E3 H1 |
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?5 i# G' j" g. p' o% `$ G/ I
( o3 B( x4 ?! ^2 i$ c, m/ |A.MVC模式% Q# ?* M- \/ i' K, n3 I- {
B.抽象工厂模式(Abstract factory)
* B6 c! v( t0 Q' P/ bC.单件模式(Singleton)
5 \+ P4 v! |" kD.代理模式(Proxy)1 h. U/ P5 x0 y& h- E5 r/ ^' H
E.状态模式(State)2 F% c1 n. |* l* J$ e' j7 c/ H
% i6 | F4 q7 c3 f3 o0 J0 i. X5 @
6 F6 G7 K, y2 j4 U- V7 D1 ]9 @5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
( }. q1 X# b( N. A f- _# n9 Z# B& x1 z- @3 O4 d3 F; r. ^
A.1个
! B, N+ S7 e* t8 o8 NB.2个5 s0 G- {0 f# f5 V) G% ~/ I0 H! W$ |
C.取决于系统资源7 K+ l4 a( s; |5 c; S, M
D.3个
$ A$ W* R& o& [7 _3 FE.想要几个有几个
* i8 B( M5 |* s h* `2 W, q/ T% }' b T! F9 l3 q
0 Q! c9 C0 y: T
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承7 p3 T- X, K: `& U: q1 w
B.接口
! U r/ \- e- n$ u0 JC.抽象方法( @& |8 t- j: r6 B! E8 V- e
D.Private方法! B: `/ U- C) |( D/ n
E.函数重载(function overloading)
- @$ |: i. a7 f7 a0 V
8 J) r# l* e2 u" B `: V( [: u* v
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
0 E' |8 z* k/ T$ L# r: I6 A7 M& S0 |5 G+ I% j0 |6 N$ I# c' ?
A.__construct; i# O. @. G2 N$ A; o( R
B.initialize
; n# x5 W1 W) ~5 jC.testclass
( O4 N$ B3 h6 [" j! ^. [D.__testclass3 H! U3 i! f* L- B# h4 [
E.只有PHP5才支持构造函数
7 b6 C6 D0 y) N7 N( L- k
- _- }2 g0 ^- l7 P8 c5 s/ Z
8 z+ h0 `* U# ^9 m, ^8.一个类如何覆盖默认的序列化机制?
5 z4 @% v5 D( Z a
/ x0 m7 k2 e9 H' `A.使用__shutdown和__startup方法
( ], E$ u- T8 n wB.调用register_shutdown_function()函数 E- Z7 J# K L. }6 C3 ?- Y [
C.使用__sleep()和__wakeup()方法
5 i u. H0 K4 z5 o2 t2 xD.无法覆盖默认序列化机制( z: j+ R: r, {
E.使用ob_start()将类放入输出缓冲中9 x" H# b Y V4 G( v& e
2 Z K# D9 Y* L, v
0 c8 \, J) F& [& y j( }$ |9 B9.以下哪些面向对象的概念无法在PHP4中实现?
; h; A$ ^0 R1 u4 z. j: q3 v+ j5 T& s& a5 H, D" h( k) f
@抽象类
/ V: J5 G9 k$ V1 [5 Q6 w0 M@Final类
: @" @/ @1 c P& x8 `& K@Public、private、protected(PPP)方法6 C7 ^, p/ n- b e9 l
@接口" D& w) j- c5 g2 u1 Q
1 J0 b9 |% L& M" E
A.抽象类/ }, O6 M* O0 ? [1 q$ y
B.PPP方法5 X+ k; r# E$ a d2 g7 c
C.PPP方法和接口
" d+ N2 y2 u G% ID.以上所有都不可用* `2 e+ c/ G0 R' ^3 w# p
E.以上所有都可用4 C1 S" X0 J8 |
) p+ A: ]* Y7 e2 A6 @7 K* J6 Q* _) X# }* ]
10.如何在类的内部调用mymethod方法?
. Y4 q1 f1 A1 c+ U+ F U
- R. \; m7 V4 }( y5 X5 e K4 rA.$self=>mymethod();. R5 l7 a2 D, u8 e1 z9 |
B.$this->mymethod();
# {( O- I! H. I3 _( KC.$current->mymethod();& q8 z+ l# x& A7 U
D.$this::mymethod()0 k- }. U; Q5 M6 L8 I3 s
E.以上都不对
/ |( r8 c3 ~* w$ w" }4 x$ q# g7 D! G4 G3 }8 J+ A+ F- F
% X) p5 K- [/ Y$ A4 D
11.以下脚本输出什么?-
- <?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.10; Q; S! Z! A5 }4 l, S: T/ o& ^
B.Null; Q* t s' o* y: K! I: P- K: S
C.Empty4 Q4 U! z9 P# e( z( p
D.什么都没有! X3 x8 a4 |* W/ s
E.一个错误, u! i+ \& u( G5 t
6 C; w' P; z5 O. f6 L( V F/ F, G( f. {/ h0 R' c k( M
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. v) `" \( z) s% [: @/ x
B.51 C" \4 K: Q) X6 {* q: _7 T
C.2
) S3 _& P+ L4 s9 c. KD.Null
" |- m8 ?6 D9 o% O& n1 D) ~+ C/ yE.什么都没有
* j: k$ u6 W% r5 z4 B1 Y6 U
0 s- l; i% ~4 H0 o* P
$ y u' n: a! n0 N# `8 |/ O13.以下脚本输出什么?-
- <?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
* m& Y' s. [3 F- oB.10
/ _6 U f1 q: p, eC.什么都没有
* J5 ~: C, C- `, |) B4 y: V* Z( x' oD.构造函数将报错3 f8 V* W X, H5 u
E.5107 J) {) R" s. {6 H
4 C( m* |* ^% h) K1 H
$ G( }* g. H2 Q+ G6 V
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函数必须返回一个值# r. B. }2 m; w8 e
B.reduce_fraction函数必须接受一个整型值
) f/ M, l9 D7 C* G4 m. f% QC.gcd函数有问题0 b6 {$ q: T5 ]" B/ p
D.必须通过引用的方式传递$eight_tenths对象
( _0 M( n/ |/ XE.对象的实例不能传递给方法以外的其他结构。$ }1 ]1 @& c% }* I0 z, M- Z
- E x. b2 l, J6 G' q7 m
3 P* d2 a6 f0 ^15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法/ I% a% c2 _5 A6 T' \
B.生成myclass的实例并调用mymethod方法
+ D, N( S* F$ m7 |2 {1 O1 BC.产生一个语法错误
k5 h6 k3 a+ u: d+ sD.默认myclass类最后被创建出的实例并调用mymethod()
0 \7 y5 G, m; [E.调用名为myclass::mymethod()的函数
+ W; ^: W+ ]6 f, C% @8 }* N8 T2 c! j* Q* ^* F5 u* Q# m) l3 }
: L- O( J( n* [0 {1 m16.PHP中有静态类变量吗?
/ ?/ F- r4 a. d. |
* Y8 y" u# c0 ]/ ~) H/ w0 m' }& [$ z1 ^A.有) O9 ~$ f, h0 i
B.没有0 ]. d" [* r3 V2 K j
2 N+ C2 `3 i5 h1 o7 w
, m0 F3 B% Q2 ` p; ~. c17.以下脚本输出什么?-
- <?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 ^1 d0 _3 t; z& E5 D4 P0 Z4 F
B.2 A! ~( \* H6 Q E4 e9 E
C.一个错误,因为没有定义a::$myvar
3 v% a/ _: f$ P5 B$ tD.一个警告,因为没有定义a::$myvar
8 G+ C# n! _5 V4 O- j9 NE.什么都没有4 Y3 H' e; d" z {% j1 w1 z1 `8 b/ h% ]
9 D8 R+ W1 }$ O+ d$ t( s: z9 y2 S, V' u, L# B. p3 M, q L4 s
18.如何即时加载一个类?
5 D+ a& F' T. u$ h# L
1 K( U( n3 ]- ZA.使用__autoload魔术函数 Q8 m4 a( n; q- v
B.把它们定义为forward类
( H2 E. F0 g& V5 i' h$ Q$ `0 U0 oC.实现一个特殊的错误处理手段- R0 K' p( m1 I$ d
D.不可能) S( c6 e$ r0 x. R Y
E.用有条件限制的include来包含它们
; f' S8 k% O" V/ z
, I7 L3 a5 y: o5 E: c/ L
9 v% c: \" l! q3 Q1 `) d19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
) B& v' c8 l! |* H" _; `2 ]9 t/ b
; [- Y. `5 j6 s( @ 答案:__________& L4 Y0 Y8 P: @& o
9 E4 X, P$ O4 G) u% r1 B
* J- r# w4 D/ i# j# q* r1 Z2 t/ x3 C& Y20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called/ _, Q4 B: X/ m) g1 z/ U
B.一个错误
@4 ]) q# i! ~0 M p# U% xC.一个警告
' B6 }; B0 j( T4 _3 V7 YD.什么都没有
( R" i- ]* t. M& [8 B+ a4 F0 z3 H0 n; S) }
5 R8 }, ^7 z$ \2 }% K( ]4 T% N) b3 l" C# y
答案速查
7 y+ s+ k0 G: _! `4 D. |1.类, M0 l5 C2 k) M& m7 I# B7 @$ y
2.BCD2 a: ?9 M: y; s
3.C% s6 T0 s- W5 o- l) U1 p
4.C4 u2 s" j5 e; P) e! P* |
5.A+ U- N+ Q& z1 n% v& k
6.C6 Y# @6 ]% s2 k& f# i
7.C0 S/ ^; Y$ @# h! R" J) W* o
8.C" ?+ @- {# t4 Q& K
9.D
5 p5 T' u( l8 {7 Y6 `6 E10.B8 G/ V1 I; f3 d6 U2 B( J
11.D8 x! ~/ d' V5 Z1 P5 w: [' D1 l
12.B
( _1 ?% K& d& P+ J13.A9 Q, G8 \2 c) R0 j3 _! U
14.D0 e7 C; L+ V% Z# I1 n- x
15.A
- N9 @; Y7 S8 ^1 V# z6 k16.B( R8 D- o( O) m X4 o" q
17.A5 _- H0 i( B3 m* o( x9 G5 c( I
18.D5 X6 g7 F# R9 v# B4 C
19.设计模式0 S+ e" G5 T* M+ U4 o" ^
20.D
! L: L% V7 S2 Q
# d5 A) O2 E& n) `, g! v( j) a" [8 g! z, s; V8 F1 p7 d3 ^
# L& A8 ?4 Y C- G5 h答案详解) d, P$ Q _" e | U0 T) p/ _
8 l3 Z& l& _) N; I3 z0 o
1.类是对象的蓝图(对象是类的实例)。
+ m" n- E; ?# k7 A9 V' c! `6 @" v
6 f+ V! j' U8 P; j# } P2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。+ w, _+ H2 H. Y ?
; |6 n) u% [' G i; B
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
8 ~0 a1 O! G5 W) ^
5 j, \( t- a; C; W4.单件模式可以限制一个类被实例化的次数。9 F- {! b' p1 e2 S4 E: I J
) e: c; x5 N5 @3 l& s" G5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
* t3 [" D$ n8 g2 ]6 x. i3 Q! o9 A2 N' J# v& b8 v1 D6 j- x" h8 q; P
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。# w( N9 W) r& o* O" e
. x1 c5 u; p8 ~
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。0 n6 b6 k7 h- P" l
$ f' B9 }. }& o. c8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。1 w2 i4 j# O; m( V2 {" L" }: P
) T2 E% Q% v5 \! G/ S& |1 x5 \9.PHP4中没有题目选项里所列的任何一个概念。答案是D。) s: d3 G* R, X: |6 X& V2 O/ a7 {/ T" t
w; i3 w% B7 \ K3 q1 _10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
: \( I) s1 E4 M/ c3 |1 M3 i& V) p$ r* c4 E1 [' D8 M
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。* h" k1 y! t, U7 F, P& O4 t0 L; e9 l
0 ?. x' F' {2 K1 k1 \* f12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。. o% U+ t+ c% V
E/ u5 ^% ^: u) D' ~% f( b- K* e13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。1 F U7 y7 m6 T
) a0 x# ?: [& v- X5 C" u3 k# Q
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。4 ?0 r3 @: [' h( @/ U
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:& h7 \$ C0 @1 r& b* T
function reduce_fraction(&$fraction)
9 c7 N$ K1 ^6 }! m4 B答案是D。
3 n# i x+ }2 m: t! y& X$ g$ R1 u0 f9 b, H( U5 P- W j% t8 ?
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。7 @ G& g* b1 F/ s: e/ a( h3 p- w
5 ]1 A+ F" p" `16.没有。PHP4只允许声明静态函数变量,没有静态类变量。2 | g( i! v! j
7 v" V; D; m, _# @1 n
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。9 ~) Q0 j% e7 w, O3 x+ I7 \
+ d) c: F. A1 Q3 ^( `
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。, Y3 N7 G$ k3 n6 I& h7 z5 ^1 L) N
! I ] Z4 H) H" w) R, z
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。" c& F: a F; m( `( |
# ?* k* Q2 Z' D, n$ N20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|