  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14161
- 金币
- 2371
- 威望
- 1647
- 贡献
- 1319
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。5 N1 L& i7 y7 a6 z
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。7 l7 i" K g0 c
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。! e3 B8 K7 ~: e( |* O% J
+ A9 l2 g" ~2 i
问题6 b; \- l7 {( e) N
% F/ r% S+ Q. y1.对象的蓝图是什么?# B: T! a; a. H" q* r# U0 j
8 }& b' A' ?) R8 G" f答案:____________1 p. P* e3 Y8 K! S1 n
/ f4 p; E# b! K& ]. ~. \2 T2 i% E6 n5 n5 x- 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- c o9 T/ y: Z# ~, i* X
B.b
9 K) r) k1 S* B1 i) n6 ?0 FC.a s* V+ r" C* v" _8 r
D.d7 I% |8 j! M5 p( _1 G; `9 q
E.e6 g9 Z4 P8 l# e% l7 Q3 K
9 j8 l8 C1 R/ |0 F: b O. a+ c( N& e
3 R L' L3 C8 U: Z3.如何让类中的某些方法无法在类的外部被访问?- T1 R. |1 M( ^' Y- j7 _, w) r2 _
- I0 U* Q- p) L4 I" @A.把类声明为private2 C1 z H0 R: A# e) N7 _
B.把方法声明为private4 `( M% V8 o, v* d$ O- F' ^* a
C.无法实现
# q! o: R: Z5 OD.编写合适的重载方法(overloading method)
* a F- G- j2 B5 c' Z1 R2 u" V4 Y- b* {! N2 D, m3 Y% z
% Z, m) _9 W, z! o
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
8 j& T1 h& }# a$ T! {8 f: y: L
1 O3 J/ T* E/ c* x4 cA.MVC模式* T# W# Q u7 O1 a2 P" P \" V
B.抽象工厂模式(Abstract factory)! c; [ Q0 c9 L B( d6 ?$ u
C.单件模式(Singleton)
) g& S! b) Q8 w! D$ Z' K8 x) b6 X2 JD.代理模式(Proxy)
0 U) a0 e6 W2 o6 t) ME.状态模式(State)
2 N2 C* O6 Q& V t* k- J4 o7 \% K
( B4 @7 F+ H( l' _- J- q* [5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
* Y: @. q2 \$ U3 l& m9 Q! l& x
/ ~1 |4 N* W. m* @+ }: O# I uA.1个
/ @7 q# }, T3 a" t5 oB.2个, D) P! Y; X! q5 X
C.取决于系统资源4 R# I3 \6 P# h0 O
D.3个, ^) p$ k6 ^5 Z
E.想要几个有几个
" ~8 w% `, ]9 |0 _) f8 \1 y- n) ^ ~+ l% y/ {
: g. {0 F8 N( m6 S& V8 C6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承0 {) w8 D1 T7 Z# c) D
B.接口 c" F( C C1 K0 A$ |3 h4 f
C.抽象方法' t G0 d9 r8 A; t; n# I
D.Private方法
& ?0 v4 |% M3 H, L. F& iE.函数重载(function overloading)) Y, V9 Z+ z8 f0 d
3 n5 G# b8 M% Z4 d$ { i
3 t8 M+ Q6 w! K7.假设定义了一个testclass类,它的构造函数的函数名是什么?
/ B+ l) {- i( n6 t, M4 M& V9 b- S6 H. f/ U9 g& E
A.__construct
) \; U+ l% h" G8 p% o1 |B.initialize
3 d3 M* g3 G$ W) hC.testclass
7 ?- B Y5 b w f$ R# [7 y9 iD.__testclass; g8 D" \0 g0 l4 W1 _
E.只有PHP5才支持构造函数
& S3 p9 L! }# t7 S2 Y
$ n. F+ ~0 `" d# @. R+ D
: S& P: Q J( J4 i& J+ d8.一个类如何覆盖默认的序列化机制?
- ^1 | Z9 I2 C7 c7 O% ^$ m$ ]5 J/ x0 e" G
A.使用__shutdown和__startup方法; Q' g$ b% E. C# E
B.调用register_shutdown_function()函数
$ ^2 u) G. Y0 Y9 g8 i7 G2 h' jC.使用__sleep()和__wakeup()方法% G( T/ h F$ \2 B4 U
D.无法覆盖默认序列化机制
$ E K) w$ V9 W3 U( _E.使用ob_start()将类放入输出缓冲中
2 W9 P2 Y/ y, ^- n1 N' ]; P3 h" \/ c8 g
' o% O H% J' e2 A# z9.以下哪些面向对象的概念无法在PHP4中实现?2 M" J" G+ Z. b6 I$ B
1 ?* f; i: x) ?; X' G! [. [: a@抽象类
& @" m/ p, X8 V* k, u# Y- O@Final类; a. [ N9 _& R0 \, p9 q: D
@Public、private、protected(PPP)方法* M6 y' `" J4 {% l, p4 g! T
@接口
6 W* q, w# q& E4 |5 b9 ] O T
: V7 t" n8 O" C V2 {A.抽象类
, [/ \7 {5 T$ N: o6 d8 ]B.PPP方法5 w- M& x+ e! C0 Y d9 b2 P
C.PPP方法和接口
6 h2 Z7 E# k0 W jD.以上所有都不可用" W% A! T' l) l4 |5 T3 t# o- ~
E.以上所有都可用
# ?9 L2 v; N q# u. X3 g
2 ^) V, A- H. G. X* m! t3 }+ `/ S3 Z0 ~* |2 s
10.如何在类的内部调用mymethod方法?
2 o0 E- T% b: P) A; n8 S7 {( D1 k2 u% _: t2 b
A.$self=>mymethod();
' E; }& A+ M, O# X8 g7 i2 yB.$this->mymethod(); ^" C5 o8 }: o" q" S
C.$current->mymethod();
5 d! K: q. J# h9 UD.$this::mymethod()
1 F+ {& G5 s) GE.以上都不对
5 Q* @# Z O0 H0 r& y y7 K/ b( M2 L( C/ S
8 w Q* k ^/ g7 A9 s0 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
1 ?: p8 f2 V# M0 G) K2 [* T: nB.Null
' U5 g* `5 q5 ~2 ^C.Empty
" E$ g, `" C8 [2 O+ jD.什么都没有
; f# p; `6 z ~9 m6 jE.一个错误
' W; y6 m L' H3 N, s% M/ E7 j6 v2 ?$ s* N
/ a- F6 N, g. @4 l* g. z2 E
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$ k' C* c) f6 J( W
B.5' n/ p4 X- L% W% m1 E* V. X
C.22 M7 s0 J+ \8 Z* c: t
D.Null! X: I9 l, W( _# }0 b$ N; A
E.什么都没有/ J5 r& s1 H2 J( i
1 I2 ?& p* y$ t7 g; \ V( v2 n/ F* S6 |5 m0 T) A& y4 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
+ o: g! D# f$ ?3 o. HB.10
' S% _2 Q% o1 P% U: `. C2 LC.什么都没有 M, X+ m% ?5 `8 U( B& S
D.构造函数将报错1 Y( H2 H' s, w: y0 i
E.510
4 x. o# a% o/ s% Y: S! Z8 Q0 z; ]1 _; ]$ [. g1 b/ p
% Q2 B3 r& m# T8 s6 C
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函数必须返回一个值8 Z/ E5 {9 a* }! Q: |
B.reduce_fraction函数必须接受一个整型值
/ h0 P/ ^6 \) @+ nC.gcd函数有问题
& p, J2 N% {9 _2 ^! ?4 ?8 eD.必须通过引用的方式传递$eight_tenths对象
2 k' h ]" y( h) Q7 X& U9 ~E.对象的实例不能传递给方法以外的其他结构。
5 r: o+ c/ l# Y9 G+ G
) d+ e& f1 k3 O, Z- I# O3 @ L, _* m% k O, `
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
4 } k. _2 U) a4 z: m+ zB.生成myclass的实例并调用mymethod方法
5 E& J# z7 c7 T7 a* G6 J4 ]( mC.产生一个语法错误
- @8 V- b% } t9 N& d+ pD.默认myclass类最后被创建出的实例并调用mymethod(); R! v1 Y* w. N2 q0 v& k7 p
E.调用名为myclass::mymethod()的函数
! J# _/ S. B: \) U; r" M3 i/ K$ S9 x; R: j* _% e
' T6 O9 s3 B6 x5 }! Q16.PHP中有静态类变量吗?
7 e' f- Z* _1 }$ f) m9 d8 m" K3 U) a% X$ p& R0 x6 A3 a8 e
A.有9 X+ G- q; _0 H4 X* n. x5 ^* A- L) q2 F
B.没有' Q5 e \8 v0 o; [$ Q' s. j. T
3 p- [; T6 n f( H8 C T, Y" P) O
! }# n7 k$ M M" _
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
/ f/ @1 ?5 a5 y; D @B.2# ~4 C: o6 g: i/ a$ }. Z
C.一个错误,因为没有定义a::$myvar0 l/ [( h& |5 F' Q0 j: Z% y9 k
D.一个警告,因为没有定义a::$myvar
" s- h; p2 O$ a% O1 {5 U6 RE.什么都没有
3 Y( v5 T/ f1 n8 e, s: r+ Z9 {3 F" K) Y% [
$ Z7 b2 V: b0 z) M7 ]4 \
18.如何即时加载一个类?
p8 K' F, H+ h5 e1 u* q& I- e& {: X y
A.使用__autoload魔术函数
6 a4 A& ~. D/ z" E1 A' ~B.把它们定义为forward类
# z% D" W& `) B! c+ UC.实现一个特殊的错误处理手段
8 j5 ^3 r, p: p" l8 V8 PD.不可能7 A9 P2 j. j8 w" {6 z
E.用有条件限制的include来包含它们
* R5 }9 n" g1 p( W6 M z: T. W) c5 O9 H( w4 \$ g4 V) v l; m0 x7 T' {- S
& {$ z3 m) }7 f0 A; ~. d$ m5 P$ f19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 J- H1 M0 [$ @* ~$ l9 Y( M7 A
0 p3 q; u' F) l2 s c 答案:__________
( @& s( p* f9 w( R
$ r3 a5 \3 N- i
, t% x% ^+ F5 D- D6 K# w9 X/ d20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called# h7 y8 z+ o. H
B.一个错误
7 w+ ~: U: h7 HC.一个警告6 z! @- w; c1 y1 U; c
D.什么都没有, P% Z/ m# S6 X$ p
. ~6 Z; T+ k& G
1 c! c9 V x, {- r& m( }: m
' A1 S9 U/ ~/ G4 {答案速查9 ~: K/ V6 M7 u; C8 S$ y" t* [4 F; i& ~
1.类; o! L z9 l" t5 j1 ^) H" o6 k
2.BCD! Z( t9 o5 n" H" Y
3.C( z! Z7 p/ X3 Y I$ m5 q
4.C
0 J( \3 b( c! d6 Q, _6 x+ v5.A' @" c4 x3 ]) s" P: d& Z
6.C9 I+ _( j: {7 z" K# u+ t% ]) E
7.C! Z7 g) }. e2 b1 m% X3 p* r, {
8.C
4 Y4 B, U/ l# p9.D
4 g* J3 t# g$ D& U* G O$ s10.B
- ?$ L. I1 H( n" _11.D
o1 C% Y, \2 h1 ?" O0 U9 j8 [12.B# x" L1 h! C2 a
13.A6 W; Z: i% N7 e! k" }7 L6 p
14.D
, L( ~* p/ D/ y" n; u" i15.A
: d R' C4 @; R) v2 C. r$ J5 W16.B
+ H, Q0 [6 W% Q# c8 t, _9 t) \1 H0 V17.A+ w* y/ ^7 k* z- ?
18.D# V9 r2 A0 B( n, m, W+ x% }
19.设计模式
3 |) P" y. D* D1 \& r& a$ I9 h; ]20.D
) H/ L# A Z6 K+ y- n0 t9 _( p8 F: l7 C$ S$ e/ E7 Q
, W% x# x- a7 a3 T
9 u$ l* ^% t" p答案详解
- z$ C1 p( Z- z3 H( p3 o- ~0 m" k, g! H, u4 g
1.类是对象的蓝图(对象是类的实例)。: L" W2 a1 j( q
/ i' ?9 B# h. |- W7 g, o
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
( ?/ }$ U# ?, J/ ]; k# Z
. |; a6 b3 d. b& J$ O0 g3 c3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。# e) K& O# H) `$ M1 d' x& G
0 y7 ], v4 u! ?, |" N" h' q; r; c4.单件模式可以限制一个类被实例化的次数。) U3 L5 o1 \' K; E1 ~. h
1 ~; ?: `" C7 N5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
M2 H' q" @3 S+ U" `
|! h2 I4 K( u. O& Y6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。: W* g, M# W0 B3 _
3 A" L/ d/ J% K2 J' p2 w
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
& \3 X+ o9 H7 P) Y7 b! d1 g& h1 W8 G8 |# b; P4 x
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
2 y$ V8 K9 \4 Q8 T
; W* t) S& J4 w8 u' D/ u% n$ c+ X# Z9.PHP4中没有题目选项里所列的任何一个概念。答案是D。; [0 h! |! T6 n: M& W/ {
8 O- Y4 K4 b' H& F. F10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。4 c$ H# T3 R+ s" L H
% B6 T# s! {4 T+ a9 _" W11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。 @* ?) e x. O3 r
9 W" e0 M) L8 v( P9 `12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。7 A4 ~$ [! w/ B1 j3 P1 ^4 ~
2 b7 p H3 D9 L! q2 {( U13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。. }3 N* E. A% G# }9 M; q) a
- p, C( P% A; E* ^1 E14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
F" i3 H! i4 e$ Z9 w; I8 E) ?+ l回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:; {. a/ M2 B4 t7 Z+ x( T3 q
function reduce_fraction(&$fraction)
/ }+ N P Q0 U" c# ^答案是D。
" J' V, M. A) \' n' a) H
. U0 r" g7 R) `2 ], C" n" [* `15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。0 e) P: o# a5 K P4 D2 h
9 l( _5 x6 f: r I6 ]16.没有。PHP4只允许声明静态函数变量,没有静态类变量。$ z1 F: t' G8 ]7 O
8 K4 Z. B7 s% Y/ L- i* b7 t17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。" R, ^1 F8 `6 C0 _' V' }% w0 l
7 m, M( Z0 ?+ p/ G; C& ^; ~* b; U
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
2 m8 c+ k; f' X2 i" U; P- m+ ?9 j3 g: X) p% l% E
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
+ K- W: H! _2 ~$ `( g3 W0 p7 e, ^8 T* c# A! Q+ C4 ^- R
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|