|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14325
- 金币
- 2448
- 威望
- 1647
- 贡献
- 1396
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
3 n5 c9 s! S; @: g( ]PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
; d* t1 @' m' K+ {本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。9 ~2 c& F% p& E
* ]* Q- \- M O% w9 J' R" y问题9 F. |. ]) i- i2 I5 m
5 L9 D9 Z; q* h7 {1.对象的蓝图是什么?, j _* x+ Z5 ?9 J
$ s/ V& @; j9 s e% B
答案:____________
5 `! D/ r$ Z3 t
, r( Q& \1 D5 i) V g6 e9 m+ j+ h2 C; p. N( o' O
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$ n* D5 R& q% c ^1 \. X6 [
B.b! `9 _& B9 b E9 U1 [4 o ?- D2 H
C.a8 F! [9 h6 T8 W- {
D.d* d2 v9 c" l, N" p! L; I, p
E.e
$ }0 X+ N- L/ c1 o3 Z& n2 |+ \5 Y8 l# }# e* T0 m( k, O
. ~7 J' W; C( J" ?6 z8 D# R3.如何让类中的某些方法无法在类的外部被访问?
. t3 V2 }% m4 ~7 m9 h& p
. A2 x, t' i, X: ~/ tA.把类声明为private# R U6 ~& ~# b! A! n' m
B.把方法声明为private
]2 i, N+ t* v9 a5 bC.无法实现. N8 t0 t1 [& G% J. B0 T" q6 k! x! A
D.编写合适的重载方法(overloading method)
/ v7 [- f1 k" u& ]" E# [3 A9 K9 s0 _
' p) D0 d8 B& p: \4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
( Z0 D' U. x* j0 ]6 }/ M
, I; m2 G; P5 [: bA.MVC模式0 p& q4 L) H0 {3 h* @
B.抽象工厂模式(Abstract factory). k M( B3 `; X3 U: p. x
C.单件模式(Singleton)
; l- j. A0 s1 I, BD.代理模式(Proxy)
% f3 H. G7 v' _+ Z- d& C/ jE.状态模式(State)* @! ?# \. Q" O7 x' c
% A+ I6 E% V$ N9 F O' _0 v+ V) L$ o0 Y% V3 V
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?3 i' {* b( `9 h+ ?) Y
/ K4 w0 A0 f$ v* E+ E( ^
A.1个
3 B: x. _: [# v/ Z% J# MB.2个9 a1 l/ f/ H. ~. g# C
C.取决于系统资源7 ~: P3 p' P5 \
D.3个
! I g. R4 _- B: y: j1 E. qE.想要几个有几个7 J5 T- D8 L3 Q7 L8 S8 B3 ~3 r
8 \' S _8 M6 | K3 Z
+ o ^: X" L8 q6 O8 P5 E# i* Y6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
( z: V6 p& N5 X: C- z/ l4 `B.接口1 w% [8 U0 G, ?* `
C.抽象方法- O' z h. X; T- d" B" _
D.Private方法
7 s5 v4 s0 v1 I7 ~, eE.函数重载(function overloading)
+ P7 b6 _' d9 d0 m" H/ U" h! U7 T# F% P8 D/ B! t6 G
9 x( @5 S5 x$ g6 m, q5 o7.假设定义了一个testclass类,它的构造函数的函数名是什么?. _2 U' s3 k6 s8 s' q; z
) F$ Q" R3 A Q; R$ ~A.__construct) e0 M& {+ ?4 z- ]
B.initialize3 p/ U5 W- A' f, t
C.testclass! @) ^6 Z. r- g0 {% w: H
D.__testclass
) e/ N6 X1 ]1 GE.只有PHP5才支持构造函数
; P0 P& L0 ?5 a! ^- G5 {, n0 n/ c: p8 m8 a3 u
) e; Y; B, o6 V7 s) |% R
8.一个类如何覆盖默认的序列化机制?
* V$ {2 F& f& B" V. z
# ^5 G5 f" B9 s a% qA.使用__shutdown和__startup方法0 h) g6 G* l3 X# s7 ^6 {4 N
B.调用register_shutdown_function()函数
, _+ ~9 [0 d* B" K2 n! OC.使用__sleep()和__wakeup()方法
0 e$ S- q S. \( B* j6 ]D.无法覆盖默认序列化机制
0 k9 s6 s: V- o) y, O H0 BE.使用ob_start()将类放入输出缓冲中8 D; d6 U* }* D. U0 A4 D
0 m# X9 H' \0 T
4 D7 |$ N, b* o! R8 ]
9.以下哪些面向对象的概念无法在PHP4中实现?
- I% e! W5 m7 k- M
4 f( X9 e& O- w9 [, W3 L0 j, V- j@抽象类
$ e) I, f7 Q/ r6 D@Final类! b4 T% z8 `# I2 l7 N& P$ H. T! u
@Public、private、protected(PPP)方法
+ y- c- O+ \! A@接口
% B6 A' V! k# ^8 F3 N+ n |/ R4 e+ |9 m0 o$ \% d, M
A.抽象类
0 h# e9 c) f# }, Q8 xB.PPP方法! R9 a7 X! x* r1 P
C.PPP方法和接口
% F, b% ~- Y' U' C: RD.以上所有都不可用' V6 y: l$ L; N2 P
E.以上所有都可用
8 {1 U! ]: j5 F K; \0 m% w! q% v( n( [* t6 }0 {# k
- S% T ?* V1 ?& O10.如何在类的内部调用mymethod方法?
' D/ W/ B, V3 |8 O+ N7 z/ I% L$ Q8 Z! F) \2 i' u) t/ T& d* Y
A.$self=>mymethod();# D& b4 N' ?3 w3 {; P/ N
B.$this->mymethod();6 x2 V. @. U5 W6 V! U2 n
C.$current->mymethod();5 V* M- F. i; z; j9 O$ P7 J
D.$this::mymethod()
' m2 g x- Q' h' |5 U" [E.以上都不对
3 c# `2 {- x+ h' q6 j
3 i3 H& y ]7 W& L" y0 I: V5 M3 ?) ?+ b, w
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
$ Y& R, l1 O( k# e; y" t6 `B.Null. _! s! ~' b, C7 a1 {# }
C.Empty
& S4 Z: A% F5 [$ ND.什么都没有2 c# Z8 g7 M$ G( k; W
E.一个错误
# D- J9 J" j6 d/ m
/ Q" D* Z' O! Y, b4 N9 V3 h
$ p) ]1 ~& `# G$ E12.以下脚本输出什么?-
- <?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
9 i6 H8 y" w& [/ JB.5: E# h9 G9 J/ z# m' m
C.22 o" m1 d( L; Q$ H5 h5 z
D.Null0 D H2 h, m G6 T
E.什么都没有
5 F/ f2 i8 _/ B. _) ]& v, J6 n
( H7 W8 g( g2 j; P9 J! T1 n! l( I) c& A2 ~6 Q; ^
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* e; w/ D9 ~1 y; }* @3 l9 T4 [
B.102 e5 a. B) {, ~0 c$ q/ C. P# W* v9 Q
C.什么都没有
# i; G6 g% F6 @% ?8 h/ VD.构造函数将报错5 z: _2 I% \0 ]$ h9 i( N% C, e
E.510; Y, Z0 t4 K* h
4 g* d6 d3 m' T$ f
9 d* W6 }! R# c" m' N0 E2 Y0 A
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函数必须返回一个值- g( x; m% l& x0 e. ]: v
B.reduce_fraction函数必须接受一个整型值8 N J( O& \1 V8 i6 a5 F
C.gcd函数有问题+ G. [; ?3 b5 j5 U4 l
D.必须通过引用的方式传递$eight_tenths对象
) c0 v% X# C- V4 |" w. yE.对象的实例不能传递给方法以外的其他结构。 T9 S0 h0 g3 w1 I
' ]1 N& o& a @7 c, p& I5 P
+ d0 T' ]7 Z; t: O15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法% Q$ Q: a5 W, Z0 H6 T$ e
B.生成myclass的实例并调用mymethod方法; R0 D' g% x" G$ b9 n# W; Q: T
C.产生一个语法错误
|5 V* ^ U: l$ \# Y2 OD.默认myclass类最后被创建出的实例并调用mymethod()
" x+ A q N. L1 d* x0 [& xE.调用名为myclass::mymethod()的函数
3 E; l$ U5 E- E$ s/ \
4 u" [2 U/ s. h; S' {9 A+ \
% _1 |: [# J9 Z' b) `/ M7 F16.PHP中有静态类变量吗?
$ \- w' A, \4 n* E) E- @# ?& ~7 b: m; }
A.有
' s: Z, Z4 N/ k' ~B.没有, ]( _3 ]$ ]6 T* r3 t
* q7 m5 L( i3 i7 F
; u) H$ k5 e8 h" t. W' F( G0 R17.以下脚本输出什么?-
- <?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.19 q; o" R/ B% D) ], p- x" q
B.2
# n& ?/ e f% uC.一个错误,因为没有定义a::$myvar
. X n' u; `* r8 D- U' l2 {8 ?D.一个警告,因为没有定义a::$myvar
, \9 u7 I0 D E/ EE.什么都没有8 o( I0 ]8 X) q7 X; a! A( o; B
) o9 G3 }, [% s# j1 V4 Z7 Z
+ B/ g. t8 z, V; M$ b18.如何即时加载一个类?" S3 [/ v7 |5 p- T1 m
1 r) g6 B3 \* O: g* P c. ?& w( G6 LA.使用__autoload魔术函数$ `& Y+ n% g5 m% Q
B.把它们定义为forward类" K O- {' O }
C.实现一个特殊的错误处理手段, v5 u$ W6 s2 M% \* C, F: c
D.不可能! f& h# X0 K. M$ K# X
E.用有条件限制的include来包含它们
) S |! V" D3 N1 q
+ ^$ r7 I- {( Y7 F
7 O* U! B( R8 W- ]: B19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
" p6 u( r# O% v& P/ H( s( C3 z, N9 j; l
答案:__________$ A% d m e! q; U
7 G$ e9 A4 _6 d4 Y: [
/ G' ]/ p2 `6 a0 G. A20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called. W, c; C$ S6 P+ D2 V0 F
B.一个错误
" n0 `7 E8 ]; ]+ Z+ @& w; w& SC.一个警告
/ X J( D+ Q* g5 \$ sD.什么都没有0 H! u9 @& l% c0 }- y' Y. l7 E5 G
( x2 d( K* ^" C: S
; a. w u+ J& w9 y* H$ t3 k
; h& Y) l. P) A- d" u2 s答案速查
9 K, O( F" u! r. j+ l# \8 R T1.类# J% s8 c) C: V/ A
2.BCD6 t- u2 a2 M1 s7 r* U/ k
3.C
& k% S6 ~; L' N2 x# Y4.C
- i/ d7 w F. I. X5.A
8 C' P. \" b" D: L A6.C
0 R3 P1 X/ ~/ v2 |1 U7.C* A o) x3 ?5 s+ D
8.C9 o1 Z" k) U* `% e, c! g
9.D
' v% t8 Q5 ~& n1 p& r10.B5 T8 j" V, s+ C+ @9 Z
11.D
6 E; u& c& B& Z, R, _12.B' \* I& j# a% T; I: V, p
13.A
! Z9 ?) Y f: \- a# l% H5 V# |14.D
$ e4 U3 V! m+ F. e15.A" K5 h8 u& F+ P8 `6 z N
16.B- a$ \. ~7 U2 z
17.A# X' f6 D( ]# M& {% P3 f
18.D( r& @ x) @3 ]' X- ]* H
19.设计模式* S/ M3 U2 z7 t8 n' _# U
20.D
. a* I8 F- q) Q5 y% @ Z3 M
( }" m. J$ y5 j6 M- q( Y, [ ~* I7 v) D4 g7 [4 b
p1 b" |( P7 Z答案详解5 W/ |* ?4 R0 ?* f4 a
* X4 ]# T3 c1 j/ c, D
1.类是对象的蓝图(对象是类的实例)。
, s, ?. C9 `/ i t; ^$ Y- A# }% }$ M; a# N. D% [. g
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。; P9 P$ m& U$ I' v- X& f$ m
) }$ f" @" s! k# X+ T
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
+ M" Z9 \1 P6 V5 B* F! R# Y
& ?4 s3 G* u8 ^- o/ j4.单件模式可以限制一个类被实例化的次数。
1 q1 p/ |$ A K/ R& k5 m
3 S" r6 K' l, Y+ `+ e+ ?# M5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。$ r0 D' I, n. u: P5 f9 r. S
6 c% \' m& i" ?$ @7 {1 W6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
* E/ t/ o' K3 A/ E2 H4 f( h
1 y: y: g$ G/ C7 l* |/ z' E" c7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% t- h+ M) b6 c8 ?: b3 T3 d& W
% e2 U( Z$ @( Y2 w- n; ?0 Q8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。& }" [% g* b/ L3 S8 p( m# F
) |# k3 g. A( f9 ~0 k- n9.PHP4中没有题目选项里所列的任何一个概念。答案是D。' w! i) `3 U' u
' x/ ^6 P3 b; Z7 X' B, z" s! \10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
% t5 ^+ d% C9 J
0 e7 m+ ^( @ V) F7 x4 {, H11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。" |8 O# ^1 y8 U& s, {
1 f- y1 z; k9 y; O
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。$ V) S9 f. X* q+ {
" ~3 W* Q/ W4 L% R" h% V, m
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
4 c: Z' A" ^6 L, F! C9 j0 N; o. b" z8 h0 w, v: p
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
% P$ M9 Y P# w% z+ u回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
0 {& K- A5 r* ^9 d' E7 O function reduce_fraction(&$fraction)+ z# Q6 y9 Z6 i/ `& |. j, R) ?- ?
答案是D。! r( Y& ~" H5 E
* W3 T1 H# ~5 x; c' }% _" J
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 k, X3 w4 Q) R+ t4 R% @3 @7 R0 _' p& r' O, P' g _, u
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。- Z5 q5 S# W5 @) t# k
& C1 K; u' a. I- o4 s8 y4 X
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
P, W- c7 A. z V8 @
* k. T' C' w% Q2 P3 a18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。) {# x1 n9 U" V1 |
6 u, L$ U% B6 G- G& ~+ n& o19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
7 P; v' _! Z, _- ~. y9 u$ `# a
6 O( @% ]2 k7 w8 ^# L20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|