|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14321
- 金币
- 2446
- 威望
- 1647
- 贡献
- 1394
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。0 R" a4 x2 o" Q$ z( ~- q2 }
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。7 } J0 \# Z0 {. ^( J+ c; G
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。# z' y( F7 Z# r4 ], w& v! j$ R
# [; z) @" y1 p; k, ^* w2 Y问题% o2 A g# {: A
/ |: G e* x7 k. y4 P1 ?: z1.对象的蓝图是什么?
# l8 M" o) e) u( [9 Z6 R, ?8 W! _
答案:____________
+ ?! m3 v6 o7 j" S& |7 f
* S: z+ \7 L! E' A! G7 h# B
! L5 J2 X; g Q; u* T2.以下代码执行后,数组$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
) a' _& K; Z9 ]3 ?- W4 N3 h+ G1 _B.b8 q1 D7 g1 i! a* [
C.a9 m N9 u9 ^( j& ~2 r/ g" k
D.d
, V3 F( H3 Z2 W* A, t4 \; M- IE.e
% V! I' K7 g* c) ~0 f3 O
' h" m E: b7 C) X' ^
, V# d+ v) {8 v, @+ l' x3.如何让类中的某些方法无法在类的外部被访问?
+ r- F: j5 g* c" i/ f% K5 f8 ~7 q) K0 C: j, V# Z
A.把类声明为private0 }# y! ~3 `) i7 Q3 H' Q) ?
B.把方法声明为private
5 M- n5 U- t7 _. b+ H" [C.无法实现
3 g; A) w! N- h3 ^D.编写合适的重载方法(overloading method)
# m- X. l) r9 F* D
4 I K/ P n9 u \
9 k+ O5 @4 B m$ A- m+ |4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
$ M c! c) I3 z G7 z
1 S0 |$ n ~5 B" C! JA.MVC模式- |4 j: Q* K5 d( j1 N2 V( `
B.抽象工厂模式(Abstract factory)- |+ M+ [' z" |- `3 v+ I5 V v$ P
C.单件模式(Singleton)
, U+ `/ d# ?% @' ?, w6 o/ E0 wD.代理模式(Proxy) B# V- A( N; N z
E.状态模式(State)
$ f$ X6 V O0 t9 j3 k' I9 _# q: m8 r6 V2 D" T4 N; l' t
; K) _1 j# j5 \' @, m) h; z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
: B4 M% V" U y4 J/ y
/ Y# y5 x7 C$ Q9 UA.1个
& V" m) y+ b2 @! ] {B.2个# z) S- R8 V% I" i' g8 C
C.取决于系统资源
9 k5 h8 \1 X) ]. E' Z, J2 b4 OD.3个+ X' y1 L& X( V
E.想要几个有几个" Z, ^' T( t) \, c- o
7 R$ U) x% P$ V c+ V( U0 I. s) h1 R7 l
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
% }5 a2 `( D9 f+ X1 N6 IB.接口, h5 N* h. y1 O3 {3 A
C.抽象方法
% @3 x7 i% X( O. ]( LD.Private方法6 t9 D( t, w4 o4 m! ~
E.函数重载(function overloading)* ^: D* L" B- |5 x7 a
) q( U& o. W& K0 a8 `* j8 _
0 o7 w" h2 t* P6 p6 X d7.假设定义了一个testclass类,它的构造函数的函数名是什么?; B! |/ ?# e+ O8 V- E T
6 z$ F# Q' O& w2 ~
A.__construct& R( T" d/ U5 Q0 i Z: Q! G
B.initialize1 m2 w6 y7 p) ~1 R+ H- M& c4 x
C.testclass
$ X7 k9 R! y) I. uD.__testclass
8 @3 _3 |$ f, h. @E.只有PHP5才支持构造函数
- |; B" \+ U) E2 { m- S4 ?# u8 S
+ R" W8 T* P8 |3 d
. o0 f h( C; f: S) Y8.一个类如何覆盖默认的序列化机制?0 O& _6 ~' J& Z3 \% a
, A* p# o; [/ p- _
A.使用__shutdown和__startup方法7 r6 p" R E2 \% q6 Q
B.调用register_shutdown_function()函数! w# E. S+ ?% K2 E: R* o6 l* u
C.使用__sleep()和__wakeup()方法; H- H. a- s, D, L- m
D.无法覆盖默认序列化机制
* z. T# {3 z% Y: W" `! o! _. nE.使用ob_start()将类放入输出缓冲中
2 s, h9 F3 [1 l* B0 r4 r% \
% i) Z; K# T& ?, ?0 d, f6 m& \! e' h' Y) F; }" {
9.以下哪些面向对象的概念无法在PHP4中实现?: T9 ?: c& ^$ a( Z& J, P. c; C4 \. r$ Y
, V* b6 s* A& p@抽象类
( r, m2 E& X# N) m) a. {@Final类, T- X4 ~. E. ^2 Q6 K
@Public、private、protected(PPP)方法
7 N. m _. D& l" g! c- U@接口, M+ r+ e! I3 r# x
6 Z2 O. E; j& J+ M5 l* T: M. i$ s. |
A.抽象类
1 Y! |* q3 j* W. F/ c6 i: dB.PPP方法1 P9 ^( j6 E! ^ P8 o G9 W
C.PPP方法和接口 a3 a* |# @( k6 N
D.以上所有都不可用6 R9 {6 A& D) D2 w* N
E.以上所有都可用* d) z2 u" H- H3 k/ E( x6 r1 N
5 z2 Z3 }/ z/ P0 j7 ^ }* d) `
; Q) L. o) \5 B
10.如何在类的内部调用mymethod方法?
$ A3 z' [5 D1 j4 C
5 |8 v) W& L6 P5 x8 U, Y1 \% x3 YA.$self=>mymethod();" @- @% P+ h$ [5 B1 ?
B.$this->mymethod();
5 I1 M6 P3 Z H0 j FC.$current->mymethod();
7 t2 M" [- A; S! c4 JD.$this::mymethod()9 K9 t' {) y Q* ^# w0 ^
E.以上都不对
8 Q1 B& R3 M2 @* u9 @0 s* I5 L& f9 v6 [1 V1 h
% L) K6 Q/ R, I) F$ G: X4 X. @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+ `; v8 y. w9 E4 _' K+ w
B.Null
9 x2 S% |' ]6 c, q8 @" \ iC.Empty
- k$ F. f4 n" b# H7 jD.什么都没有
' c7 @$ m0 _7 Y! L# P+ [; kE.一个错误9 m# f8 [" T+ S
. y9 j8 _) X* c& B; F7 L
, M: i4 n/ h6 P& B+ x
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' T* z! U; Y! c& J# W h
B.5! d8 l% ^3 ^+ h0 }
C.2
5 Z' a; u- k0 `5 {0 _4 A- B, d7 DD.Null' K; Y6 R! k" w4 V/ i! T( _. l
E.什么都没有4 Y" F/ M$ i% G* T' J8 e
2 G; ~% @7 c3 I; \% y& P4 N* a
8 Y) D! B* ^% T: `7 {7 q) a8 e
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
$ g- @% X& t, ^, [B.10
( a: W; ]( l) \ Z0 j- HC.什么都没有9 y8 d7 a) A' L
D.构造函数将报错) B$ Y. X+ o0 y& w* A
E.510! m6 p# a- X% }/ w. R
* h, I) N0 t! u. M& @& J5 d
1 A D) A. D9 k% |* f! R7 M
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, h4 t. I) P3 A) CB.reduce_fraction函数必须接受一个整型值
+ ]" T) z; o5 h! a1 `: R6 T: C( UC.gcd函数有问题4 V' F. ^& _- h/ o6 E$ t( X3 w4 }+ N6 T3 y
D.必须通过引用的方式传递$eight_tenths对象- A9 ?; S2 f! Z$ ]. M/ o! P
E.对象的实例不能传递给方法以外的其他结构。; u: G& x0 W- `) R2 G+ E7 b
& Z" | g- O+ L$ K$ O
+ V" Q$ H! m% y5 Y% c' A
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法. \* e* h; O0 M t% }) a# y
B.生成myclass的实例并调用mymethod方法, O: ?- z$ S" z3 u4 m+ ~; ~6 d$ U0 b
C.产生一个语法错误1 M% {% O1 @1 c
D.默认myclass类最后被创建出的实例并调用mymethod() i( L, i. j7 N m
E.调用名为myclass::mymethod()的函数
& s8 N0 b I* E3 d- @$ O/ Z9 [3 R
T% I/ X2 e& I
$ ?& H& a4 l k0 g16.PHP中有静态类变量吗?8 k9 Z) G* Y9 L' Q9 b: s
- g( c$ }& X: y2 D; OA.有7 ^( O1 G9 c6 I) P" c+ y2 R
B.没有, F/ c+ b& b% P% G% L0 O
/ c$ Z5 u: j# G3 O- g5 L5 p' x
) `0 v( L: o0 D4 P1 t/ ~1 @2 `; `% 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
* [+ P/ M6 ^- h) S4 L* f/ F' R% _6 RB.2! D' _+ n/ f. N5 Y; b# X
C.一个错误,因为没有定义a::$myvar$ l0 w7 {! }+ W8 ~8 d- x L
D.一个警告,因为没有定义a::$myvar7 t+ c# i. v1 Z) U" E n; {% n
E.什么都没有% ~/ w5 f: G, c( T2 R0 _
# y. w: s' S4 I5 @. }$ P! Q2 w9 k0 h/ a: X
18.如何即时加载一个类?7 S! \( E$ f& K0 G3 {
' @9 R$ S; Q' _
A.使用__autoload魔术函数' d( ^( o7 Z ^: ]6 R: ^
B.把它们定义为forward类
" A, C M+ q7 a0 f( nC.实现一个特殊的错误处理手段6 h% b+ |" s: K
D.不可能
5 ^& p8 f$ B: R- q5 bE.用有条件限制的include来包含它们) ~+ T! U$ y3 n) X
" c3 [7 J9 F' ^
( Z& T2 l/ d0 M* O0 m. Q9 p+ ?19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?2 p+ T6 h+ C# n' G( s# x/ ?
8 C! u7 o" s% W) M+ j 答案:__________
- I3 e! ~. p( M5 v$ A# N8 u# \& V2 d( X* x6 v
. s$ x# n9 _' D! R/ u) [; }6 d% D20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called+ o; n3 Q1 e n, f9 _0 y" q" L
B.一个错误
' {0 W R0 @; S- GC.一个警告
, w% A6 s, L9 `' @8 F5 Z% ]9 C% }D.什么都没有
: ~3 z$ {7 D1 I% V4 P" S
: r+ `3 T$ M. w: E* X
$ j" l4 s! N9 `5 }& g; X6 Y: i) S. \8 {& b- Z2 W4 a
答案速查# S9 F8 S! R' {/ J. Q" ^: t2 N
1.类7 x& R( @: V" m9 w: f% I
2.BCD# I* x# u! V. J( [/ J
3.C$ ^& X# x4 k! y; i
4.C6 K R# Q, P; E9 f( W
5.A
% S' e/ z0 ~# n/ S5 ~! h" U7 f x6.C
1 R2 r3 x" W" I Q" x' b9 A6 h7.C5 r- U/ B |& g& C2 v* u3 L
8.C
4 U( i& Z/ x j& }9.D' u4 z0 S2 \; x
10.B' X, z: s0 j; _0 D, V5 I
11.D
H X# C; f6 X12.B
1 L! T0 p: d. e5 v13.A
3 T7 K9 o5 j) v! V14.D
5 y! n0 `; H) }' C8 F15.A( c7 g- x9 C+ `6 O5 L
16.B
2 C+ E! K: e: }2 H/ Q) g1 m' W17.A2 I+ ?) C% B! `) f+ x1 F
18.D
9 m& u4 |' @8 w3 T' a19.设计模式! E( _9 |; r# W! L( ~
20.D
5 ?. |8 D a7 t6 s& z* S/ }$ {2 J3 c# y8 V4 K; k l' S
* z: V9 I; L/ A2 I0 b Z5 w+ `" S1 O3 S9 x5 B
答案详解
- q- d, X- N! }6 M7 X1 Y$ ]- o. z) P* s, y
1.类是对象的蓝图(对象是类的实例)。3 a! |2 H( w4 R* h" L+ o- `
2 n' y. A& ^9 h3 A2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
; m) ?6 T5 k% v' N, w$ Y0 {' v3 r: X" ? F, z6 ?
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。. i" O" [+ g" j# X- A$ l* M
3 y4 ?. R1 y) j+ ^4.单件模式可以限制一个类被实例化的次数。
5 J0 \# q0 a4 n. S* y" M; U8 H/ u( F& N5 `; _8 Q
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。( l- C# i/ e: x% S0 ?' h" u5 [8 w
- o+ j8 l6 v4 M, F- y$ N
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。3 G; T; O7 o d- f6 W
) O$ p, r( b9 o I3 N
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
# a& _/ G e- V& F( H( r) i# l' M. f- H m, v3 p0 [4 N
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
- c, k. M' J7 a* u4 d
. [$ q2 m( H, B( e1 _2 H$ o" i9.PHP4中没有题目选项里所列的任何一个概念。答案是D。4 }* N( m) _ K) a; t6 ~/ h B
. y. h, z7 {9 P) O' [# G: J o10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
4 f$ S: h( v( G7 [; H$ J
2 n8 t, p- G, O' r! A3 P# `11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
I" f" M6 {2 ?; k1 i
$ ?: i0 Y% p+ q) \/ b2 j7 K12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。( p9 i7 q7 ^" v% g$ U
8 s% L4 F& }. W. e8 @' h
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。/ t0 |( b# W; q7 M% P& @! s
* @4 W5 X, k. w0 t; h
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
/ P' A$ p. u) S6 e回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:% \) F! l. h$ |' ]' [
function reduce_fraction(&$fraction)
- c& _( s( A$ e( c6 D, H, x' k. ~答案是D。
$ _3 A, x% |) A( s% k% W& T2 S
; p+ e& t' [& v8 l15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
) @% I; ?2 z6 r- G+ b" x% I- Q- H/ b* E5 F
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
# B/ a7 E( N0 E8 U& r( U/ }5 D U- j" ~$ C8 G2 J- I1 }1 H+ u
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
* ?( v5 P$ n8 [# |7 m4 j5 o# l( C" ?; n/ \" I* O8 Z5 |
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
. w9 e1 b; |* r% t, G$ n" c% c% Z2 s2 C+ Q
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。+ T& ~0 [$ f4 F* ~* s4 M, t" j
0 x6 j& e2 w0 a4 h6 `* ]5 g
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|