  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。' @( G" P* n& L8 l' `5 ]
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
5 i! |& [. d8 H& g: l6 j, m S$ Q本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。# T0 X$ L) N. F8 ^1 s! _9 w
. i- G& k; C- {3 u7 F3 B' E问题+ U' o& W |9 e# {4 Q
2 l$ z+ y6 u) u9 v1.对象的蓝图是什么?% \6 B: Q) Y* I9 Z) _1 m
: V+ F0 D1 p8 P8 v: B4 E答案:____________
) J' H& g5 F* _' p3 N. k4 `6 b, D$ |# `) f. M% t
3 g# G& r. L- H, h! y& n+ K2.以下代码执行后,数组$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
. q% ^0 f L7 q. V. NB.b: _) z. _' H/ `
C.a3 U0 {$ l# G$ T$ V0 M( c
D.d
g8 D" o0 s. Q% i- SE.e+ z7 [: L$ [- J+ x/ \. @. X
# C ~5 }6 ]. ?8 {
+ P0 z* x& ]" O4 N; K, D3.如何让类中的某些方法无法在类的外部被访问?
' [0 {+ N3 e9 m* @
4 m1 O- _3 Q! b. \) X" ?, FA.把类声明为private
& ]0 ^3 t; S2 P1 LB.把方法声明为private
# u0 ^( w/ I- T3 {C.无法实现& ~; ]* d# S- b3 O
D.编写合适的重载方法(overloading method)
2 T2 j: m+ }& b$ S3 v8 [% L u& z3 N1 r
0 F- x. |" }. _- [
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?+ o) B/ {/ x+ q+ S' P
) L2 F) Q/ Q. \ t' M \
A.MVC模式3 T; s" W# {& g: h& d& H$ P
B.抽象工厂模式(Abstract factory), ~! T- R2 ^0 X) ]/ V8 h* K
C.单件模式(Singleton)
" \! i' N3 p' XD.代理模式(Proxy)
8 W g* x1 x" m* J3 {E.状态模式(State)
9 e" m2 d% G$ ?$ d [/ M: E2 g. [
, a j5 I2 v; I' c, N8 \# B; w9 T6 c3 n$ Z5 F/ N! Y
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?' o! Q& v) N O2 V# F0 K; ~; i7 q
, ]7 ]/ b* K* d( c) C6 E
A.1个. X3 n( o8 X) Q7 h$ D
B.2个- V: y0 }6 V: `6 w/ c$ v
C.取决于系统资源 d& ^, Q" |6 U; ~$ x1 w% h# H
D.3个
2 a4 T( J& D; D* r A6 T% Z: nE.想要几个有几个0 q! i* F# s% e: r
9 z, \0 \1 r) g+ B+ Q# M# D' r3 B) @
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
/ T$ @; z( \' A4 C; J8 CB.接口! Q: H( D2 C( I/ D3 E
C.抽象方法2 e3 h6 L1 k& R, ]$ `
D.Private方法/ P9 ~$ Q' C/ _. \, H
E.函数重载(function overloading): |$ r8 S0 I2 M7 w, ]. @3 t3 \
: d8 T( |1 \3 P6 Z( |: K4 j- t- r; R' u
7.假设定义了一个testclass类,它的构造函数的函数名是什么?& W( T- o* C! G6 k# u* m0 t) ]
, P3 u- w4 k9 w- H
A.__construct
: @6 u) x9 m O' IB.initialize
- | l# V7 U2 S9 ~) R3 D- [C.testclass
B' m+ F/ ]2 F6 y ?. xD.__testclass
% k, J7 i, h% `& ?E.只有PHP5才支持构造函数' e% @; [1 Q P/ t+ g
( {7 w, W% b& @% H5 Z
) A5 e' x- B: D0 e% q/ P8.一个类如何覆盖默认的序列化机制?
7 s& |) _/ G1 A6 A' @ {
5 R6 T5 I8 K0 Y. pA.使用__shutdown和__startup方法, f! b+ O: |# X
B.调用register_shutdown_function()函数1 h2 \* W' E5 w+ B
C.使用__sleep()和__wakeup()方法
) b, |2 g- \) y! R2 N2 D u: jD.无法覆盖默认序列化机制$ U2 B2 D/ B" e4 L. E
E.使用ob_start()将类放入输出缓冲中3 J% O7 Z5 |6 D9 ^/ |
+ k* \. e X; a9 F, K3 E
9 Y$ G7 X9 M# p4 \' Z. Z% c
9.以下哪些面向对象的概念无法在PHP4中实现?- r' E5 a5 o" E
0 ?% W: o' d4 b. c j5 V
@抽象类
# R/ P( |- c. `+ \/ t6 `$ E@Final类
2 r$ X9 y( ?0 L( v% G$ M+ W@Public、private、protected(PPP)方法3 S: k8 W' k x
@接口" m- u3 ~, W+ {9 @' u- M) u+ o6 i% R
0 I2 _2 Y9 U3 m! h# V. q
A.抽象类" ^8 H* o1 r8 Y
B.PPP方法
* o4 B: i/ p/ |C.PPP方法和接口' }9 \ A/ o- x# U. @
D.以上所有都不可用
2 H& r3 R2 x+ Y1 s2 K- ME.以上所有都可用; D( j! e, D0 _& G
4 d4 { h9 ?4 V7 |. c) Z
( }6 W. m- Q, p, ~/ d10.如何在类的内部调用mymethod方法?, k% p# e) C9 U! [; f/ \: h
# S+ c }3 Q/ p7 ?4 x8 x) bA.$self=>mymethod();
& w) q$ X* j7 X3 q' b; aB.$this->mymethod();
# B6 _3 n J' e2 g, j7 DC.$current->mymethod();5 ?' t1 x7 D6 @3 t( r- _
D.$this::mymethod()
) [+ |: x1 d; `' _E.以上都不对
+ I% _$ u) R$ n3 @7 W/ e0 p l y: q1 l/ r! n6 g$ q4 f
& w/ o' b+ q+ A+ y9 ^- O0 _4 K2 ?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
+ h, S+ `4 W+ D$ E! oB.Null
( z# A! f& v1 F# P8 {: D0 C" jC.Empty
7 [0 a3 h. b# QD.什么都没有+ }; E: [+ t: a z* Z4 Z0 m
E.一个错误5 q/ e8 S% e/ g# \
o* P& u# Z3 `. g6 \
: X' {7 G: y$ h8 R6 G( k12.以下脚本输出什么?-
- <?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
+ i- e. |0 R5 y* J4 M( uB.5- }! @+ O' K) o9 G0 E
C.2) h( h: T- A- a9 B/ W
D.Null
3 }" P2 B$ p3 SE.什么都没有
* K: {( b" e; X
6 D" [4 U" [. Q4 x0 H R" S1 i. G" _3 K3 ?
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
: K6 u2 g9 ?5 @) ]( V7 U" rB.10
4 z, q! b/ d! [( NC.什么都没有
( b- i) I6 y; E% A/ n& x6 a1 {. ID.构造函数将报错, K0 T3 G; y: [. P" R0 q
E.5107 w3 a: L9 J+ g# S O
8 U; q5 m3 [+ y0 O
% L- {0 i! U8 R5 X( p4 T
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函数必须返回一个值
# F7 M; M# j- A& ?B.reduce_fraction函数必须接受一个整型值! W% j2 Y7 u- d# K0 p
C.gcd函数有问题; ?' ^: Y& s- k! I+ S
D.必须通过引用的方式传递$eight_tenths对象
" p4 l0 `1 I. |" B( y! z" mE.对象的实例不能传递给方法以外的其他结构。
: z, Q3 J: g9 K H1 b0 c5 x4 }
1 u5 x% A5 g3 |9 O4 |0 P
9 v* W' o+ N4 }% ~: z, h S1 V15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
) L1 L% V" f. J4 c& YB.生成myclass的实例并调用mymethod方法
! s' D* Q1 n5 t0 t* f6 nC.产生一个语法错误$ Q; o6 W7 Z6 S0 Q+ Y3 v6 g2 i
D.默认myclass类最后被创建出的实例并调用mymethod()) W. ^/ L3 {7 `& e' [
E.调用名为myclass::mymethod()的函数
& L# l8 Q) u I% t/ s: A+ B1 \3 M1 f% o( M
8 g! Z9 F$ \! C" V! P
16.PHP中有静态类变量吗?! h) M# M' V1 y" j
8 ]6 n$ I" @* d9 q
A.有/ e+ p: ~) ~2 ?% Q
B.没有# _1 ], H& M# c/ }6 ~# k+ o
5 r4 b7 R1 e- K3 e! R' v& |
' T x4 e4 @' g2 D( u17.以下脚本输出什么?-
- <?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.11 x& S1 `2 W8 A/ P+ e
B.2
5 X+ D; t0 w+ yC.一个错误,因为没有定义a::$myvar
. I* B, p- ?" h% V3 a/ BD.一个警告,因为没有定义a::$myvar
; M* Y6 `5 t$ Q1 J GE.什么都没有
4 ~' F* I7 L+ `3 \1 ]
L& z9 E% _, Z5 V* Z; ?0 v0 d
$ c- }9 {& Z; Y) { S18.如何即时加载一个类?
3 l- C h8 w" G- o1 e5 e4 {8 l% d8 J7 u% @2 Z% c/ A& S: i' d
A.使用__autoload魔术函数( e/ t- N/ A$ p$ Y$ }! ~* R
B.把它们定义为forward类! a5 H% q) Z9 x! o( O0 V4 I- r
C.实现一个特殊的错误处理手段
) e5 e; S: w) \4 l6 u( MD.不可能
+ a3 N- f" c: b% J2 N: e# t2 K4 hE.用有条件限制的include来包含它们/ H! O) f( a# [% ?) l w
$ W! g8 ]9 U. x9 ?* X5 _0 A
1 r- z& y% }6 c" a9 Y: x# R19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?+ m- [' U% E: T( f
* R! u; r+ y- g4 j( q 答案:__________. U+ p' n0 z3 o8 A
# L% J& H) }4 G) a0 A- A( z% x% }
$ X' ~$ T$ f, Q8 A' i: K8 f
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
# A7 ?1 K4 s, R3 tB.一个错误
4 y! u$ X& G" V# u% _# w" ]7 `% QC.一个警告0 l* C. B0 Q4 s
D.什么都没有+ q& L Z5 p9 f8 T$ M
7 ^2 q3 f9 n5 g' G8 Z. y
8 ?# Z1 M) z' Z+ Y: i0 H: E( P( L+ \4 t0 P
答案速查
/ b3 ]( Z: i4 y: |; Y- U1.类 i8 y# C d1 Z/ I+ Y
2.BCD
$ |5 u0 @# e3 m5 X c, ^: H3.C
% B& ?6 D' u5 G- I6 y+ Z4.C; s4 D" y0 a. j8 X
5.A4 _5 J# U$ X% W3 Y; g3 y
6.C9 _2 X4 C: @* S W9 w% v3 L7 p
7.C
( y6 e' r g( ~" R% d8.C
( U( B' D; I0 y/ k9.D
. r9 y( y1 U' [6 U# B! w7 m10.B3 X$ M" i: }. Q
11.D
3 v- Y4 [4 f4 j: r* g \12.B
! t' A- Z4 V9 Y' t) D13.A
* m% t; \7 o. H14.D/ M0 ~6 s/ r; T( m+ |2 ^
15.A
- {5 l" K& U4 ?3 B) d! v16.B
y1 i" V# }. j1 a5 o17.A5 o5 C9 j& u+ ^' O: O
18.D- J% P4 Z1 V. G0 n3 \
19.设计模式
: h" o2 F0 K; E20.D
0 j- H5 C4 r0 a9 V$ _! K5 N+ v- o2 L9 b
7 X: L1 F% Y7 Q7 @' W1 T
5 w& P7 |" a. f/ b( Q. C3 N答案详解
5 l9 v, ]# z! ~2 p) Q! i1 V% \
) ~& m% }: ^4 `1.类是对象的蓝图(对象是类的实例)。6 w8 p( K" e7 \; `8 i
( [) U3 e5 I) h' K
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
# s% D8 h1 O$ R+ {6 y
9 o& F; z% Z4 f% V. I: h$ `' C/ Q7 [- N3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。 C3 ^4 Z7 T2 ]2 E
- }2 W- X/ ?( E% ~# D4.单件模式可以限制一个类被实例化的次数。# ^, d/ I5 O7 s
+ K0 h" Y2 l; }. B4 n) N* O5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。8 u' l3 s+ S+ I* L( a
/ U$ f7 y; t2 ^: a/ ~! w
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。: ?, l# x3 A# e5 r% j7 _+ ~
% ]9 L' i. v2 a' G7 n
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。: H0 G, O/ T0 D9 t2 \
5 k% b" m8 O3 C# Q' e" m8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。$ k3 o0 A7 E1 W) L% ?3 d
$ i; s. }2 B5 A6 r3 S: R9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
) _$ a$ m& M( N5 q+ R* g& K8 b6 U) Y) k/ p# H/ n
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
+ H c& g$ ~7 R3 p
; g9 V$ e) a& [% }" {11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
) {4 k3 h2 N `9 _6 R" T5 i7 A1 Y3 B2 x! W& F* U& D/ H
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。! D" P$ f1 y8 J' G# }* |
- |0 @& e! w1 m$ N( o6 `/ ]* M13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
1 M$ R* x+ p& c, K0 F4 v ~* p; J# ]& {6 E! }% f
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
2 u2 I& W" |: [5 Y- A# d回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
8 N z) j7 I0 m2 W" E: N function reduce_fraction(&$fraction)# Y2 T: b* p8 L# l
答案是D。
. O! I4 O" t C8 O8 `( S8 q3 H
: j$ Y8 K. M6 T7 m( s! J! z9 N3 q15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。3 h: N( s9 E) k9 j
D- R" [. N& z0 V' D1 [1 ?+ {16.没有。PHP4只允许声明静态函数变量,没有静态类变量。* g. u4 ]* j" |" m+ `% J
( _' j8 h' F) y0 B, a+ H- V
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
2 k, }4 g" P0 _6 X* m2 d8 y- i4 @: n9 Q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
- b/ R- u$ q" X; B/ t/ @
9 o" f: t1 T# k/ Q19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。- U7 E, U' z/ M/ k) y
' O2 |" w7 m. C! v7 Q
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|