  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
7 E: Z/ ~4 S- E6 q% YPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。6 Q( f/ S: O, [
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。" K" o' o; ^1 `4 x" _# J
$ d8 i: [; ?5 E4 U; a' {+ z% a4 w问题
4 g3 K3 o4 p5 w0 Y4 z6 _
9 E- p8 c0 O, g2 W v' X: _: |" O$ v1.对象的蓝图是什么?/ x: c; J' ]3 L3 v9 d- E8 b
4 [/ |& \* r4 s6 }; }- y* v
答案:____________. o. y3 \# t* @, m& l+ K
# { W4 _/ K! p4 r$ q+ B$ a" Q( t
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' u- ?, N* F! E) q+ p
B.b0 C2 q# E8 b. P% Z( |1 K! i* h7 q
C.a4 d& s/ K' J% {& D8 A
D.d: N+ W5 I8 i0 U
E.e
$ s- Q- W- m" F' j8 L% q8 p: \( o- {, k5 X6 {/ J$ J
* U% J ]0 m! b( B) M% @
3.如何让类中的某些方法无法在类的外部被访问?
, K8 J P4 g6 I0 M% q7 U# a! E% r6 Z& g
A.把类声明为private
* d+ g# `- w6 TB.把方法声明为private8 y4 E* _5 t& a8 X7 J0 ?# ]* Y
C.无法实现
7 a0 w! d! c. B7 d4 Q4 i; HD.编写合适的重载方法(overloading method)
$ y3 ^; ^0 L7 D7 X6 x7 b0 [
5 T, w& U- G$ `0 I6 @' ?. G
1 Q p" }/ f* v2 c1 \4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
* U4 E' r: }" [) g) x0 B3 g% H& A; \
A.MVC模式0 F2 y* q, H. D. i
B.抽象工厂模式(Abstract factory)) e1 E" e8 r5 e; w1 \3 J, [. J5 {3 o
C.单件模式(Singleton)% D2 X# v6 m5 w) O
D.代理模式(Proxy)
" T" e& ?4 e0 M: aE.状态模式(State)
5 b* a& N! l- A- b
# o$ `$ ~* [( k' r* g" {# n6 w% W: F( `) e( }1 O
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?7 F; O; e( e3 F3 A
7 c2 G5 M8 d1 |A.1个
) O* P: \* n. |1 Y- }B.2个% s8 l( K2 p3 s7 s( A: @
C.取决于系统资源
' e7 |$ h* d& iD.3个
, M( Z. v% q' W. k K Y3 F9 A" uE.想要几个有几个
+ n# x! \/ Y+ j: ?
2 Q/ \; T- L) T' h; k! [& |! `! Q9 v5 N9 Z
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承8 e) J Y. k) l+ `6 m& o# Y7 T
B.接口* `8 w C5 C! g
C.抽象方法
8 G2 U @+ g2 N- P5 D- _D.Private方法/ y% s% }7 F7 j1 Z
E.函数重载(function overloading)4 ~' a) s( W0 z. h3 k. L
$ }& ]3 C8 ]+ ?* J
: B! ~* X. P _8 F- f0 m: W) r7.假设定义了一个testclass类,它的构造函数的函数名是什么?2 O% K' R2 @8 \9 q# F+ q" y4 x
0 |' }' R. j N3 [
A.__construct
5 r" ~+ p3 }. QB.initialize
, o: b3 v& K8 D( T5 i7 SC.testclass% W5 W! J0 z" i6 C8 i
D.__testclass
' u( M' b( ~9 N/ D3 Z& v) p% AE.只有PHP5才支持构造函数' H5 R k8 a: B! \4 I# k
2 K; e3 g$ R3 \3 `$ n
* {7 D, d; H; Z8 W, v
8.一个类如何覆盖默认的序列化机制?6 ]4 w7 W2 g, s( [3 s
6 X" J+ e/ g. ~& w7 z9 r
A.使用__shutdown和__startup方法$ F, ?+ t9 C# q, N: E
B.调用register_shutdown_function()函数
2 v( ]) u" A3 N0 pC.使用__sleep()和__wakeup()方法
) O. E+ P# m, E+ k9 eD.无法覆盖默认序列化机制
# c! U; E8 }% R3 d. i- F" mE.使用ob_start()将类放入输出缓冲中
6 v j5 X- q& i% c- y
) n- E, z9 p% n" B$ H. y& S* e
& Q$ v2 r& B/ E9.以下哪些面向对象的概念无法在PHP4中实现?; Y/ {/ }% j6 N! p. B! l
' m8 V8 }' F/ d5 k% N7 V. Z
@抽象类
Q6 t6 M+ j1 i' g( E8 J6 I9 w@Final类# K& ~- ]: P! ]1 t# ?+ `7 H
@Public、private、protected(PPP)方法( ?' W# l' y. n1 K) R
@接口1 [* i) y! o; ^# J) b( b' d5 K# C
3 N% C1 Y8 q/ \/ ?( ^( y
A.抽象类6 Y* A/ W# B7 {; a
B.PPP方法) i& Z3 V5 X7 ^# g6 v
C.PPP方法和接口
+ M3 s; d+ S2 Q4 Q- mD.以上所有都不可用
/ h& W# I2 _6 q* g1 Y* NE.以上所有都可用
' a* V% J1 w- r5 P% ~' K9 I6 O( P+ w y6 Q1 C7 i4 e8 w! c1 I- @
" o8 a; u7 H, y7 n4 e" S3 I10.如何在类的内部调用mymethod方法?4 C9 J3 O* J% R
4 q) Y, m; ~( I2 H0 D
A.$self=>mymethod();' a- g2 m1 i6 y# K! V
B.$this->mymethod();6 v% i* I. j. Z/ f. g
C.$current->mymethod();
( h3 k9 L7 m; m6 rD.$this::mymethod()
! u; l0 A$ z) V, M# K8 p/ \. l; aE.以上都不对8 [( @1 z4 L) L
r% h( I3 P& L& J& z0 @) p5 X Q$ h
: ~$ G8 |' e5 {( b11.以下脚本输出什么?-
- <?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
4 p! d0 l, _, uB.Null7 }" r, C" }- \, D
C.Empty
4 g: D0 _& n! S* E; L/ e$ _/ ID.什么都没有
- G0 N8 Z' H2 @+ ^ v/ h8 EE.一个错误
6 U1 i* l. Z w5 L8 s. F% V% ~" B
- I* P+ l1 l) @% \6 `9 Z7 |& Y
- C \0 b \$ |1 W9 k12.以下脚本输出什么?-
- <?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( L) W! F) T7 x0 c D! x: L* p ]3 g
B.5; r5 G* W* A% I7 q0 C, o. A
C.2
( v, l* J0 E& A- l8 _) yD.Null/ y: }: ]' x' T0 P0 h8 F$ ]
E.什么都没有
4 S" r |+ M3 c& e
8 G! W1 Y' ~! Q" d c3 k- m8 l' b0 g" e) v
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: l$ r* ?$ h3 ~( s
B.10
% X8 L p" \% V" m0 C" RC.什么都没有
8 k$ u) c& \1 mD.构造函数将报错
; Q2 C* r# w% h* Q0 J' \E.510
" w2 Y' W4 Q3 ^5 B4 t4 O7 m( W/ K. C! \8 z6 ]$ X" _
$ i0 R! d3 {6 `5 s* W$ ^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函数必须返回一个值; A: M8 U0 f: M# O7 |
B.reduce_fraction函数必须接受一个整型值
n+ u8 |. A. }, B2 E# m7 X1 NC.gcd函数有问题! f$ Q% i4 `$ I2 b" x5 ~* B8 L- M" ^& p
D.必须通过引用的方式传递$eight_tenths对象$ C2 J( t5 f/ {' @: f; @
E.对象的实例不能传递给方法以外的其他结构。; T) K2 T6 D& U! M8 R, H3 d" e& i
d: {8 s3 [ Y2 d2 s4 ]. E# \+ r$ ]
- s' @( U: z+ X7 A6 t: A15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法) Q( F: e* P2 R: L
B.生成myclass的实例并调用mymethod方法
. _" ]- K6 \$ \. QC.产生一个语法错误
. p% ^6 z$ w3 P5 i2 y p1 v' S9 oD.默认myclass类最后被创建出的实例并调用mymethod()
4 Z9 \; M* Q2 M2 FE.调用名为myclass::mymethod()的函数
' W$ f9 M2 M, q K0 y
" o7 R, l0 ~# \
1 }4 z( Z8 p4 U1 z2 s$ }16.PHP中有静态类变量吗?
2 D9 N. Q" ]; G* t5 E* Z' ]# ]+ t% e; }* B- ]& ^
A.有
! ?: j8 M2 j) LB.没有( C" g! s8 G, \: q4 U" h7 o
6 V$ K$ p, T1 U5 G4 s" L' m6 ~4 p
) |9 C# F8 g& X+ c6 Q17.以下脚本输出什么?-
- <?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
" a( J8 g( L3 S3 w% xB.24 O9 H# {/ E) B# O3 p2 i
C.一个错误,因为没有定义a::$myvar
8 }. C' y6 V9 yD.一个警告,因为没有定义a::$myvar$ X! Z+ e T- N% \7 `
E.什么都没有: ]' O, T3 V" {% W
/ Q$ _' m, }2 C4 `! I
; A/ F4 b6 N6 O4 F18.如何即时加载一个类?
l2 `1 r; D! o. U. Z C- h, ~! b# i8 ~: Q f( o: F
A.使用__autoload魔术函数
9 [& X" x3 ~, G. ]: b# V9 aB.把它们定义为forward类6 \, T9 ?! |% @" i( ]
C.实现一个特殊的错误处理手段
2 m$ A, v R YD.不可能" u! x6 V3 V5 r& w4 V1 R8 N% O4 d" S
E.用有条件限制的include来包含它们
$ J. @7 m$ A) [$ f: A/ v8 p3 P0 i! }! H, p/ K
, j e# k/ R7 }" b1 @8 X( p19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
5 P' h# M* D* d0 J
+ C% {7 `! ^6 }0 k" @ 答案:__________
1 a6 }1 u9 c& }
# L8 e( R( }0 Z& y% K7 r" Q
6 ^6 D8 H. a9 Y% ~1 D# B" m20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called* N5 `0 k" e- s+ m. k. F$ ^
B.一个错误
8 ^: I9 u) Y' n/ w& _C.一个警告9 a. ]& M8 J, _. V4 _
D.什么都没有# G, G+ M6 H; K0 o
' b7 H$ b7 v' h) E
+ t1 }# L T( P$ z3 z8 b
- S2 q1 F' w6 Z! [
答案速查5 ]! P, e" a* C& j
1.类
2 t" K6 K( x6 c$ z( |: T) ^1 R; S/ S2.BCD
# b' X, k/ i3 j( r' `! w- d3.C/ `1 m' a- y- t3 n8 `
4.C
4 f; V- V2 Y( S5 v& H' F5.A
4 D0 G: Y1 t4 B" x6.C$ `4 b$ r# ~* r2 V: T: h5 e6 x! S
7.C& w* Y+ H( H& ~2 ]
8.C1 w. ^5 w8 O/ W& F& d& |
9.D* e1 `2 ]. `/ p' |
10.B
$ t. Y' t; _; k/ m' i( V11.D9 e7 z; x! B' s8 `* K; I: M4 n
12.B0 F- L7 w5 S) J5 F3 s5 ^. o4 Q
13.A' m! y& _6 m5 a* O* L1 l0 Z4 A
14.D
( O/ A8 f0 y* r15.A! f) l5 D4 @; P" g E% y. X2 ]
16.B, ~8 Y/ `3 C* q8 J- H4 k; A& R
17.A4 N& n8 k, V& ]6 ^
18.D+ h# P9 N% M# H" k4 [
19.设计模式6 Q0 _ j6 a( B& Z s8 V4 _
20.D
- h' b3 j- u1 M% p3 N5 B/ l# ~* n( @3 B5 g
9 C9 H/ R- B' L7 o8 ]
/ w' _, L* N- f. f" f答案详解
. }0 i/ B5 z4 ]8 Q, E9 b: R
& X. N7 O, a, j. o- ^1.类是对象的蓝图(对象是类的实例)。
/ s2 P- I- i& w- w9 k* @! F o# P/ l% d+ k( G1 [% Y
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。: M6 ]0 q9 G4 V5 @2 U- {
) k1 Z! T% u: s2 ]+ d3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
! R( R& ?/ _* e. d2 V2 L- ~1 |5 c
0 k; v' @" c/ Q W- _- x( e4.单件模式可以限制一个类被实例化的次数。. r& s" B- g/ a
. `$ O4 X2 p8 y; ]- p
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
' j' X3 J+ e' e7 _
8 m; u6 s0 ~- [' T0 w t6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。2 E& u% ?+ e) o
. L& r+ p# b/ @* B& V) s
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。! N% X1 `8 L& f
) S+ _2 R4 A1 r' Y1 J
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
* N. p: T8 O5 H3 X
, n4 ~6 V% S: T1 X9.PHP4中没有题目选项里所列的任何一个概念。答案是D。- }$ A" T, Q( Q
& I0 t! T) V8 C( S* C' g( u( `
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。6 d6 m- ~+ O) {6 V/ i, S
9 N* b/ d0 \. w: G6 |
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
3 S- v6 _$ \4 T$ B1 b
5 X: {& H+ ]8 b8 A12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
5 y, r8 f, W3 n- ^0 g; r% n: q& T, v7 X
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
: I; f; i# @& ?8 @3 X$ h8 m8 k! K W$ ]1 \8 `: O- f3 k( x
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
" W& r- X/ }7 Z2 B I/ f% R$ o4 c回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
' F/ Z3 f3 p1 @8 v/ T. k9 n" [ [ function reduce_fraction(&$fraction)
. }( P! K3 }) ~) Y9 \/ l3 Q, J2 G答案是D。
' B1 b. s( [) u( a: H1 [
* C6 Z6 I2 j! O, v2 j15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
# r8 R3 h5 p9 i; V+ P8 I: x% ]3 ?$ T+ q7 A& E* i
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。% `7 m: G) W. d c) ^& ]
: S5 o& A2 E3 v/ \
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
1 p: Q1 _( V- |. F9 ~, U8 {
3 A T. `' E4 `) o18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
7 |* x( \8 @' }, |
7 a$ O6 [4 E6 a# k19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
. t8 C% X; d( p1 j* `
+ W& F3 G# {- h1 W20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|