  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
: D; t( W" i9 F6 x2 v1 z" k% RPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
9 }4 t3 v$ e: C本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ V1 A5 h: S: i9 c) L; `( t1 P7 p; B4 e8 y, }1 b0 v: H) B; t
问题& {/ W7 A% X/ P: @3 R
7 p; a+ H. n5 R0 t( J7 b1.对象的蓝图是什么?9 x4 [) N2 g; z+ y, ?' E$ B2 U
8 j" r/ e6 G& a* V( B* Q& b答案:____________
& m' D F3 y: L5 z9 t5 O M5 R4 q$ ]% {, g8 O/ D2 a0 H
- ]0 Z+ Y' w! m- d# L2.以下代码执行后,数组$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
/ l# [- ?9 E+ k6 W# U+ s; W" u# wB.b" p; t# _% X! |7 l
C.a
- `0 g4 y! }% b! ]& {D.d
. b- r& ]3 x6 v. D+ }& DE.e
" J) L9 \! ~+ M% E" x$ ]- T2 f9 n- A0 Q; I w2 o, q0 r
, u' e8 `! L4 T, n4 B( S2 q4 ]2 h3.如何让类中的某些方法无法在类的外部被访问?9 y2 E9 G! D2 ?* q3 W- d" z6 O6 k
% n( X. D* p" s% n
A.把类声明为private
. |8 C" f& A/ }4 T3 O$ b! g* w8 mB.把方法声明为private8 }* z% N4 k( g% D
C.无法实现$ d( o( q8 n4 I% M9 f
D.编写合适的重载方法(overloading method)
8 _; n0 v+ \- l% U( J+ V/ i$ n- V- u9 Q
4 p) }9 T( J7 P" E. f
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?7 V1 z/ E. j* h
) a- P' a* L6 J* q) y# ~
A.MVC模式, b5 x9 _/ P/ G4 O# U
B.抽象工厂模式(Abstract factory)" ?7 d. w1 i- A7 i* H9 X* M( J
C.单件模式(Singleton)
7 W: P; m+ k# o1 hD.代理模式(Proxy)/ ]6 c4 r) m6 e& b9 N9 D
E.状态模式(State)
7 H+ F' U. z2 J7 P& B. w) P' Z8 V2 I$ w' {7 Z; ], Z
8 R u) n* l$ F+ }5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?1 I7 R3 \0 q4 \# ]2 T/ [* K# k
x6 p4 B5 s9 Y8 `$ MA.1个
+ y9 I0 J. W7 I- }9 @9 X# rB.2个% G) y/ A3 i( y* v: d8 j
C.取决于系统资源
, l7 T! t/ C- D- T( p# DD.3个
- x8 H) d2 `+ n7 u4 Y( s5 d' ]1 RE.想要几个有几个
2 c" q4 B. |. Z2 Q+ ~+ M$ {; E: n c
. g& m3 d. C8 _4 C! ?" j8 D
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承) v5 C$ Q9 p# l$ L# T/ b8 F
B.接口
0 Z5 c7 v5 K6 Z. t M3 JC.抽象方法
: K* A1 r8 t6 h# q9 tD.Private方法
1 x; F! u- d' C4 s* ^* P" ~E.函数重载(function overloading)
+ s4 R, p( Z" E' v3 D& b# {/ k
( D1 m$ l: g6 P" @1 x, I( }; `% u9 b! C$ F" ?
7.假设定义了一个testclass类,它的构造函数的函数名是什么?4 }& }3 ?! g: Z& l8 K# N1 Z6 d
* a6 K: V' J& fA.__construct
. t* r9 ?3 @* j0 B8 AB.initialize& n: X& _/ p1 u7 n
C.testclass
, T& c% R0 N2 L3 b! HD.__testclass# n. [0 n* P0 i$ n+ W& U
E.只有PHP5才支持构造函数, z: z1 t6 ?+ E2 D' G1 R
9 t0 L# f) W( E
/ O! r6 E1 M+ w) m, k7 D8.一个类如何覆盖默认的序列化机制?
1 |" j1 u% |( L( c* N" W
' y0 T. t d. hA.使用__shutdown和__startup方法$ Y, u8 A, I: t% L
B.调用register_shutdown_function()函数2 a4 B U' _' P7 O0 a+ m$ Y6 w
C.使用__sleep()和__wakeup()方法
. ]( D7 E( I0 V& O+ DD.无法覆盖默认序列化机制! d+ F, V) m# I# J1 `3 ]- y. _" f
E.使用ob_start()将类放入输出缓冲中
l) E' }7 Z9 A* Y- d: |5 P# j+ Y" ~$ T) w/ O
, p z% }4 U% b6 q9.以下哪些面向对象的概念无法在PHP4中实现?+ }, q" V9 m8 d+ e
/ Z4 ~' r& o8 o) p" h- N. O& n& \@抽象类
9 ^( b0 J2 P! D1 A. q( n@Final类, {* p, ]# a+ H5 {6 e8 N( s
@Public、private、protected(PPP)方法 G/ k5 `; O" c/ i4 d+ [5 O$ c
@接口% T( @# h/ u! s4 r8 M
# |$ Y: d7 \! D1 r; A0 }1 m' x$ m
A.抽象类/ ?1 { S( j" N% {1 A, }
B.PPP方法6 G: G F3 }9 ^$ y) f0 }
C.PPP方法和接口* p% b' Y3 u2 Z2 ]3 j4 m
D.以上所有都不可用9 e6 @" M. y3 e
E.以上所有都可用; N# u4 I" F' t/ _
$ D9 t0 n: D y" G Q5 }6 @! M& H
" d( S b K% S$ J9 t' [10.如何在类的内部调用mymethod方法?: \! n0 @) @3 F! H& e( R( @* Z
8 X. B8 x( W- `! T1 T8 `A.$self=>mymethod();8 `$ T) B2 B9 r
B.$this->mymethod();
, J1 m) c" p- C4 T+ ]* MC.$current->mymethod();' g @- w9 `3 h: e& U
D.$this::mymethod()+ V2 ^4 K! M' h4 ?7 w
E.以上都不对2 h" u- R9 _' }) Z( f
7 U( U! c6 f+ g" f* J7 F
% e6 k8 [8 w, {! Z& Q11.以下脚本输出什么?-
- <?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
& J. @/ ^6 I- z6 l0 ZB.Null
% [) C6 f0 {! e) i0 ?+ K$ k2 D L9 t* IC.Empty
# a9 C5 p6 H" VD.什么都没有
! X- D) M9 o/ x8 v* XE.一个错误6 f' G. j: [+ U8 W4 G* f
* U3 j6 b" q: e0 o; D* e: {, n
) t# ~$ t+ c& j- P8 }+ q12.以下脚本输出什么?-
- <?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
2 r$ |% g- z* k# ^7 uB.52 A6 ~+ X' [/ n4 E7 g
C.2
' Z) c( h" K1 wD.Null
5 Y, M: n! d3 iE.什么都没有
" {1 h2 _5 T ?* t$ n5 b8 r
5 y0 }1 D8 i T
& r" a+ j, S ~( _9 K T/ ]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
) Z2 g' D$ q$ x3 a( |# iB.10
5 \1 c5 b/ a0 E; x7 {- w$ P- WC.什么都没有
" ^# k) T7 i( P4 r/ o6 x7 ]! HD.构造函数将报错
; {. C8 j, T6 W4 i% P: _7 `E.510
& C1 ]+ j1 f6 G% ^! u0 ^) u7 J& h) V) m7 [
y& H3 r" R4 b1 w& ^, Y* F14.考虑如下一段代码,执行时,$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函数必须返回一个值5 Y) L( E& \; b- ^, s
B.reduce_fraction函数必须接受一个整型值
5 I9 {& j+ r8 b. ]1 g. U4 E% f' wC.gcd函数有问题! w) i9 d. {0 p/ o% K0 I M
D.必须通过引用的方式传递$eight_tenths对象
3 f9 G$ u" _1 M8 e" z/ XE.对象的实例不能传递给方法以外的其他结构。" f& J9 I1 N1 `- q+ E S$ q
# Z, [3 J2 K+ v; \
& y: J: s* ]# \15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法 O* n$ K# s; H8 k3 I2 H F
B.生成myclass的实例并调用mymethod方法
- I# w2 D: m; K% ]# P7 [3 PC.产生一个语法错误6 R' R4 H+ i. ^8 {
D.默认myclass类最后被创建出的实例并调用mymethod(): J( x% Z6 I: `: |* k+ E
E.调用名为myclass::mymethod()的函数
4 K$ ]$ E3 ~' {& K
" i! _- a! m f$ B) y8 G- g% Y; U1 g8 R$ d8 R+ r+ f$ x- G( p
16.PHP中有静态类变量吗?
% e. ? z; z" P7 c3 O6 ^- X6 a% E( a% S+ v5 T o
A.有
6 h/ ~8 ~+ F0 P( X0 JB.没有9 |+ H' ~& S+ V( y( [' e
, [% ^* ]7 q7 c3 I
% e/ s- Z7 \# N- x% {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
+ C2 C3 ^& ~5 \# N! TB.25 ]6 K8 w) F: j6 ?
C.一个错误,因为没有定义a::$myvar
3 B$ e i2 H4 t6 C7 xD.一个警告,因为没有定义a::$myvar
, W$ R) @: [% B. UE.什么都没有. }# {1 R3 |1 S8 d) z2 O, A
2 P$ `4 [( R; J" w- w
7 U$ I2 R5 `1 p/ ^* a18.如何即时加载一个类? J: P i0 F& O K6 W" ^7 \: I
( s, I2 B9 @2 _3 c" Y( S3 _
A.使用__autoload魔术函数# \$ B9 M0 G, Z* M4 C* W; X. t
B.把它们定义为forward类
S2 [0 C3 A9 I" G1 b! k8 @C.实现一个特殊的错误处理手段
3 k% c" K7 k8 J; V: UD.不可能$ [6 P% a! P/ V o" k, l
E.用有条件限制的include来包含它们
]) Y4 G% V# \- S, {; p) B/ l. v1 c+ B; z+ K7 h
8 v/ A- A1 s+ K# \. G- A
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?/ J. Z% D* H0 s3 Z8 i
$ S% ~9 g: E; b7 v; W 答案:__________. W: n4 [- @/ E5 a2 @. d! Y/ Q
5 q. L {: B6 F# j6 m: E, s; G. |2 ?! ~3 f; x1 ]% k+ {5 }0 S
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
- T- D6 k% P' a- M8 GB.一个错误" g" X3 O8 R% B1 `2 o' _; [
C.一个警告
2 W9 `7 e6 y& e6 r4 y# nD.什么都没有8 l9 A2 C# q0 A% ^
/ H l i7 C" v* }; K
5 {- T" h1 l/ Y1 F: H( r
- r, L% }$ c6 f4 N" I答案速查
5 P4 Q0 ~( |" L7 }" U: o5 |+ j) b1.类
; L6 U. u) K- o$ h( G2.BCD
; S7 A3 O# q5 o$ m3.C9 Q V% W" d' z
4.C! P) Y( M6 u* M. d6 E
5.A. P4 E: h9 d, Z/ C. c9 m# S- n" I
6.C
, ]6 z0 ]4 k2 p+ ^$ g7.C
) m0 I9 D. V" ?9 M4 ^6 l8.C
6 O S0 o: S9 L8 I, g9.D
_! ^* Y4 L* Q1 |5 _: H10.B$ v) A* P/ D2 b: y8 x/ N
11.D
+ `2 J% i t; a, l! E; m12.B
3 w' B% l# j' m13.A
$ E3 M( [* B+ q: C V4 l, q) `5 _14.D
# X# w4 S0 G$ s15.A
3 ]8 [* Q2 T6 F2 C5 {' {16.B
: A; j8 L- q: b5 z9 I% a17.A
$ O! P6 M) S- \* b k, I18.D
^0 Z' W3 X6 J7 ~& `6 E, [19.设计模式
2 y) O5 a- m4 z. I1 a20.D* d+ O; X; D7 S* D6 h3 x. U' ?' u% W
4 a! j4 p6 m& S* ^- t2 u; A- ^
- @ x/ B" V9 Q s
N" f. |0 D! \: N9 |
答案详解
+ F+ B1 n" `. N% T O4 ^3 {: F( Q5 s5 z
1.类是对象的蓝图(对象是类的实例)。. t& ~% ]/ S# D% I+ u/ g' ^# N
# A" k/ I$ \, F2 v9 l- A2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。9 @, I) X2 K( o' S
9 @" @( \9 E, e7 X
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。" E, S- U8 w8 @- Q% I9 q
, k7 L% m f4 t# M# l; P& l% c) }( q" a) F
4.单件模式可以限制一个类被实例化的次数。
3 R+ |* B9 `0 t. r' A& N0 f/ E
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
2 d5 O% W' l9 |" o. n# P( V
# Y# r9 n4 o- S' P O6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
5 L# ]$ y* c8 l* o) R) G$ Q1 o# H& r+ U8 s, s$ q1 p5 Z9 O O, b& c
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
. Z' V5 a% X M# X; U( d
4 q' Q$ R/ f) z$ p: F8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。- o" X2 R& C3 v6 P% d$ H) q& T1 _" B
$ O. l4 K3 O6 ]# [ ]2 j9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
9 G0 U" q# H* K5 e$ J( @" `; M
; j5 w" ?6 o h* [. @7 H- n3 S10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( t1 J* O) }4 n3 G8 n
1 k% s+ c f& `) d: j11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。# M" z: k( P2 L6 d; E' S" Q! a) `
- {+ L7 w$ s- [# c% Y$ V
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。: w4 h/ Y* M2 R/ o9 F1 i" O: t" [
. G3 x5 Q& o$ j: E4 F f
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
9 {% C1 J! Q A, j; Z! S9 b, f& A% ]9 I. K E7 H- o
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: r# h2 ~ {" m5 H( A) A( Y! B
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:# s1 ]7 P5 v0 L7 j8 `
function reduce_fraction(&$fraction)
) E; E7 z, K& {1 @8 k答案是D。
' C; V k8 I3 ~5 f! e/ l. i
8 _" N! a1 x/ U& p* j( F0 s' V8 q15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
. u% Y0 I& r B; G7 C& W8 F. K( N# ?: g, ?( S9 w
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
( i; M* w* U. V: x" n
( m6 H0 G4 X8 Z8 B17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
" d; s" q7 [2 k* v1 p- K( w& S$ |
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
2 T! e/ ^/ n t. n* f) u- b# f1 q' X) z( R6 x
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。" ?: l( \0 W: N5 h3 M: F
: e9 [" G% w, e- F; _$ k20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|