|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14391
- 金币
- 2481
- 威望
- 1647
- 贡献
- 1429
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。, K C3 G6 }$ r; w! G {) P
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。8 z7 h, a, X, ^1 I
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。( G" z, `1 I9 G% x# F7 Y m
* U9 N! f! j( Y/ R" b$ g
问题! V, P: H& A$ {/ I: E
6 L0 J7 W8 t: p1.对象的蓝图是什么?& \1 t0 q6 a1 M# G
- M& r% q, V6 x6 x G" W答案:____________
5 W8 V: w3 G6 Z" b0 l
. k) A9 Y+ J: ^7 h/ ~6 @7 k+ s$ A2 I/ u. r$ `! w$ ]
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
9 h1 t, o1 p3 a0 J% M$ ]B.b
' `' v- y$ E# D% kC.a
7 V. Y4 I' B B& }/ n+ T1 ?D.d
9 a, F7 O0 f% D4 ^1 u, ]/ T v hE.e5 x0 _% D7 K7 [ Q9 F% n
" Y7 h4 L+ N6 E" X0 A
# @ L' r3 o9 V- g* u! `9 l8 i
3.如何让类中的某些方法无法在类的外部被访问?0 k& k, k8 e; F, l- Z+ t/ u* r8 h2 C
8 t) H D+ g# O/ M7 {' |2 u. J( BA.把类声明为private
& b# I. g: Z. z$ G2 x- CB.把方法声明为private( |2 r f9 {7 t8 }
C.无法实现* ?5 L, C' [0 W# x' b
D.编写合适的重载方法(overloading method) A3 e, Y% Y; ~5 h }) R3 Y+ D
! R8 \, t: h( g8 r! b1 v: m* _
! @( Q/ [! V5 m3 C: m4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
i' _# g- B5 u& e
; ^% L# o6 j- N+ n2 [4 T0 U' PA.MVC模式
+ q& U! F7 k1 D* dB.抽象工厂模式(Abstract factory)
_5 \& j) M0 ~% Q7 PC.单件模式(Singleton)
* w. P: l5 j, a# ]D.代理模式(Proxy)
/ H4 ~2 t/ Q7 Q; u) W5 }8 Q/ fE.状态模式(State)
% z, g/ L# a" q1 P# O) E
* x6 L% u8 _: K# C, u+ t1 O" e2 z8 B( l' x
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
( @5 _2 n1 B1 k/ z' R3 ?3 E* ?$ o( n. L& Z# F1 w1 T. B* \1 U
A.1个' K+ Z7 O9 h5 u3 ~
B.2个
: _" w7 {9 {+ g. `$ \8 P4 J* VC.取决于系统资源( \! Q( A( \1 Z; a* x; |
D.3个
/ \9 x$ U! ?( a" Q8 r. O+ E/ D4 BE.想要几个有几个
8 Z8 Y9 L/ Z5 w: r4 J+ l2 c
3 R: {+ q# u$ ?9 ^8 f% [+ u7 t( Q# ^" D$ r# A5 l
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承2 ^' |2 w$ N6 E( U2 M& A
B.接口
+ I; j( Z; U3 D* {3 S* cC.抽象方法
- \2 l; l8 t1 T3 ?* DD.Private方法# F) i6 `6 y# }2 Y! Y: r5 v8 {
E.函数重载(function overloading)
; ]5 Z- ? z G8 n+ B+ o. ]( x! w4 A) p7 F0 G9 |5 B
5 J. R; l8 ]9 ?( U8 X8 `* N6 U
7.假设定义了一个testclass类,它的构造函数的函数名是什么?- ~ ~: e" y+ S b: b7 `9 b
5 K; W0 D8 y+ o" G/ pA.__construct
+ }8 g' I, f% e3 }( n. HB.initialize
3 S: [/ c1 I1 Y$ {8 ^! I! ~; e) WC.testclass
/ a/ D* [* Z1 A% ?+ O) Q7 h% ^D.__testclass
w z5 x/ m. }E.只有PHP5才支持构造函数
8 X3 V8 c4 @7 M9 N3 H1 [9 q" h
- d: h- u) ?2 T+ x% w
' T/ D* X4 | }5 u8.一个类如何覆盖默认的序列化机制?0 n" E- K' @# B# }& m: s& i
. a# E7 b- ^' Z0 rA.使用__shutdown和__startup方法 N2 x. b. k4 j0 t* A2 t" o8 X; i
B.调用register_shutdown_function()函数( y) r$ s: O8 k$ `1 C2 Z4 n
C.使用__sleep()和__wakeup()方法$ W3 m9 W5 L2 i8 o& v* \ k
D.无法覆盖默认序列化机制
) d& d$ j% G* C! v* qE.使用ob_start()将类放入输出缓冲中1 L" j* L' d- L0 ~
1 C4 ^1 Y! E2 k4 Z) K$ ?/ B" f0 T0 ?$ T4 i' O9 Z1 B) O H' r: r
9.以下哪些面向对象的概念无法在PHP4中实现?9 A* P# z9 _1 I. Y
3 G2 u" g- A" ^, k: X@抽象类6 h$ I6 e' Y% _5 z4 J. t! U. [5 q
@Final类" v* m0 Q2 v9 S3 l' j7 ]6 R
@Public、private、protected(PPP)方法, F6 F) G [1 N) _- A" Z
@接口9 d6 i; R' ]7 |$ ?
5 l+ G1 }' j ?( t* e+ r) c
A.抽象类# k B* C1 m- ~8 ?6 `( i, N9 z
B.PPP方法
+ V- t% Y7 G4 L" FC.PPP方法和接口7 {* t+ }; f3 y- N
D.以上所有都不可用, v# T& ]* { _
E.以上所有都可用8 C! c' ?) M+ \$ Y, z( a5 d/ j
6 }# A! o' M0 V p
0 G7 a( S `" |1 j9 H1 s10.如何在类的内部调用mymethod方法?
, }4 h! S2 b* J' h6 z! I( a8 Q! z7 C7 ]2 P# f0 r7 F3 B: Z
A.$self=>mymethod();
- f8 ^+ @, J) t k$ D( W% wB.$this->mymethod();% `( H& B$ \+ Y/ w
C.$current->mymethod();
2 A! h2 {- y# rD.$this::mymethod()
+ I' E! c6 b3 `& HE.以上都不对
9 O9 A: ~( X, D. Y6 z# ?
* H5 ]& U; Y$ U- x, q5 z2 |9 q( ~) L8 h8 H: v6 C
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
! |7 D( i% y( Q6 W0 z# u0 YB.Null) e4 Y5 I: l( Q& Q6 B4 b1 W
C.Empty
6 S) J: C1 R y4 s0 bD.什么都没有
1 F$ v: E# S- {: J% [% m" ZE.一个错误
, Z0 N1 A, o5 y% [
7 R/ Q" I. Y4 ~9 C. E$ _) Q0 p- J* q4 x$ Y
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
+ [ s. L. i3 S$ A: U# H8 }B.5( ~" G8 T) n0 g
C.2
8 U( T2 ?) ?* J/ BD.Null2 r B1 N9 l4 y& b* Z
E.什么都没有
! [: V6 c; w. q6 d/ J7 A' x. O# P+ ?* W+ ~7 p* P
3 s$ Z4 }& {2 s3 ^* m% ^# i13.以下脚本输出什么?-
- <?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
! c8 s, M" b2 z6 h$ H* ]) {B.10# R0 d+ f( `# w: C K- D" \* ?; [8 w; ^
C.什么都没有
# [+ ~' E, P9 o4 I3 cD.构造函数将报错* d9 A3 s& ^7 }! [4 i6 ?
E.510
) y. t$ H, r" W# F& J; ^, H
8 ^, N7 S) x8 R& b5 S$ u* @2 m, T* a' u& `$ t3 B8 H$ a- F
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函数必须返回一个值
& N; J$ f! B7 q0 sB.reduce_fraction函数必须接受一个整型值
$ P1 h! [! e) X5 Q I) uC.gcd函数有问题
$ ? u, u2 e$ t0 W+ F6 ?. ZD.必须通过引用的方式传递$eight_tenths对象& f9 J) g: x- r) J
E.对象的实例不能传递给方法以外的其他结构。- e( j5 E. R- Y1 ]1 y' e' i7 h' z0 P
9 ^" d+ _2 f7 a
' L: s+ y0 \/ N1 r' a ]' R& C15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
5 h1 j; @7 k/ _2 ^B.生成myclass的实例并调用mymethod方法
# y# e# u q6 ^$ v6 ZC.产生一个语法错误% E4 n& Q+ Z" |6 N! e5 Q
D.默认myclass类最后被创建出的实例并调用mymethod()
' q7 L0 l* L) e. t1 p- ]' vE.调用名为myclass::mymethod()的函数+ Q3 G5 V% C8 P! F5 c
' }! d1 |- R) T% |
/ b) y2 L$ B% Y
16.PHP中有静态类变量吗?
* f. r' B4 O* O2 w/ f C, }! a4 A0 s& M! m3 e4 h6 G
A.有
! S7 @/ E! }' {. }) u4 D. KB.没有5 c# H. S8 V/ n; ^8 e
5 w# d; { m6 w5 k4 S: K3 k
8 k# U7 ]/ |& z# C; S: 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
& O7 f4 |" H2 R( f7 YB.2- P3 l4 U3 h8 s2 v/ c$ `6 p
C.一个错误,因为没有定义a::$myvar) Z8 A$ h2 a0 N( n( h- e5 ~
D.一个警告,因为没有定义a::$myvar
# n& ^) ]1 Y/ S: F3 ]# eE.什么都没有
4 x7 ~3 W! J; Z j) E) B+ U4 q- C; K0 G# d& G6 q! r- f
3 t. n2 H/ H. s& w5 T4 ^
18.如何即时加载一个类?
0 w b4 J9 B7 V; v. A, D J+ ^- Z/ Z2 H3 H6 E( J# @
A.使用__autoload魔术函数
2 F; ^ p$ ?% g( c4 O( I: `B.把它们定义为forward类
1 t+ y5 ?1 O: V4 d; \% x5 KC.实现一个特殊的错误处理手段9 D8 b: g* q9 Y3 l5 ^# g7 H
D.不可能
3 P' o& ]7 M- c ?4 HE.用有条件限制的include来包含它们
2 B; ~- D+ n' ?+ [5 W+ ?5 V
8 I) ?7 W' o3 k, J8 y9 ^9 u# z; Q9 s! e( B
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
2 m6 \: F- N& V8 n- }* C# r
0 I* B5 u8 I! }9 p( ^ 答案:__________
8 f' ^1 p3 W0 t8 }
. R3 o+ \) [. q# b" J- j _$ w' ^& U2 b6 \& G& u0 {0 b6 L
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
# r9 s. j. Y7 {, y; ]B.一个错误
7 L0 S. |. o% R% ]- v$ |( RC.一个警告* }; P. k1 H# G- O8 U0 K
D.什么都没有# }& W6 p; F( a5 @8 j4 Q
) n( @3 [+ {& J( F; o
1 p+ `9 T' d) ]+ A& Q' U! |- y* Z) L# g4 N, H! V
答案速查
: v& z# I7 U: i6 U* }6 D1.类7 q1 y" x7 ^$ D8 U, |0 b8 E0 G
2.BCD
4 a% s1 t$ {% i, P+ J2 p; W+ ~- j# M9 F3.C
! h! V. j H& ^( V9 P& H4.C: B6 t4 M3 P# M- O/ n- u
5.A
) Z5 }8 u! T$ P6.C9 K) _0 r: n7 F: s' X$ X5 M
7.C) @ z2 w7 T# q8 B) ]' z7 B; _
8.C
+ u- {* L1 P. Q1 j9.D4 G' t6 V6 C) f; |5 X7 T0 G
10.B
/ G- E6 W7 |( a7 S11.D
' m1 H* Y& p H/ P( s& }12.B
1 Z! t0 b3 f% C% W13.A* }' q9 n/ f' [3 Q. j+ o5 T* r
14.D8 _2 v4 p. |: l) M6 r3 H; S7 j# x0 y' l
15.A
+ i2 E- {. ]" E* X! h16.B
8 h6 z4 }: x# G# ` X17.A
6 Z2 g' H+ c# ^3 X/ e$ w18.D
! Z- Y# I7 H4 G9 U- @/ s- a7 [19.设计模式
$ ]; K5 F- s Y0 {/ S% P5 W20.D! i% k/ J6 Z( ~8 k) j( D5 F
- y0 Q3 d" x& N9 E4 H& b3 S" z$ O7 C+ x$ p+ ?* H3 \
5 d4 @3 K+ i6 \0 `& b3 u
答案详解
+ x% Z D* B3 }! `# Y9 J
1 e1 i4 G* h7 g& G( z7 E1.类是对象的蓝图(对象是类的实例)。
4 s M* F* h4 M% W
. \' Y# Z/ u, L8 @6 G" ?2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
1 F2 w$ g3 c8 D# C; M( Q; z/ j A# b. G8 ^
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。6 o& m0 k0 e0 g
x) M P9 _( B* d3 }4.单件模式可以限制一个类被实例化的次数。+ d3 Z6 c* T% B9 m7 ?$ ^, O8 R
6 Z; z2 R& }0 F8 c1 T. _5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
% i. Z) E& o4 L9 s& ~, J
1 {- ]) O" p' Z6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
% Z( d" Y; i1 W7 _ Q8 B( _7 e- E3 p6 s
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
/ |7 H9 T/ M$ Z& u9 ?1 R& ~; B8 t, B' Y+ w0 _6 z# a [1 W/ Q
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
4 p+ [. e r) t4 C6 Z3 g6 h) j1 @* k6 l
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。$ }" x* R' @5 \2 ^3 C0 Z, Q
/ p% K9 k$ }3 M, t+ [10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
! l1 J( R& @0 N& U F) h3 B- Y. E$ ~$ I! w; r- G
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
1 I" U0 @" j6 _6 t0 n
6 p6 }- s: `( P1 |# i/ L! U, Q12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。3 `. ]0 \$ P' ?) f
7 W4 \ v. a& [, s
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。- ]7 I6 C) L9 j! C, ?! |
) o0 C, ?6 A* }6 ~ W7 ?4 ?$ d
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
+ P7 f- ? C" j8 I回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:! C& k; F0 u8 I: x
function reduce_fraction(&$fraction). A2 g0 y% c3 x' j& `
答案是D。
1 ]; H0 z0 V$ G7 { i% ^; L
. M# A- b/ m- B15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。1 H( |( ^9 U# b4 L2 `
( l9 ?1 C% u- T2 y" k16.没有。PHP4只允许声明静态函数变量,没有静态类变量。* [* F. {" C( h6 A
# J; @& C5 C3 h2 X5 o& E% |
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。8 _" M. G* w6 z8 A
3 A$ T8 s" C. S* G, O+ | F, t& A
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。) o7 c9 i. k; O: q. @
) Y, Y+ J* `! F+ j; K7 |19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
) d# y7 r( f9 U }
$ J4 Q: A3 m3 u20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|