  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14171
- 金币
- 2376
- 威望
- 1647
- 贡献
- 1324
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。- e/ _0 C2 V, S( L. x4 q
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
; l4 `' a, l% l' g, Y本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
# |' {! j4 l0 d9 `1 d9 U- ~% \4 ?! u9 Q2 r+ q
问题
/ ^" V+ a2 g: N- d$ i' k8 E
( c& ?) T# F# Q' F% ?; I1.对象的蓝图是什么?
8 q, e4 o9 C& ^5 T8 X( Q- H+ ~3 n+ v+ V# F& |
答案:____________7 W8 C2 M! g, M" N
4 X5 {2 d- ^) `5 a" E8 C! M
7 Y7 i" Y( i* J) ~ r, `
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
1 m; B/ p& S) x3 ~B.b3 l) Z s2 P, K3 V
C.a
: f# G2 V% d4 s! m& uD.d
/ ?: s3 b5 J# M2 [3 `. v. SE.e+ W2 g5 F) ]# K- q- o+ d) d
; k& Y- _3 E y: o9 I
/ [$ n& O0 \" f p; N' u
3.如何让类中的某些方法无法在类的外部被访问?& Z" |6 U2 E4 @8 B2 C# P3 [9 N4 M
9 M5 C/ n8 u# Q& k. D+ s
A.把类声明为private8 F, P* O* x2 ~
B.把方法声明为private
4 s& G' F; I: ~: z% ?C.无法实现, j0 ^4 Z& E7 D8 M% G5 J" K
D.编写合适的重载方法(overloading method)
, e6 x- c2 z" s; g% {# t" s% F- j4 K; K' B, [0 V, }6 h7 B
) o& K# A V/ }5 y, ^4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
# k( b4 x! R0 n& S$ L4 ^! s: A; ~$ v
/ V; O1 u# _( X, e4 UA.MVC模式
4 m {# P [. K v- V( R5 \B.抽象工厂模式(Abstract factory)4 _1 G7 k, |6 z2 t+ }
C.单件模式(Singleton)
6 F' i- _ X$ ^" Y) u4 a( ?6 ?+ ^D.代理模式(Proxy)# A! v U- Z/ e2 v( R! Q+ s3 w
E.状态模式(State)* Q }4 t, }& {8 O' T) k& b
+ Z% j% _' Z7 ~- k: n2 `& O3 y
2 O( Y* S6 X0 { S! u5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
+ I4 d1 P+ v/ m9 U$ T2 o$ \
3 j0 x/ s5 q ~! Y6 m& j3 zA.1个
; J8 W& k% L$ q( N9 C5 BB.2个2 E. Q: H! g# m9 G/ E
C.取决于系统资源
5 L' Q) z U# H6 w9 Z" pD.3个2 j! O7 M, u& j) Z
E.想要几个有几个
, N7 N5 B! b+ T) g0 |, {1 ?; M0 a, r0 C
2 w0 e% I- h8 ^9 L5 q6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
q9 q" I5 P8 O1 G) \; |B.接口
# G4 y- |9 ?; G) U1 S$ PC.抽象方法6 x; n" b( Q, z
D.Private方法& ]( {/ j, o9 n5 i/ G
E.函数重载(function overloading)7 N1 B. W- q( h* r6 o% c) A6 S# C
' P7 k0 x2 B1 d- o
9 F, @& s Q* y* X& R7.假设定义了一个testclass类,它的构造函数的函数名是什么?
H2 x- F5 [* u" [: N4 P! ?% v/ r2 ^6 X( u: B: _0 D
A.__construct
4 Q8 B$ [! [& O0 _B.initialize, w3 T& @. ^$ L9 E- h
C.testclass
. o+ x/ Z) [$ o( M& E6 O: Q+ wD.__testclass t4 Q2 @2 t. d' x1 Z
E.只有PHP5才支持构造函数
% b4 d! }- B7 T6 D0 N, H
7 @* ]- `8 L, C. V& x. l) F; X: W% Z4 m, A8 s- \4 V& `
8.一个类如何覆盖默认的序列化机制?
+ i0 M' P/ m; J9 S! L$ i% k- E# C' Y1 G, l6 u7 R8 E' G! \
A.使用__shutdown和__startup方法% Q8 _2 L- K" {6 t+ R
B.调用register_shutdown_function()函数. g* a% w7 _% b: I9 W8 F" i
C.使用__sleep()和__wakeup()方法- }0 |# O& l1 k6 Y6 ^- p* p
D.无法覆盖默认序列化机制
" f; q6 e" h4 ?. LE.使用ob_start()将类放入输出缓冲中3 B: a9 [& |+ a o5 X
+ ^" A3 _+ K4 q( M9 L4 O9 |8 x$ b2 F1 @) M; G
9.以下哪些面向对象的概念无法在PHP4中实现?2 I0 [0 J1 u' t5 X
9 ~$ a6 Q2 m1 c1 w- J% h@抽象类$ f) x7 d: H1 e- h- I x
@Final类
$ S/ G4 L1 ?- f `( m# {0 k& a@Public、private、protected(PPP)方法
0 J2 J# G/ i+ h) q7 s@接口
6 P- r/ m7 y' H+ F" E7 o0 [7 K1 m3 h
: F5 x7 u+ B# ?! OA.抽象类
( p' n: ?& Y( {( \* b6 ~B.PPP方法4 H7 `' C, p7 Y- R. H1 I, g
C.PPP方法和接口
0 F9 n7 D) T5 Q* d8 ZD.以上所有都不可用
" Y m4 x5 H8 c- B* `# ]E.以上所有都可用
9 q1 Z+ t# T9 E, ]7 u
$ Q$ U U1 D( j1 w# x, @9 Z/ S
' L" |$ ]+ k# Y, S7 s. h# P10.如何在类的内部调用mymethod方法?. W! \3 a2 J4 L# u
. t+ Z0 e8 n. i7 kA.$self=>mymethod();3 \9 e+ C9 U& D5 D. p; |7 f2 Y
B.$this->mymethod();
& }4 x; L: I3 n3 q( \) g7 @C.$current->mymethod();. x: a4 J1 r& D1 G# w, Z3 z. W
D.$this::mymethod()
- ]! q8 p) S* EE.以上都不对/ {3 w d) S# k# F+ n2 k& N
$ U/ e( ^2 E9 L+ u; t3 ?5 C: n
0 a e O! |( M C# O% L
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.108 t' O: M( ~0 q# \/ Q' g
B.Null
# e! R+ e6 z1 O# ?, TC.Empty
% J/ q" W( `. s! M1 Y( `* MD.什么都没有0 Q. i+ ]" o) o% O! o) ?3 V
E.一个错误
! Q+ S* _3 Z& h
3 `3 I- Z! d8 D/ A! f W" D& s# } W0 a& x0 f& ` a
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.109 K% U. a' [+ P2 E
B.5* E P' N8 d [; q4 V' T
C.2# y* i) [' a: Q: E. s% }. r
D.Null4 i0 P8 ]9 N) A- D
E.什么都没有
' G" @0 `( k! s3 z6 l Y4 E1 O6 W& ~3 f. z8 X
9 L' i" i% S5 L1 _4 f# |3 F
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.58 Y7 ?$ a3 J5 v9 T
B.10
* d3 d* ]7 J+ G; i/ xC.什么都没有' L7 f ]* V& r _' k
D.构造函数将报错
" B& k. S. ~; k" UE.510
5 ?# I3 c B3 t3 j0 J
~! l# @1 L2 _( h7 U- \
# E9 K* V2 Z# {" T# F; w14.考虑如下一段代码,执行时,$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函数必须返回一个值3 o( k0 E: l3 c& }( v' v7 F" Z( W% v1 V% @
B.reduce_fraction函数必须接受一个整型值
& [4 b- M, }4 H+ ~# QC.gcd函数有问题) g F& m1 y$ J* L
D.必须通过引用的方式传递$eight_tenths对象
! _1 O) c+ U) ?( z& e, SE.对象的实例不能传递给方法以外的其他结构。
H8 J/ k/ r" M/ H- M8 Y6 B; f7 j( M9 J- |2 N1 q8 L
# [3 v7 [% ] L# U: Z; }( ?
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
1 F/ e- k0 _# v- X, t8 DB.生成myclass的实例并调用mymethod方法
- g& j( c$ }9 B: e! |- I0 I7 nC.产生一个语法错误
% J1 `/ M5 I7 {8 b3 t) @- D9 e9 G) _ BD.默认myclass类最后被创建出的实例并调用mymethod()$ ?+ `7 J' a& G3 x( ~5 g9 G
E.调用名为myclass::mymethod()的函数
u8 p5 w$ v6 ?- a0 v1 f
B* m- T+ C& f, p
) I# |$ s5 g1 g) f7 s3 j16.PHP中有静态类变量吗?+ a3 v9 s; ^/ m3 R& B5 k5 k# c
; k' X" l: f, U& X" K# X, i' L
A.有* H2 P+ k8 r& C4 V4 W
B.没有
6 M0 ?4 p0 n4 S7 V1 w2 a% |4 F% i" X& p$ Z7 \ y$ `/ }! S
6 W1 y! H0 D- B# M! b17.以下脚本输出什么?-
- <?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
4 B; K u8 [+ I) ^: ?8 D% rB.2! U( X8 w- I2 x- |
C.一个错误,因为没有定义a::$myvar" |, m$ D, c, T& ?0 b
D.一个警告,因为没有定义a::$myvar
* H3 V2 u8 B/ ^9 TE.什么都没有
2 J8 j5 v$ R- D
j7 p$ ^5 R* C9 ~7 ]
( P, U+ f3 {9 m9 _' K% o3 k18.如何即时加载一个类?
* X& P) B5 o; U- T4 l4 }/ D4 g# X6 s! I
A.使用__autoload魔术函数
* c( f$ W( d; k: a6 f& NB.把它们定义为forward类
+ T- }3 Y6 O- N* u+ C" VC.实现一个特殊的错误处理手段; v+ Y' a& p, T) [
D.不可能
2 j& h- E8 b) |$ ~6 v1 @$ {* ZE.用有条件限制的include来包含它们2 Z2 Y+ n7 Z1 G- n# ]% d$ C( C2 A
/ a; p, s" j: ~/ u' [) ]2 y
+ ~. Z9 ^% j# Q( @! J* ?8 h
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
+ d" E" T. J0 \/ `0 i. E8 b2 q4 h7 |3 s4 q, X! [4 P. o
答案:__________# f4 c. W0 f; E0 l6 i5 P6 q4 G3 X
, G' @0 [- c7 w* o- j
+ k" ^& r, v# }) y
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
( u. Z7 i, E% n. p8 `3 _B.一个错误- c) E+ W# k4 h7 a! Y
C.一个警告0 l$ Q5 U% V- A! r" }
D.什么都没有* K- y1 b' v3 e. k ^, K
6 b- j8 M) _3 R$ ~; l- T4 @; P; o: c" q, F' p
4 `8 |4 P" {) s
答案速查
, u) G% ?) U3 y J, z1.类; q4 b7 ?* J! ~3 T( s2 ~% ]
2.BCD
" C" E% d( ]: w# r# o! |3.C4 o* W7 y# B6 p5 r" [" Z# D, L
4.C: J0 X4 A1 @+ `; T6 V
5.A, s6 `3 I! d) a
6.C+ V- C# a6 }1 |* h/ i/ r
7.C
" E L, T) v# D% ~1 U# C2 `8 Y1 O7 n8.C* c2 G' K! @) Q# p
9.D2 S7 X [/ k0 n/ g2 S
10.B z6 ]( o# E! D9 I) J( ?! z
11.D
+ {6 B! l! U! U& h, I `12.B
! p, F* H4 q& H W |13.A
+ ^& [4 l/ F0 L+ ^/ d( \14.D
/ r M2 ~% D( c" t6 \2 A15.A
$ c0 O9 e3 w+ q; h2 E16.B
0 w6 f; i0 F: l" c6 d17.A" x6 S7 ]: n7 w% y
18.D
* G8 L$ n; w4 M1 Z# `% b. m) `1 o19.设计模式; Y' _' e( \+ h- K f; ]
20.D: u# c" g: l/ Z$ T
% I& P: \( }. C( U' P
1 F+ a! X2 c2 b' l8 O; R! W
) _! T' u+ E. k! C( W答案详解( b: T" ]) ~ a Q* `9 ]
- `; C' @' p) `. L
1.类是对象的蓝图(对象是类的实例)。
1 c* d* u$ l x/ O5 L. i6 X F' _
4 i/ K3 r5 e+ d3 P0 H2 s& U# \2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
' o9 `6 g" t4 c+ |7 y6 Q0 a1 W) t6 T. i( d* |5 `: C+ _% Z8 `- P
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
5 [& ^2 T( h9 S$ ~" K: W
+ z4 l3 t# L2 [" ^3 b- h& g4.单件模式可以限制一个类被实例化的次数。" s( N4 O2 r0 I* @* W3 [+ x
0 M8 u/ o3 x3 u9 E7 g8 N5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
5 T6 c" d8 x6 |7 o, ]. x; d* g: `" n: i- {! M
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
- q& f0 S1 L* y0 o1 [( C
+ {) y+ W/ l# R K( n7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
, i+ C' m& a% q/ K4 O
4 L2 g* J8 O( T7 k! J- J* _8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
& L/ K( c* f! Q( Y. [' L( W& o& Q2 j J6 P' F
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
& m# t1 D- v, X! x& e! U" E; J( A( D
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。7 r9 |0 F3 u' F3 z
9 `' ~* p; s" R: Y/ d11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。- [7 }/ K' }" K9 p" }. V; C
# N, } E+ F' h I4 [; d5 w# v2 H12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
" R4 a2 Y- U( M, n* J. u r
. p2 d; ~8 t0 d8 v" \13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
6 ]. y" R# h9 q. _6 J) D7 Y; ~( K5 _' f1 j5 y
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
N L. ]" Y$ N( D5 c1 D. `- z回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
( i# a0 A) o$ o& B" ?! q function reduce_fraction(&$fraction); e9 D% o, m/ j8 ^7 a$ G' D
答案是D。
/ x0 _6 w; G, n/ P: g# P P! p2 k/ S1 H/ {
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
9 _/ g# m$ a+ p0 A7 s# w: T) r
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
- [$ }4 H5 q( d8 U' w& v7 \+ I6 d. A" L
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
% n* E7 O& t' @, S8 ?
0 `0 _& {* J' N" _+ r18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。- l7 y }% B% O& D2 A4 i4 N" o/ j+ A3 N
9 O% `! b B7 G5 i* o1 @5 o19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。! S; `& K+ y9 P3 y/ P& p( N: }
+ w- K- _4 x/ n- p# G
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|