  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14171
- 金币
- 2376
- 威望
- 1647
- 贡献
- 1324
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
# I1 L) W& m! d8 r6 g; H8 UPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
" A' J7 \7 a" X% \4 p2 A本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。+ G1 f3 F$ @1 A
( N( M. x5 G( k! S问题
0 K5 L0 b! g7 X2 K9 _6 w7 M/ s1 B1 M) B/ U: s* U1 f
1.对象的蓝图是什么?
5 o0 o/ r: r$ P7 X8 y$ H0 P" Z! Y
答案:____________) y- T( q& Z1 S5 O& O0 `
' f. {! O& S( @# G3 Y n
8 d* q5 v$ B* B/ q; R- {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
2 r& C9 w; z8 o0 ~5 D, O! RB.b
}* n( R# d# ]6 L8 e& {. pC.a
v( y; |7 E: ?2 W$ ~! ZD.d
% g; [0 e4 |1 F: JE.e
4 p9 [7 l _* ]* g7 d2 J3 x! J5 c$ r& L: N$ N+ {0 h4 O3 i
5 r2 I- i* O; v% h2 b% C; e. @7 v3 z
3.如何让类中的某些方法无法在类的外部被访问?
4 ?; W& [0 P) v, P1 u" X
6 U: O' V& _% Y F! d& \1 rA.把类声明为private6 u" d) y2 e" ], {
B.把方法声明为private% k% O8 R7 r" s7 Z
C.无法实现
* J" T2 ?( l7 o+ H" M Y$ P* z* sD.编写合适的重载方法(overloading method)' ^, o6 t' \) T L
, f6 j+ [" O9 n/ E- ?' k
. a( P Q) v# F# h1 f% r4.哪种OOP设计模式能让类在整个脚本里只实例化一次?- x; \ f8 p, {2 G
$ x+ e; y+ K3 b7 c. x
A.MVC模式; k, m- F6 p5 H7 j
B.抽象工厂模式(Abstract factory)1 K1 y8 ]" {! Y
C.单件模式(Singleton)0 x- o4 T6 H$ B9 {, x5 y
D.代理模式(Proxy)
' X: a% \+ J5 }E.状态模式(State). R: }% t. h8 a; @( n
0 @7 ?: O. B$ Z" l9 B) Q9 a6 J' m+ x+ p
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
6 A" _& \; W' h/ Y9 k% Z7 H* I# M7 ]% O9 `: N* D
A.1个) e7 ~* D1 ^$ r' j) n
B.2个
3 C {; y. z5 C- U# L( A0 XC.取决于系统资源
, w2 v2 d0 ?3 }3 _D.3个2 o; Z7 Z; {( s7 @+ |& n0 q- c
E.想要几个有几个
, L' x( U! H0 V* X: C- \2 G" Y2 _( s2 i" g5 H* i
3 C! m" c: {! S8 c
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承% t% {2 i! w O$ S+ U7 E9 {' ^0 y
B.接口# o% R, Q4 E. q
C.抽象方法5 p8 y6 W9 C+ n$ s2 q
D.Private方法
6 w) X9 |5 N6 D5 N, ?, q8 J1 Y0 F, hE.函数重载(function overloading)
' z1 P5 x6 s @" J( J% r& P( c
! `) ~; S P+ @4 ?3 u' x" E$ h. i% }8 k2 F0 \, N
7.假设定义了一个testclass类,它的构造函数的函数名是什么?8 M& [/ @8 c8 C$ y- d/ h" A
j/ f h2 p( c5 Y* W9 mA.__construct
+ L9 D/ o1 Q D# Y$ tB.initialize
9 {# t( }& ?# g# AC.testclass
' W& t! |/ j, vD.__testclass6 q/ L, I. H; s( Z7 \) I5 p
E.只有PHP5才支持构造函数7 V0 F/ C& X$ j
" a+ C v d- A% g& V
+ }& ^1 A- y7 r5 K5 G2 G2 w: F; K8.一个类如何覆盖默认的序列化机制?1 m/ C$ O% S+ {3 z# ?/ \
8 X" l& {) D: {' D/ {7 S% ?0 N D
A.使用__shutdown和__startup方法
( A& v) k0 g4 G& |' L! s7 MB.调用register_shutdown_function()函数
+ p' A$ | R' h7 @/ z$ R9 ]C.使用__sleep()和__wakeup()方法8 A E" N. m3 O+ J
D.无法覆盖默认序列化机制- G8 R- F+ B" S$ `9 X! Y
E.使用ob_start()将类放入输出缓冲中, B3 L2 B* T" o& j
; H4 Z* ~5 c, A9 H! \% u# ~6 a2 P
; _) x; T# G$ t. n$ M: M9.以下哪些面向对象的概念无法在PHP4中实现?: R3 s- K2 N: D
9 l: \/ m* P* _
@抽象类1 S( q; C6 Q4 M$ B: R1 K3 K: Y
@Final类; C0 H. \$ m& V, p( G1 f
@Public、private、protected(PPP)方法
% B! J' b2 A5 X# E/ X@接口
' v6 P& G3 S- m1 Y+ X% x& z/ l2 b; y6 N9 B1 U+ c
A.抽象类
* C, Z3 Q9 u# ]" e: m) B. u( lB.PPP方法
; J5 P! J, d3 g: U+ `C.PPP方法和接口
1 d8 U9 K/ } u6 O: DD.以上所有都不可用% `& w, R4 Z1 f2 A; _9 M h
E.以上所有都可用
0 ^4 o5 M9 x' w* `4 T- w- E6 `# y5 h J* |, E% p- J( G# l
( U& n9 i. P8 q8 @) q
10.如何在类的内部调用mymethod方法?+ a0 \8 `0 C) y
& [" ` @ D1 r1 {! J1 IA.$self=>mymethod();
/ v7 ?+ r O. h9 H& RB.$this->mymethod();6 k5 ?% y- d k- _4 F( x; t" z
C.$current->mymethod();
' l" f4 o) \, d0 E& v# b+ S) `4 UD.$this::mymethod()
' e8 D4 Q, I$ c5 A z: ~. kE.以上都不对) r4 I. z% G1 u( a; P8 W
, Q3 k0 j9 g- G" g$ Q8 j
. l* v8 Z9 e2 r$ B, f, O1 O7 `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
, ]' J3 P* V9 c- {B.Null
- f% T3 N2 U" g) L9 A8 sC.Empty
2 u H9 \7 Q; T0 RD.什么都没有4 K8 @6 n4 g& Z3 n8 O
E.一个错误
5 M+ J$ F, g$ o" Q* S$ a" G9 T. S6 |5 L0 w8 z, ^2 r! T. x. ] n% K
2 ^) `0 F4 w6 o% \) Y7 U& r7 F12.以下脚本输出什么?-
- <?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.103 [) I/ \8 y& {5 `1 j
B.5
) p4 O9 `! k# T- p; [% d. nC.2
5 A& b& [2 ?+ I- ID.Null. [ @) Z" X0 H9 D
E.什么都没有2 {( b, T4 A: i/ e4 z. c
9 O8 u a( u4 O
5 y5 @4 y6 Y- Z0 I9 F. h13.以下脚本输出什么?-
- <?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
5 p+ J9 W, f4 g- p; M2 kB.10
W2 @% l) a7 r5 Z0 tC.什么都没有
- U% r3 A v6 ?6 ~5 hD.构造函数将报错
5 a* K% C! q! F+ `( ME.510' H1 a" z4 O' f; A; X1 W0 G( g
' |$ L( P' u2 W% ~. y
5 C2 V8 f' ?# i" \2 K14.考虑如下一段代码,执行时,$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函数必须返回一个值 N$ _! t# ~7 W" t" F3 K; Q& H3 G
B.reduce_fraction函数必须接受一个整型值) K+ Z5 i# W1 R# E
C.gcd函数有问题
% p3 C+ C2 ]( D7 JD.必须通过引用的方式传递$eight_tenths对象
6 \6 r- E! ~& D# W" o) N; _4 @* Z7 SE.对象的实例不能传递给方法以外的其他结构。! s6 L) [' O. R6 R) {
+ ]% ^$ w8 z$ |+ D& c' ~( ?' E+ n9 {) c3 \. p+ V1 _
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法2 R" X1 \/ d& R& r* r8 N
B.生成myclass的实例并调用mymethod方法
4 Z0 y' r; J6 B Y: G- UC.产生一个语法错误
2 H6 S! _1 t! AD.默认myclass类最后被创建出的实例并调用mymethod()+ X; F+ T |- Z; X0 M; D' b5 P6 a8 @
E.调用名为myclass::mymethod()的函数4 S w- L& w( ?
6 S# R4 `+ J; }7 k- U2 k% N$ J; `& n$ _7 L, X
16.PHP中有静态类变量吗?
8 ]. G; h2 ]# y2 g/ W/ D$ B. l/ H2 s7 {2 d% F7 K7 K1 y
A.有& q) Z% x1 k. _. i8 J2 O- U+ @
B.没有
) \5 K8 _! }; k% B- g6 P( J0 F" t& O( Y+ [& D- z# Q6 U! v
4 i9 H& B1 x k9 r5 ~! e
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.15 e( n; m: e2 `" n
B.2
. t1 E4 f7 d8 k6 kC.一个错误,因为没有定义a::$myvar
" B8 X# w% E) o' H+ _$ S6 z+ b uD.一个警告,因为没有定义a::$myvar. a6 y0 {0 N8 p9 P7 C
E.什么都没有
# a) s/ b) A, d% e: T$ v$ j! G
" L& O+ L3 v0 R+ Q1 ~% s% P2 h7 l8 d7 O- ~. D; z9 ?
18.如何即时加载一个类?
3 \( {" X0 n) k& @
- z7 u% f' i3 vA.使用__autoload魔术函数
: c u2 C1 ?% x2 X/ B- dB.把它们定义为forward类/ {4 b; h% p }# q1 x
C.实现一个特殊的错误处理手段
: J2 P+ [& [/ TD.不可能 N. r+ S- Q+ c
E.用有条件限制的include来包含它们1 T! T5 C. E4 J. x$ s# I/ e A
m* N: Y$ s2 A& {
' @! T; G3 X/ u. R e# c. n19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?5 i+ H& r- |8 ]) H8 K% u: U
- T) P% L+ s0 n2 K
答案:__________
. M# f: w' @. I- m9 K9 t$ j. H
. _ D" p& x. I% O20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
/ {) Q% {% r5 Q. s. \B.一个错误
?/ Y+ N, D ]+ P8 z, h2 tC.一个警告" W$ w5 h7 Y: n9 q+ w7 C
D.什么都没有 f$ k' [. n* i% j4 @
1 T6 @+ U% ?2 H0 c' B9 G6 o
* H9 {1 Q x8 u5 ^4 A
4 B: }/ b9 ~# |- c答案速查
' e# N8 U, e) C$ @: o% I1.类
) f* W3 s; k" B2.BCD# x- r+ ?; B0 \( F1 \
3.C( |1 W ^+ D; L6 \) e' ^; K
4.C% P; I$ ~6 D% N$ T
5.A% V( }# t+ S0 m8 t2 v1 _! n
6.C
- _* D" s& {; c5 W( n4 f0 _7.C
s* i) }" n$ R8 @7 s- P6 L) L8.C
( j' {0 ]3 i1 x# m/ `( |/ R9.D8 `; d; Y5 q J; k) s5 g: x
10.B
% R# P4 y7 Q+ E4 I3 U2 G3 [9 D$ V& G11.D* j( G, `$ Q" J4 q/ ]
12.B2 b7 q" E5 L3 }* U. c* h/ ~/ ~# {0 q
13.A
$ a, N5 ]1 R' p, g# e$ W' j14.D! M1 q g7 [+ g4 v O
15.A
9 c5 y ]6 Q* Q8 A, ]- L16.B9 Q6 c9 J9 ^: Y# N
17.A$ P/ ~' L' B" {* v0 F! u2 `
18.D- P' j* ~5 |# u- f+ q+ K5 m
19.设计模式8 c" _' A6 ^* b6 Q1 ^, R& R. F
20.D
+ o( Q3 x* E) o) O8 q2 E
3 U4 S$ ]- N9 ]8 S
' `3 X/ q# o: F' ~) k) \, ~. Q! m4 G1 W* ]
答案详解0 m1 R% B) B* g+ F. O
- h4 v, c4 q7 F1.类是对象的蓝图(对象是类的实例)。* t1 X; E; w# {1 _2 h" _1 b
0 q& l9 q: c3 d0 h2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
' [0 L$ q6 `, @8 U9 }9 d8 m, d! ]% |4 |
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。, e5 h4 c/ p7 l( s I
# B- h6 z4 r0 s$ c- O! q
4.单件模式可以限制一个类被实例化的次数。
( X* J6 u' P$ b3 `( [0 r
) A t, g, ~* b- K+ l5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
- [; L' p5 e$ g6 Q* Q# G* D- c4 ]) O3 d$ {/ l2 Y( U8 [
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$ |7 z& ^1 Q* P+ X. ~
" x! Z: `# T( |% q, G- q
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
9 H. Z. }: U9 T( I- F
: Q( g% V- O) i4 Y8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。* u8 H `( \) y2 b
0 E" e% o* Z: @0 T2 U/ [% g
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
4 l9 ]6 M6 V2 @- f! S9 V- o9 K0 M' [: u" L- T Z- M) K
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。0 C6 R2 {1 F! \; S6 T! O
8 H) s' x' o& ]$ ]& N. p11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。7 Z' k+ g, I! \7 ]
5 [7 r0 C! N4 b
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
9 d. R1 i2 ]8 ~( z2 c$ z( h% J/ { J7 y9 \. J# Q6 o* X3 x$ F
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。 a/ ?- @! k% S8 Y9 _& e( _
0 G4 g. ?! N, h14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
5 w# g) d6 l3 x5 k1 e: D回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
- a# s% j4 v% i4 t* l4 W function reduce_fraction(&$fraction)) z1 h' F) y7 [' _
答案是D。
" ~/ c1 q4 n; p/ f/ b2 Z+ a3 d! l8 l B/ A
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
6 N4 r" H8 g: H3 a# c
% A0 H, K6 J1 p+ Q- A9 d16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
0 }8 w7 T; [7 B0 h2 Y
, K+ c t. l) ?0 N" E' m9 Y, I& s17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。% k+ d' {. @7 ~2 X
0 M! E0 j' E+ q& I; `) v
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
/ z" I, I% e' M5 l
% G# s2 A. d$ j# J% ^4 B' A19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
6 E) p m# k3 P4 I/ p
$ w- r) e+ w4 |* {" E3 o20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|