  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14159
- 金币
- 2370
- 威望
- 1647
- 贡献
- 1318
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。- o8 w1 u' _3 Q, U/ u
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
7 i% k) N# {% |' ]本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
" G' ~1 i7 ^) |6 P/ R
# ^7 j2 X5 q+ g' n: Q) N% ~问题
4 `/ W- K$ V( o5 o8 }5 E5 m- ~! j8 s% b {4 {- f
1.对象的蓝图是什么?2 J' a$ @: U4 y7 |: ] E
0 F4 \/ G. T* F2 F! H4 i
答案:____________
- [7 Q3 H- r( |5 e9 Y4 G: o$ v0 {; m$ U
$ t3 A5 I" O2 q. u* n- ?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.c8 K0 i; @: O; p# f, a6 R, F
B.b
8 ]) S- {% X, t: tC.a
. T, D: }0 l) ?5 s' n# m' tD.d8 H( x. @7 a d: m' E4 C5 A
E.e4 @$ G- i+ h0 y" x
# e9 N# b$ i7 k- Z' Y' M* N( a" V
: R! V, I* Y. S( `" o3.如何让类中的某些方法无法在类的外部被访问?0 u3 D$ j' f. k: o! @3 t/ n; l
2 r1 ^& p- [6 u( y7 `0 Y+ p! i/ J
A.把类声明为private
0 W, a7 A6 A1 U7 U8 K. vB.把方法声明为private
) f" t" j" f7 r: @C.无法实现' a, Y' @& q% q& f
D.编写合适的重载方法(overloading method)
+ w5 `. F. B. q0 I7 [8 @3 m! T- w
' w) K: \' B6 \
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?7 {3 l A' G3 }6 s8 o* }
' [6 E4 f& ?# @% y9 xA.MVC模式* P4 {" d7 |/ V: E
B.抽象工厂模式(Abstract factory)
5 w0 K8 Q) G, L8 G2 T, W/ q2 zC.单件模式(Singleton)
* t! s! a4 s" g" ~D.代理模式(Proxy)1 d+ d8 O( w( m: p( x
E.状态模式(State)
3 d+ ^4 c8 W5 E* L* H. F: ~1 ^) C2 F( L- u v. `) u, r
2 k- Y0 S/ x: D5 j5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
+ I7 ?) n, x1 H' d
+ I7 L f: }1 xA.1个
4 [/ w3 l1 K* q3 ]) OB.2个
( ]$ ~8 b" n: z8 uC.取决于系统资源
# k; `0 H! X0 pD.3个
+ w6 N% E* u7 G, a5 pE.想要几个有几个
4 a1 Z8 N8 w" H5 m" b0 Q; L" ]. g( q w- q
& l" K+ W. s4 E0 J) C4 h
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承 Q3 |2 G! n9 @; b9 @' Q
B.接口3 x. @ V1 s. x3 P$ T
C.抽象方法
% W/ s( F, `" `! q4 E: zD.Private方法3 k2 T& U0 u% V: U! L/ `( O
E.函数重载(function overloading)
4 a( L& e/ q: A/ B3 D; Z8 }" X5 D
. o/ h$ q2 D2 O; O1 ~: X5 N! k Z% U' ~7 O- W. ?: z+ O" Z' D
7.假设定义了一个testclass类,它的构造函数的函数名是什么? Z$ ^. S2 H, l1 W
/ R( A9 v7 w' ^A.__construct( U8 s. j, l0 ?/ @* R3 S. m& V
B.initialize
" n. t6 \$ Y, K BC.testclass* s: k; D8 u$ d6 b- A6 G
D.__testclass( a7 t. z& n" d1 h" v S" K& H$ N( _/ t
E.只有PHP5才支持构造函数" x! R* T8 t3 A) V3 _
1 a6 J! Q% d. O
4 @$ W: N" `, W4 y/ R8.一个类如何覆盖默认的序列化机制?7 i) a9 H5 r7 @
" e) B% Z0 o- T# r( W( B- N* KA.使用__shutdown和__startup方法; X. ^7 g# n/ |1 Y/ c
B.调用register_shutdown_function()函数
4 V/ J- N; b4 J5 q# `C.使用__sleep()和__wakeup()方法$ w i" v7 o) v
D.无法覆盖默认序列化机制
/ J9 U% ^- D6 ]E.使用ob_start()将类放入输出缓冲中9 g+ E( R+ W4 U
3 L& C- p" Y" `6 H' m( D
' A5 V* ~% c/ f- p i# Z' h! \9.以下哪些面向对象的概念无法在PHP4中实现?2 W. \+ h( a% `2 c
( V5 ]. U' j. j* n, C7 V) r
@抽象类# W- ?- t. p9 c4 t. q
@Final类: s7 D. X5 S8 d- b0 @( W
@Public、private、protected(PPP)方法' f. z1 B7 N% D3 j8 E
@接口9 U) P0 f }+ @1 M
* M# {3 g) J L. X( W9 W% l
A.抽象类, _; p3 e& f: w. w3 Y' v" b
B.PPP方法
* _" r3 X P# G9 p) LC.PPP方法和接口0 m1 e" D, d8 f ]7 m: i
D.以上所有都不可用
, ]" M5 |5 S, E9 dE.以上所有都可用' w! c/ A! i4 u4 }6 i- r7 b
0 U/ a o* Z1 m- Z7 u* V) I" w [6 u/ ~7 j
10.如何在类的内部调用mymethod方法?
, y8 d+ t ?+ {5 l. F& Z H0 \/ \" v$ f; C8 x$ y0 l* L
A.$self=>mymethod();. [/ n. O* q- P! H
B.$this->mymethod();$ y+ i2 H4 Y0 t \
C.$current->mymethod();
, p9 a9 B) z4 Y9 f' AD.$this::mymethod()
. t7 f. e; s0 a/ w8 Q( W+ aE.以上都不对
. S" m0 @+ Z0 Q! ~/ Q+ R2 K5 `- v, w- y2 L0 ~' y! k5 A9 l
5 \: e/ [- { v9 M11.以下脚本输出什么?-
- <?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
5 K1 J4 n# ~: S `7 N5 HB.Null
8 q6 ^2 \7 \% D( \/ q kC.Empty- q B% A* D9 D- m3 j' ]1 T+ T- q
D.什么都没有& ~. _7 `, u' v0 J4 P. S
E.一个错误
5 [4 T7 N' H9 w$ ~
" e% d1 Q: E$ ~7 ?/ P. |: _/ G K2 d' o2 h0 ~
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
( O% B+ w* N% l* z+ ]9 B3 E) }% VB.5
h7 |# ~+ w3 S: \! f9 P0 VC.2
; J) A$ K2 } `2 r6 q- qD.Null. Q4 g& h% Q( D: N8 e
E.什么都没有
; p: q2 a9 A6 c5 J
7 O. s( M2 c0 S0 x; _/ }# w0 g3 ^3 N3 N# D% l
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* u+ w" F/ T& m" A1 r) y' d
B.10" Y2 h, j& j+ H6 r. C: h# \; o' O
C.什么都没有. A$ s, t V6 s, y
D.构造函数将报错9 t' j) ?" a, u7 g+ q) n
E.510
& A+ }8 J1 b9 o Y$ d3 @* b1 X( T' c, v; {" l3 F
/ C/ ]+ \# x/ d9 Y5 m: {$ b! e
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函数必须返回一个值
( S% j0 @3 z" g8 c5 c8 F9 CB.reduce_fraction函数必须接受一个整型值9 p+ E5 q, I" k6 P
C.gcd函数有问题 W8 t @" Z: m' J! ]
D.必须通过引用的方式传递$eight_tenths对象
5 |# D7 T& {, P9 O& fE.对象的实例不能传递给方法以外的其他结构。
. P' M3 ?/ w6 ]* c( _
/ R; s2 h' }$ A' U" m
7 Y9 s2 x4 n8 V/ i0 ?! U1 [: I15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
. q+ U# G2 h8 ?! AB.生成myclass的实例并调用mymethod方法5 R Z: @$ g$ A
C.产生一个语法错误, K, l! J$ M3 j- H& O
D.默认myclass类最后被创建出的实例并调用mymethod()
+ C! C: K$ }* L$ p2 t1 n O. ?E.调用名为myclass::mymethod()的函数- X& N( P, @4 `# c0 C. e) Y
( G- {3 ~8 d9 y! C8 g
. y" X8 g' M6 `& Q6 W16.PHP中有静态类变量吗?
% T1 ~6 @+ ~! S1 B! U! D/ c/ j/ C) \* x g, \2 N
A.有
2 \# d5 s8 Z2 |6 {4 K2 f/ lB.没有2 I0 J) X1 B! r* h
8 [+ _9 }& N9 c: Z- G3 B
# w( @& h$ V" C2 f* F e0 e
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
2 E/ n8 o) A2 ~2 y2 w8 dB.2
$ V8 u5 l& A' b T+ T# mC.一个错误,因为没有定义a::$myvar+ z V: m9 N3 K$ n7 s
D.一个警告,因为没有定义a::$myvar4 z$ ?: [4 s- i% t8 B' `2 _
E.什么都没有
) w9 d" k2 l# P7 V8 H0 U8 ^
7 u E0 k1 f. W( u+ o% n7 F5 c; q0 V4 o- L) A
18.如何即时加载一个类?: b: o. t5 f9 h' `2 F. [
' R) Q4 m; S) Q0 E3 D$ G- KA.使用__autoload魔术函数
# I* d* ]6 N6 y) R' V, UB.把它们定义为forward类+ g6 [" h, {2 w% P6 n( `6 t
C.实现一个特殊的错误处理手段, }) P6 b8 [3 M. I
D.不可能8 J: o" \$ r( D( ^8 w* c0 v
E.用有条件限制的include来包含它们
" k% W, q0 V9 s- K2 d6 D; F' ]2 o# W8 G
$ v3 S4 H) Y: E$ S19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
' a5 D* X% P: Z5 @- P7 Q! \; o- _
答案:__________2 Y/ b7 R" p+ P" ~/ P$ j+ _
# s, Z- k2 J3 G/ G
8 Z' e5 R! a( @) H' L& m20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called2 A3 z: E8 {: j6 X4 Q5 ^ F' x
B.一个错误
2 w& Z8 I5 w3 x" T8 ^C.一个警告
; F# O$ X- k% T5 l0 C. M% e S8 ^D.什么都没有) Q' X+ p: q0 r- k% P
$ ^6 u! e: A( [3 L
$ b; y! L# v7 O
( n3 Z! b- `8 u7 E$ O4 ?& b
答案速查: a% F: ?' k+ k; y/ R' B) V; u1 ]
1.类9 d$ L. @! a% D# y
2.BCD6 t0 p2 H# N- I6 ]3 `* U7 o
3.C
! m. D ?# A$ j- u- ^8 {4.C
' Z* D# q* l/ s. C5 w5.A
# h# ~' c# i' r6.C; L* z( [/ G- _
7.C, A' |7 H/ x# E6 l7 m& \
8.C
9 l# P. N4 U8 B5 x. B1 c2 [0 e9.D1 x% ?/ p5 L, x' H$ P8 Q6 d
10.B0 D! a M# Y2 Q2 a5 [$ A! z, p! U
11.D
- g4 e& p ^" M12.B
+ R9 M- P6 a, V) b6 s13.A4 ^+ i/ h0 g9 z" g/ I* i
14.D" _4 ]3 y3 G( S
15.A- G7 G. r' T; s* v9 X, X( g! N
16.B0 r6 u/ a% Z# k; Y. n3 E! {
17.A5 C* n9 J# ~* Q+ ]( {% T
18.D3 n6 \5 ?6 H. }, s. ] y# k
19.设计模式
- Z1 H- t( I z20.D4 J3 F6 k( j9 U/ x7 a
S3 w. F t2 \4 C
% d+ u; j! F" Z# [
0 W) d& R* A f: S" }
答案详解
9 Y X: e% R/ s6 x8 m3 P& y* n% T4 F6 y$ P
1.类是对象的蓝图(对象是类的实例)。6 b+ c+ B( Z6 Q, n+ B
$ t% O/ M+ j( R2 p c8 x4 N
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
4 R5 j$ Q( x( }* Z
+ D+ f+ R5 Y8 N( B3 Z# e. {3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。/ h2 G C/ v: k
5 p' Q7 u6 o5 z3 L6 `4.单件模式可以限制一个类被实例化的次数。5 H! Q$ `$ R, |& S' ?* q
# ^6 M/ e5 w0 C; F& m8 I
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
* K4 S. \* _( @% Q9 [$ o2 d' Y% }+ t4 w/ R" q0 x" g0 H# g: g7 F
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。& \7 ?1 g, M0 n6 c; S# v
h( M- ~: Y! G3 P6 c- P7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。( C5 ], g2 f' t
; J' L9 c. _, X( ]8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
* O7 A2 E" P& V' ~2 @5 S$ {/ J( L2 X& C, S7 K# f+ f% Z
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。$ M- f( M I8 V- b9 j
2 @" [# A# j4 ~ s10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。2 q7 e- _0 H' ^
% t: ]+ c% D6 S
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。- A$ X/ P7 d' h: e- U1 q8 E& o
) n& D4 [' X3 t8 r8 _: T3 u12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。2 `: y9 z0 e' v3 t' h4 \
! ]" z0 c% t9 C; l$ {13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
/ w* e. ]4 X6 ~% F A
7 k6 t) R9 K6 s$ }, ~5 ?( {14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。 Y- b+ Y* l" k+ j" L9 S
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
! r5 z& d! Q. u' p. _9 v* q; w1 g9 H! K function reduce_fraction(&$fraction)
; M) G1 O/ \; Y: y/ B$ P" @答案是D。6 T* C. }, i, z
' s5 t, A0 t: x# P" H6 S
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
6 K3 A; t4 T$ E6 j
9 O: y% @; b& A6 G& J16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
! `3 R8 B, o( i. c# U- W% l& N7 q$ x; O" C- v3 E. L
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
; r+ R/ J" e" C3 @* `. c
) Y; Y" b( d5 @ B0 F" ^/ ^+ V18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 B# F7 A6 \" [7 P$ P, D+ G
% F3 e) U, ?, v6 O, E2 U0 [( l19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。. A! F7 u! u" i) _+ C0 q7 k
0 r/ z1 b9 k1 J6 b' G20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|