|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。- E+ P$ T" U3 m" C ^
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
6 L0 x P) w3 P# d本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。" L7 j! k3 i9 M" G
/ E! F) D! I" u& ]
问题$ B# u; }* F$ s! Z/ G
1 s7 a0 c4 B6 R; [- E1.对象的蓝图是什么?7 U, `* u6 C4 M( v
7 b% {. {1 d/ y8 Z7 n( l答案:____________, ~0 P$ y) [/ }( _8 M' F
9 u. ]2 t* u8 b6 w( C
1 o2 u9 n S4 u# I: Q; y2.以下代码执行后,数组$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, e( X* E M1 V( K2 {
B.b
$ |( A+ Y- n( J* zC.a
. w+ O! u w' R* [/ ^& |D.d
. O$ p( o9 ^# A; U7 V( U1 n9 NE.e$ n/ b/ l, e4 }9 \! u' `& W
1 Y( Q$ |1 t! {- N
+ T* |/ I" N2 ]" m0 f" Y9 o3.如何让类中的某些方法无法在类的外部被访问?3 a: B# w* {3 |6 Q: A
: U2 Y8 J9 [5 ~A.把类声明为private7 ~# m1 k9 c4 S7 s$ e# H6 X5 W
B.把方法声明为private
' u9 m# I/ G7 Y X, PC.无法实现
" y7 b% n* V q& p9 uD.编写合适的重载方法(overloading method): q1 f9 t1 I& I! t1 q
, o6 ?) l- t4 L8 x2 L# b8 W
2 h2 S% p; x+ A* N5 Z9 B4.哪种OOP设计模式能让类在整个脚本里只实例化一次?/ |% Y3 m) w4 o! O3 ^& `( c. N
9 b% W, u' c1 V+ J/ _( P% s1 f& R
A.MVC模式& j; i' E7 N0 @8 m/ v: I) @; A
B.抽象工厂模式(Abstract factory) ?% |0 t- _+ ^! A3 K* _
C.单件模式(Singleton): W3 P) v) W6 D6 k
D.代理模式(Proxy)
5 z- M2 @3 b( D6 l8 bE.状态模式(State)
) {4 B+ P0 i- P$ f) X+ ]$ ?9 L! L# X8 M: ?9 m' |
. L1 [$ H9 | Y# A4 v0 I2 W' G. ~5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?& _* h* E/ J0 L) e! F: ?
3 |. n% m2 a2 _$ K& B4 u- ZA.1个5 D I( i; n6 K/ @$ b e
B.2个 K+ |9 A5 G5 {$ C/ Z
C.取决于系统资源+ O7 Z w* _, Q$ N. J
D.3个8 l( C; a5 g, d% \" Q& E
E.想要几个有几个
& x& ^, |4 c$ C3 a$ s+ j- b
3 i$ K) b1 O1 T: N$ E
; l8 _2 Q4 E8 q w) w% K+ m6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承. \" o. c! t( |; @: H
B.接口/ y1 I( o& h3 A$ @' N( w4 \. U
C.抽象方法
# q+ y% O* P* p3 P, d$ }D.Private方法
/ p2 F. d* o% Y$ ^. F8 ?& m+ h% rE.函数重载(function overloading)
5 U! M0 F' y+ B- ~% Z2 |
* H( ^1 k$ C9 W$ r1 C4 }3 ~; G/ u5 [) @. D3 D4 c
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
+ Z- l( }7 `4 m' x9 D
5 q5 y4 e* g! a" B# C0 u- @A.__construct
3 I/ V/ q. G0 U, ]6 Q4 V. RB.initialize9 i$ D: H% }0 v' ?# H5 `3 t
C.testclass. Q1 o3 Y" c& u! V/ K# \5 b" v5 f
D.__testclass1 s" H( p" ]& F
E.只有PHP5才支持构造函数
/ P* |/ h7 A7 l. k! s
' |/ @9 D5 K! W; ?2 h
2 ?% O5 @8 W/ i4 P+ A: c8.一个类如何覆盖默认的序列化机制?
5 }: j% D7 X/ A# i( ~2 W; h x: v: Q2 M( t3 J4 \% B1 V8 N/ X
A.使用__shutdown和__startup方法) Z& r, ~8 i P8 u
B.调用register_shutdown_function()函数4 P0 t) f' r! b! L$ y% |" n
C.使用__sleep()和__wakeup()方法2 x& h, C/ X* X+ C* W
D.无法覆盖默认序列化机制; k9 T- v& d* s7 c4 S
E.使用ob_start()将类放入输出缓冲中# H' V) X& t' I0 c v" L0 M7 C
$ `9 k. k2 M; y) O' t4 @
$ R0 |5 D, r5 {5 \
9.以下哪些面向对象的概念无法在PHP4中实现?
. r. f1 ^- ]; b1 g1 a% T2 g8 c* N7 I! k, t0 E$ |5 a% C
@抽象类 c; f/ k) ^2 A' ?) C
@Final类
+ N0 o) N- ~! [2 {2 W@Public、private、protected(PPP)方法
1 w! O) t6 J' N( ` w( }@接口$ V* Q" n) o E
1 T, M0 o' O$ p$ wA.抽象类
. y7 F/ t! ]9 J8 L$ S( C6 eB.PPP方法
/ F7 N. K, v; _! HC.PPP方法和接口$ Y/ }$ X5 N) {+ L d
D.以上所有都不可用
, h# i; X5 G0 ], V% ]E.以上所有都可用# i+ X( u1 V" B* m: d5 q
2 r& M% j" P. F+ O* Y+ v* c2 Z3 _, K: S8 {5 R2 }
10.如何在类的内部调用mymethod方法?: O* I, \- x* b s
/ T, v7 L. B0 |9 |* bA.$self=>mymethod();8 e$ O6 N! N: l+ A
B.$this->mymethod();6 S: I) {! ~( r4 } j
C.$current->mymethod();
{% A2 [. A: J* H nD.$this::mymethod()
) Q7 X' Z6 ^, T* GE.以上都不对6 [( ~4 z8 n4 V$ I5 }" z
, V6 G: u5 S" |' |8 [, X9 D/ l V" O
; ]/ B0 b9 ?' n+ M3 d7 _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
' X- P& m% B: N* `. lB.Null
/ N! }/ w4 q: E9 ^) i/ j# [C.Empty1 D+ g1 m; c: E, W! ?4 D8 O
D.什么都没有6 [% R2 V; b1 r6 c4 l7 p8 @
E.一个错误* x$ y0 z$ S' N/ G
' J. ?* F/ w: y2 Z, C) C
/ D8 L& L( O/ P2 L" Q; i! w12.以下脚本输出什么?-
- <?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
" z9 x. a' X. X3 hB.5
3 ^; ~5 g' u! o% E4 AC.2) I2 s% w5 }- i: u9 x
D.Null+ H+ @1 b: w. z5 [0 ]$ r5 P
E.什么都没有
H0 q" y: C6 n9 I! j0 b8 R% r
$ S- l# a8 I6 n; d) a; V& c! y& A0 G9 t) v& d" S" g
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) P3 C, j/ V) n6 t9 K) L
B.101 n" N4 ~3 y2 B
C.什么都没有" X. U& y/ s& _- d4 E
D.构造函数将报错
- c# w; R* L( J; uE.510
# v8 f4 `% r4 O# ` `/ O. G
3 j) Z( L: ~4 U2 M' `6 B; U$ {5 w5 \3 `
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函数必须返回一个值/ m Y& U9 Q4 @# B% P1 m" ~+ B
B.reduce_fraction函数必须接受一个整型值
2 S! h/ U4 F4 ~8 ?5 gC.gcd函数有问题
5 P) S1 f- ~8 n* X2 f' ^: |* `6 U8 ^D.必须通过引用的方式传递$eight_tenths对象0 H/ ^' Z3 X: M$ G9 }
E.对象的实例不能传递给方法以外的其他结构。
, G- @7 d# ]4 C. s( H& v: z1 L+ {( X: d' ~- D
$ y: l' Y5 k; l) a5 p) |$ i
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法- l+ o/ Z0 K; T5 X; B/ H* J
B.生成myclass的实例并调用mymethod方法7 b! r& D# X0 c- ^% m5 M& X F% K6 w
C.产生一个语法错误5 {3 n' _5 l! r* K
D.默认myclass类最后被创建出的实例并调用mymethod()
5 j+ Q3 S! B `8 [) I( z% |7 JE.调用名为myclass::mymethod()的函数7 x+ v# m% s2 u3 j# m# i, T4 m
Q& N) D! H3 n# k. g, }, b8 l
' I; P. K5 F5 W9 Y16.PHP中有静态类变量吗?, Q$ G/ |! g8 a* k& ~2 n" p
4 H. L8 o: X7 K: ]) {, JA.有3 u, s4 d. M' y
B.没有
3 Q; o8 r" t5 m7 W. x+ _3 J
) y9 Z, Y4 K/ H. C% j
8 A. e* G/ h- x% F+ f$ }7 X& f# D17.以下脚本输出什么?-
- <?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
& B- C0 h+ s. w# ~0 p- J% ~B.21 M p/ B+ m7 v4 `, E/ L
C.一个错误,因为没有定义a::$myvar
% |5 e, e5 U! e- }% ~- @6 MD.一个警告,因为没有定义a::$myvar" I' B- r4 U4 Y" n* a# S$ C
E.什么都没有8 R: |! {* M% I8 o) w
) b+ `" T: z8 M* b0 X9 M! E- p3 p
4 `" a; ?. ?# b, k* A: O8 G
18.如何即时加载一个类?2 Y9 X9 o2 o, ~7 t6 z
! K* {8 Z1 W+ s/ ~4 @' _& D/ ~! h5 H$ c
A.使用__autoload魔术函数
1 R7 j- b2 Z7 c9 D( m' t& G8 \B.把它们定义为forward类
" o7 v/ @: {8 g! bC.实现一个特殊的错误处理手段# t) X, s# C: m9 {7 J6 k0 t. ]
D.不可能 i) m. w% [; T+ E1 z7 u' n/ }
E.用有条件限制的include来包含它们
- L. {) z% Y* V- n% }5 |
. p/ N. k3 H# I+ B" I! V; U
; v# u$ p* a" L- Z! k* P1 x. v19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
" X0 o, s: g. O7 {1 d6 y, q/ V, ]/ ?( \. |: r: |6 i( K% a& j
答案:__________* Y/ I" J9 d0 H$ Q c
- E q1 K$ P' @. N% `% C! w: j
' } Z9 J' C# {( m
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called" G# W1 \. a. Q L3 |& x; l
B.一个错误! N$ Z) \' V$ h$ k5 j+ J/ n- H
C.一个警告' Q; G! K" P- u+ L$ D
D.什么都没有; o' |. ?0 }# B; [- [. M
8 W( t. M% T, X4 g5 v* D) {
( o8 \, o# p; F8 S$ z
9 \0 h" r$ l. Z* T+ H
答案速查+ f- C3 l' ^6 `9 {& r! v
1.类
! }/ ^3 h0 x! T+ ?. W5 W3 ~2.BCD
/ v# p% Q4 a0 n9 o3.C& \$ ^) v" M% H2 t5 S# F0 l' `; y
4.C
& ?( X, ~' y0 ?3 n5 K9 O5.A
9 d# ?+ T8 X( q! X8 \4 o6 o6.C
$ |; v1 |+ ~/ B7.C
! a) ~7 s) A% y8 b+ h0 j8.C
# \% R, R5 J/ L$ n! ^, ?6 O5 `2 h9.D5 r3 l+ h4 d" O& Q: _
10.B
& G0 I- d6 v2 n11.D
1 D* H' J! w9 y* p& A12.B
2 A/ k; w# P( E( T$ [13.A% C. _! ~0 y" J
14.D5 I- F/ \% K: h2 v
15.A
8 R5 I* H# D+ {16.B9 ?) ^1 Q7 z o% D
17.A
2 V5 a; ~7 [, w( t( {4 `" f18.D
0 e. Z. Q; m4 Y" r4 P# y19.设计模式
" _/ Q5 ~$ ?$ m; Z6 O8 ]4 W20.D
( Z! L0 V s2 D0 M) l8 L# K, Q8 v
) ^* G9 I' ~7 v) D+ L [4 v! k4 m1 @% `
9 R7 \% H4 @; x- c9 o" Z) X答案详解, ~7 [" b% ]* v( E
4 [' B/ |8 L, ~% _4 n0 ?# s1.类是对象的蓝图(对象是类的实例)。
; ^3 I8 _% X3 T4 g; X, L5 |8 C% u. o% V6 t. |" ]; B* S2 T. s
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
. _# o. Y4 ~% K7 @( O$ P: q; R# M% T) n4 D
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
5 w! O' [/ g: q2 v: ^2 n3 S! ~! Z1 g+ O8 T7 u2 E% X N; S1 F1 r
4.单件模式可以限制一个类被实例化的次数。: y* U( N( `# `8 T; [
" x- n" D( ~: A9 }' D' M
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
9 M2 C4 X. t. W: a
$ `8 U9 U/ M& h6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。2 e O% |+ b7 v3 Y0 M* H, p5 y5 N
" M6 w( g2 q$ V# q: ` M3 R5 {7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。# b8 o& ^+ t/ \: L1 R
6 |0 o3 G0 G0 B
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。! Z: w; u+ W9 M; ^) E
1 y# ~+ l; }, e, k2 C, g9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
- f4 g _7 c+ m/ T6 V: s
) Z- J! I0 Z6 F9 q8 }# j10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
. r- g. \% n4 `0 w% H, r2 j* @
- Y4 O9 ^4 V5 n( n& ?, W; m3 V11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
4 @( X5 x' u% K% u, ?; l. X: k/ R5 y! f2 L
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。: ]* I9 |0 l6 x
* q- v1 o6 k; x( L3 j3 j0 j3 d9 O
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
. Z# S0 h6 }8 d3 \" Y& Z$ W1 D" z y: l ?$ S, n, Z7 R4 c
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
* I7 r1 Y, W9 R! Q回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
% J+ j- a2 G$ @, o0 U function reduce_fraction(&$fraction); T7 T: f6 r! ?8 A8 A
答案是D。# ?. G6 h8 G9 R/ _; ?
% u& p K, r3 J! A& p! e
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。9 ?' `& y1 z9 }, `
7 d' R: a# \6 B" }9 T, \- P16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
9 ?5 s X/ b* ^$ F) w7 I6 y& S2 @. [& k8 Y% T. x! _3 ]
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。2 N! z* G, U2 `6 s7 |' n
7 A% g# e" S3 @3 u% I2 I
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。" W7 p; l- W1 M8 j8 W" T+ ~
1 S+ O' p- n! i' x @& b# @, t
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
# g/ b7 V2 l% v) h
& m/ U; p) R2 N20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|