|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14391
- 金币
- 2481
- 威望
- 1647
- 贡献
- 1429
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。 l! |7 D3 r! q& v/ v% v
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。, q0 _. j/ t7 S% c" Y! @
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。/ a1 g/ g: B; s, ^6 t) z# A# W
f6 S) m4 O6 k. p# U# |
问题5 @, X/ i+ ^/ K9 i) A5 k
6 s, _# z# o- Q. g) @( f$ y1.对象的蓝图是什么?
2 h" `* Q8 J! Y, T& h
* P. E. h8 i# ^& n! M* @% b; }答案:____________
0 s7 R- T2 i; y x% H `$ B0 X- Z+ D4 A4 l. D6 X
) N0 _( _' E0 b( q% e2.以下代码执行后,数组$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: U7 L3 F" d) W9 `) j; x6 C. m
B.b1 W& ]+ u- ?: u+ m0 i5 u
C.a
2 H# k4 a2 o9 E" jD.d8 m& k& Q0 Y+ C
E.e
0 T2 D& h# f$ H Y7 w4 r
. ]( x$ J) i- s4 i3 D( H
: ]+ ^* b, y& {8 Q5 S3.如何让类中的某些方法无法在类的外部被访问?
$ |% Z- M& ~0 a. T2 M% E
1 l' s7 F: X" W4 kA.把类声明为private
x* ~( c H: P# c: [( D" |B.把方法声明为private
+ e s; @2 v" O# }C.无法实现7 R/ `5 I$ i4 B- O. R
D.编写合适的重载方法(overloading method)
9 W" l5 n" c0 a2 F; L5 s' x" u2 Y
9 O* z; I# R# n3 S4 ?9 f
( S2 P# H& E2 u' g) }# L( Q4 k4.哪种OOP设计模式能让类在整个脚本里只实例化一次? ^" L- _9 w$ l) n* h
4 V% J- j" A7 ?1 y/ |4 w
A.MVC模式
4 ]5 g1 Q8 D/ y9 nB.抽象工厂模式(Abstract factory)% }- `1 ` z) \, m. M* h
C.单件模式(Singleton)6 O) ]7 Z4 z& G
D.代理模式(Proxy)2 e: F G: r5 I) e( N# W% d
E.状态模式(State)
, m0 J/ \6 H; r3 K5 F9 a; g4 q# v4 i" Z* h) ~7 b
1 R4 X9 H0 |6 t; I) [ z5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?9 K' W. S, L. t% c
a5 `2 G P, V, ?4 z4 @8 |
A.1个8 @! k$ w; c4 g$ I! t0 [" ^3 q2 J0 z
B.2个; s) O6 x$ ^! f4 I# K7 g1 f5 R- V
C.取决于系统资源
s% P H, T/ G8 jD.3个% l" N1 D4 [7 M: T q0 N5 @
E.想要几个有几个
% s- R @! i9 M% z+ M% H: v& q+ n! R* r! ]/ W* ~, M
4 m5 J0 ~9 T- g4 S* g6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承1 L4 _6 x( {8 X; U" O
B.接口! j: G# @, R: t; W/ t6 x V% S
C.抽象方法! e" _4 N: I- ?: [; A: N* J$ q
D.Private方法8 F# {7 H' o% }* R% @2 s: S
E.函数重载(function overloading): |: e! [+ ]+ a V% [
7 z7 @! l2 r1 R4 d; U1 u/ a }" k$ R+ I( u& B0 k
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
3 d: A- T9 x4 g! r/ u) j
, [3 C% }8 q3 o0 {5 g* Z/ XA.__construct
" o0 ]9 i6 C1 a# `, D" ]* o+ nB.initialize
3 Q& e$ x, Z) XC.testclass
. I/ P `5 V$ SD.__testclass& y/ ~! \: a7 Z A3 ]
E.只有PHP5才支持构造函数, A9 @3 v" S7 U# Q
' s" K6 r0 h% M# d
+ b* N- A& ]: Q8 D8.一个类如何覆盖默认的序列化机制?( \( w' y) s2 @& R# A
3 Q* o* A$ h& o$ ]
A.使用__shutdown和__startup方法* G: @0 B" S0 h+ ?5 Q
B.调用register_shutdown_function()函数. N3 m: ?: E0 r) d) _ a! S
C.使用__sleep()和__wakeup()方法
: h8 |) j4 f5 A$ n5 [0 W/ p2 {D.无法覆盖默认序列化机制* o. q: S, O. E w4 c1 E j* y
E.使用ob_start()将类放入输出缓冲中9 Y7 H) {$ w- I) o( Z% o4 z
8 i; h7 l3 ]/ a( e: q% w8 h% j+ c, u# T! {$ j: c
9.以下哪些面向对象的概念无法在PHP4中实现?
$ P% c R( n4 H: u9 e7 ?& P% V n7 K. o3 F# ~# G
@抽象类) X" C6 g5 S3 F! Y
@Final类2 G2 p2 }) V$ e% ^8 ^
@Public、private、protected(PPP)方法
: \" _. Y8 }7 x: M. }2 |5 J( D% g@接口
& {0 d" T5 L& Q# S1 u' h6 V! o7 |5 Q6 J7 U, ^
A.抽象类# A |; G8 A0 t+ D* ?
B.PPP方法
3 u% P0 x5 D, C5 C" I dC.PPP方法和接口
) d5 r0 m* l& w* P/ {D.以上所有都不可用
( i: E: n% A# zE.以上所有都可用/ k: G' J v0 w& K4 b% n6 z
& F% c& m/ E+ _3 l, X- z1 P U6 U" i$ `6 q3 J, B% o
10.如何在类的内部调用mymethod方法?
( |/ `& j4 X( k6 v' F( `) v' a+ h/ {3 }& A/ a# T4 I
A.$self=>mymethod(); V& j& @# D% k; i j0 i1 e6 |
B.$this->mymethod();
' f1 i7 Z( V% W% @6 Y& M1 vC.$current->mymethod();
6 ]! j7 E, N# N7 V/ `" vD.$this::mymethod()
) S7 I" z: x- m$ t% H) q. ^E.以上都不对: T! B k+ u/ B
' `% ^0 o9 q1 T0 Q/ x/ z. c5 A8 g5 v# W0 B: p- Z; i- G; R! N2 _
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
+ Y' n2 _: @) e; B9 b/ gB.Null
0 I- T! g9 I" h7 _# u- FC.Empty. o6 Z# G$ ^6 x+ O
D.什么都没有7 _: E8 F# B- f! t
E.一个错误
9 y2 E$ c7 _7 l' i+ q. \
0 @$ P( A$ U; K9 v5 K, q% B8 {6 B
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
$ p p4 w% ^) Y6 HB.5( d6 `" b# c* H
C.2
4 k( b6 @, Q: |) SD.Null
+ I( M7 s8 f9 _4 S# ]E.什么都没有, V! A9 l0 V$ C5 J( p, r
) t- V& L, i" K+ y
- A9 l4 z2 T$ S" l1 M: ~
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* d, i" @) z0 d
B.10
?) O m& u- k' KC.什么都没有+ b' u F0 ?) X& q* [7 d2 G
D.构造函数将报错
' `: S# d9 d+ u8 K( x0 |2 pE.5100 P) k" e# `: L) y# A) j
( @0 D5 \; ?, `
2 ^ E, P: B8 G$ Q. P9 J1 h2 X# U! g14.考虑如下一段代码,执行时,$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* B5 E0 O% C" B4 b8 XB.reduce_fraction函数必须接受一个整型值/ ]5 [5 B6 n, V h
C.gcd函数有问题 V. M q; _/ e6 q/ h3 \4 q
D.必须通过引用的方式传递$eight_tenths对象7 A" j6 S: e1 w/ J
E.对象的实例不能传递给方法以外的其他结构。: I3 z' J* X" O, `
y; T i& \! O0 J: N; a9 v* \0 a" V5 a, q$ V
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
8 q0 m w2 s b0 v/ ~. _! t( IB.生成myclass的实例并调用mymethod方法; Z' G# e9 [" M' Z
C.产生一个语法错误
. C8 \- u1 M' S P; G1 N% p% ?: ]D.默认myclass类最后被创建出的实例并调用mymethod()/ Z1 u$ C2 P6 ?/ k" ~, n
E.调用名为myclass::mymethod()的函数+ K2 a7 f3 J j3 u. z! O
9 A4 @. b8 K2 H5 e$ A- s7 I
# ?' ^/ B; ?. T/ W16.PHP中有静态类变量吗?
3 h. _* M3 r' V* S) r1 O x9 _' H8 @/ N2 [9 z: b, @: \
A.有
; o$ K, d- [9 dB.没有& `0 c* O+ ?9 d9 ]5 }3 {
; @* w: D3 N. n2 s
S2 Z$ r1 o/ L4 n/ f: @, j17.以下脚本输出什么?-
- <?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
. E) y+ |2 ] X- \ s' ~; F" bB.2& A( `9 T* j0 d$ G
C.一个错误,因为没有定义a::$myvar; ~; ^, _3 V5 w T* a
D.一个警告,因为没有定义a::$myvar
$ l" {# a# } p: I8 Z: `1 K1 lE.什么都没有; r/ @% j( [5 o9 w+ s2 M
u2 @- R& I: G( l3 @
( n& C- q I6 r x7 {2 c z8 H18.如何即时加载一个类?2 D* e7 N# S& _& j1 O9 y
( ]: M9 w6 b/ C# G# w6 G
A.使用__autoload魔术函数+ |' `& _9 Y: M4 f1 P; F
B.把它们定义为forward类2 [$ R8 W' u1 T/ C% d
C.实现一个特殊的错误处理手段
- b& V! o* {! P5 `, n( _( BD.不可能
/ V4 R9 }( ?- g. ^E.用有条件限制的include来包含它们
8 B/ ~- v* U9 k3 X9 t- c
" g, ` ?& G& z6 }
k" F( \* u& @9 l5 o& }19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?3 [0 p5 Y- v5 _; O* }, Y1 i- F( N
( _. t; A d8 \
答案:__________/ \% w" g [$ z; C
! r, h" [$ `; Y! H+ o [
, Q: u# J/ k* m; Z! ^20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called! G: ~) H5 x* c' I
B.一个错误- V6 g8 r& `6 e% o
C.一个警告
! s/ b: K0 m( t2 k3 M9 ED.什么都没有* h/ M- e1 p$ X/ u4 h2 P) U& [" g0 r
' Y- o7 l( Y0 I/ O0 d/ i8 |
& @$ U8 i: `& r$ p. }. u$ k
8 h7 y+ e, [5 T, I$ Y5 G答案速查, { c t3 z. J; @) E7 @: w
1.类( Q7 E# p9 x- g0 A, o+ a& D
2.BCD
H# v0 Z, q4 q$ z1 b3.C
* J1 j+ W3 I5 Q( @: ]) I4.C
6 h) D: J. s0 W, r0 q# v$ k5.A
' K: F3 E/ h$ h9 U7 p V6.C
6 f9 i7 f5 O7 \- v- r7 ~' b& ?/ c7.C
3 R5 y7 E3 @" X, w8.C
" B% N }- F' I9.D" m) g i/ ?+ `$ U* c+ [
10.B
& R1 ?5 n/ K" ]) p" `- b11.D% d7 }* h" o4 G( S2 C9 b& |
12.B
" `2 D( K# }% ^* z2 H6 o13.A
( e. S- ~3 f# G* F M14.D5 `: t1 z- B7 ^
15.A
6 A& h4 A9 e, A2 t16.B/ W1 h/ W5 o! j9 \ k) m d( q
17.A
6 f2 J" }) ?4 } M& {: {18.D, s; k, o/ h |5 [- f" B) A' t
19.设计模式
6 q6 j" t( o$ n [5 q20.D. @; U# `0 B$ G& R$ q
7 e# k! {4 \ b( F; }4 A" |
( A( I+ m0 r0 D9 u/ c! r+ B
0 y( |+ \* v2 @0 t, v, x
答案详解) C* ?/ l _: F2 v7 I
4 |% q! X5 e7 J) C1.类是对象的蓝图(对象是类的实例)。
. K1 J/ a! s5 P _
$ w, U l) d; v4 N+ A2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。, {+ _ M7 g3 j+ i
; e2 X: o. E1 Z; v: R
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
) w% \& N8 X4 d, f2 e' ]5 d) S I% v5 w3 J3 m* _6 L8 }/ w- J
4.单件模式可以限制一个类被实例化的次数。
( z% x3 t/ T* [; d/ @
5 p$ z ^- G4 g/ [3 Q- e5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
& k% T4 O1 C$ ?$ g' D0 V* V9 P* I7 A( D. w' L2 t* B8 ~
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
( Z K) h" ~/ a. [! c. Q. _) S
+ B6 E5 W+ o! \* g! t7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。) |( `! Z& @* l7 o
( Y5 G5 f6 i9 z; n; e) h \8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
# E) p" A3 I+ Q+ z) H. X* j$ |
- H! x# g; w( w+ ]5 Z) l1 J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。) ?0 M1 G' D* _& i
4 w$ X7 I( V: ~; W
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
) C) a- a% [" `: J, _+ D
' x. {) G# S& a11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。7 G1 B% L! M# \- ?5 O
0 H5 I0 Y* E4 E3 \7 [$ L; j* E
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。( K$ y, t0 E! X& |* D: A
" n1 d2 f8 h5 r9 m T6 g13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
/ p. m5 U" D* e4 ^: Y N
8 y: x8 h5 N1 s) X9 L14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
6 z# @' v9 q) ]6 n- r回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
; W( {; ]1 E+ W% d function reduce_fraction(&$fraction); k9 [9 b3 B, P T( i3 D
答案是D。: U9 `7 e- b$ b
% R6 E7 A8 m Y' r% {! x9 r
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。- H. ]8 b4 ]9 O3 ?
+ Y% z. J( i2 ]# H5 w C+ n16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 P. U' D" s: Q
* }* X, ~" L2 g$ Q) v* S17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
6 ?9 T; A* _' \, g5 g( W# {8 U3 G7 T$ T: q7 q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。: K" c4 p# _& @7 U' k# S) @
- R$ \! Z# w7 d" _19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
) P* @3 o* I) _2 {- J1 ?
* {( F) f h* [; p. `20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|