  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
3 v: b8 @( _( ^, j" ~( b3 {% dPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。! ]4 b3 D3 V" H0 V, b
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。1 W1 i6 l: {1 F& Z: |+ c# W4 h4 J4 @' p
- V1 @- [1 B% o V1 X; o
问题9 W5 v, q' B' m
1 |: X' G1 @& }& F/ w2 d
1.对象的蓝图是什么?0 N2 }& H8 L# d
, p, A5 a6 j0 I, ?9 D
答案:____________
5 H. ^3 {+ M p3 y- H' q7 h Y
8 B# v% m4 [, F
8 I* ~ N- x |) d2 E4 P+ j2.以下代码执行后,数组$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
% g- a: m' D. _* Q: Q8 a) L- yB.b
9 y9 a( r# o. ]/ IC.a* I5 m9 D4 }' b
D.d
5 E& L) _- d+ P% p$ _E.e9 {8 ?+ K3 |4 ^) D+ X! m/ R
; {" w8 X' d4 g5 _4 D6 i
! r- s! j9 C5 u5 b9 h
3.如何让类中的某些方法无法在类的外部被访问?
P/ F6 n" _! H0 P! f: N' K
& P6 S& F9 q6 o) Q3 G% v/ AA.把类声明为private
5 ^- e$ \1 e3 }2 t. hB.把方法声明为private
: X, L; H8 n/ G; N) _C.无法实现' Y3 X& w* |( \6 E% |, r* z
D.编写合适的重载方法(overloading method). h/ P( ]7 G3 r3 Z' D$ b7 s
. b% v. \) a7 n# v7 c: t
$ Z! V# f, z/ i7 z+ }- a
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
9 E$ x: C, m6 s+ T; V; X3 K; Y- T( q! n. ?( i. @- W, A
A.MVC模式
9 P* `6 a' ^- G" s. q+ h% GB.抽象工厂模式(Abstract factory)
) q* ]: H0 N* A& ^ K" \C.单件模式(Singleton), O1 m. R+ j. h& l% `. @. w, b, j
D.代理模式(Proxy)
) J. p9 U+ i, n1 u3 p+ GE.状态模式(State)% e% A7 |. T; I! G( g1 C
- D% o9 v7 Q& W5 p, ]0 s
( _" f# L* J6 x0 j5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
: _9 y8 ]* C# N3 I* o% ~- f
( w! F: }; g! b4 K4 b$ u! F: gA.1个0 F& J1 o# D0 X& j2 a) z5 [2 M/ Q
B.2个
1 r6 z( K$ x/ l% \. N) MC.取决于系统资源( f8 X `) Y) u ?5 v g7 m2 p
D.3个
+ p1 i+ e- E9 b3 R1 F5 b) ?" m$ E6 XE.想要几个有几个! i5 T* S$ Y6 i* q
1 t* ^! H5 U- P* P& ]5 J
) E& s! o3 W0 o% ]# [
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
5 _8 M/ D$ @; h X% e$ }8 ^3 v! aB.接口
" u) E; U1 V: i% A, o" ^C.抽象方法
7 |6 ~& v! s( @3 sD.Private方法
0 r, Y( a8 D5 a3 m/ CE.函数重载(function overloading) Z3 S( h* y& T5 ]
" s8 U$ y; ^& s/ _5 ?. g
2 R/ v5 a$ k$ t7.假设定义了一个testclass类,它的构造函数的函数名是什么?
. y/ t0 n: ?3 O2 i! Z# q; W! w% F5 M+ U p
A.__construct: x0 Y U3 e7 n9 n: p
B.initialize/ p1 Q' j T! e/ x/ T; F, e
C.testclass
s; h4 M. V+ |0 Q0 E) TD.__testclass! K* b1 e& \: Z4 e1 |9 L5 c2 y
E.只有PHP5才支持构造函数
) ?1 m3 m6 Z, r
- M3 I( r+ F$ p1 Y) @% x! P& \1 c
8.一个类如何覆盖默认的序列化机制?7 b$ y+ T8 e8 |8 g# E8 }
- O, `. S/ Q+ W9 q/ c
A.使用__shutdown和__startup方法
! A% I9 o y" u* p9 \7 o1 u$ C" kB.调用register_shutdown_function()函数
H& A \: k/ F) @5 KC.使用__sleep()和__wakeup()方法" q0 \" }8 z! R3 F1 N7 t" V
D.无法覆盖默认序列化机制+ A+ F- d3 Z' I. L& F% x4 @+ _
E.使用ob_start()将类放入输出缓冲中8 n( k! K, k9 u3 [/ e" ] V3 H
% c/ M/ b1 K; W( Q6 ~7 b% E4 Q1 c5 z u0 b# q' `
9.以下哪些面向对象的概念无法在PHP4中实现?
" g0 x8 t1 a* O v; E, t2 o( c. b# g. G, G& B
@抽象类
( j% n( R! y' l0 l; ] q+ R+ z@Final类# h9 a q8 j& }2 [. x: }
@Public、private、protected(PPP)方法0 O; w+ x# ]5 m3 n
@接口' b% q8 R5 t$ R- l& |' f9 U0 L
0 [* b0 U" k$ O# ?
A.抽象类
( ]2 T- w& I0 T7 k! qB.PPP方法
6 x( j/ d5 e1 k8 b* m3 J! z3 nC.PPP方法和接口8 g1 N% t) r! T: a. ^6 y
D.以上所有都不可用
& O% V# f3 q8 ^( d1 a+ vE.以上所有都可用2 S" v5 u+ t* s3 J, H% ^; G
6 E0 k5 {4 f0 P: M
+ E) \8 g" `$ }$ y10.如何在类的内部调用mymethod方法?
$ X$ H8 @. b" j, c0 y& P; l7 O6 a+ W/ ]6 |! H( `6 [1 a
A.$self=>mymethod();7 @+ g: p' l0 K2 s" Y& H2 K
B.$this->mymethod();
0 Q; k6 x" o3 x2 u* j" `C.$current->mymethod();# A4 v; K+ m0 g
D.$this::mymethod()0 l4 J) F& p, H) @) N- `' {& R
E.以上都不对& Y* `7 @, p. |; V
: y1 \2 |4 w- `9 H' C" p
% X. D6 [+ W) g11.以下脚本输出什么?-
- <?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
7 z% ~. o1 C' L( n& pB.Null
* N" U6 g& l$ g$ _0 PC.Empty
& c& T+ b, P! j3 QD.什么都没有- u" Z1 a( q8 {& r- n
E.一个错误
& |8 X0 z0 E& [: T1 T& h9 n7 l. E) l4 ?
' ^& H4 d5 A+ }) T7 {, U12.以下脚本输出什么?-
- <?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
5 Q7 P& j: k) r* v7 `7 U6 o$ IB.5
% p3 {2 W) E/ u- T. ?C.2 b0 J4 A% L8 ~ g. m# d% w
D.Null
- y& R2 C; a% F/ DE.什么都没有7 b( R# F8 \ y ?5 i, s
3 I# T" I9 B3 Z$ Q
6 t0 |' A* h3 f9 W
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# y- i2 E8 [* f
B.10& E# C/ D4 g8 h( a3 h5 n* M) Q+ ^
C.什么都没有
: U D0 T8 s/ t8 `3 R9 @2 cD.构造函数将报错- o3 j% F& I6 {
E.510
: U! P& s2 A. b& z9 F- D4 d' t P! k; }0 e; X
% z6 z0 F0 D- f$ z6 b6 t) R3 l14.考虑如下一段代码,执行时,$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 Y5 O2 {0 a3 W$ h
B.reduce_fraction函数必须接受一个整型值, R; H5 e/ g3 M1 S9 ^/ S& p3 R
C.gcd函数有问题
/ Y1 `0 t a- ?* `& n% o7 W2 [D.必须通过引用的方式传递$eight_tenths对象
( x3 ~/ b% n' Q3 N5 w6 `E.对象的实例不能传递给方法以外的其他结构。
+ ]* A5 @; y6 W& V, u; P" p2 f* p, Y' Q; S) n4 U0 f
& F6 D& W8 M2 j/ D15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
7 X8 F/ Q! t# k1 W* ^2 e4 g: L5 n) S/ L. g7 aB.生成myclass的实例并调用mymethod方法 y9 t- P; Q4 f, f
C.产生一个语法错误5 v' P* O$ C! K: o* U u7 X
D.默认myclass类最后被创建出的实例并调用mymethod()# @5 s) [5 u$ j) Y0 y
E.调用名为myclass::mymethod()的函数/ c& T& l: J% r( I2 Y+ V, q
- ?7 }0 x x/ _* |4 R
! {8 c* K2 t, \# w/ t. o* t16.PHP中有静态类变量吗?
}. _5 P( ]4 z. M2 i8 }( ]% k' W7 D5 Y+ B) ~+ M
A.有6 `7 l5 R( b/ \7 n% R* _1 H! \
B.没有$ w( w1 ^* Y8 y3 @4 Y
# `4 `6 d" N' e& G
4 D) c7 Q- d9 ~% s6 \/ z8 K' L17.以下脚本输出什么?-
- <?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
* Q( h9 M+ |4 A: O0 x5 d# pB.2' a9 ?% `3 O+ o3 Y; V
C.一个错误,因为没有定义a::$myvar* m: o7 T! w. u- g) S0 N
D.一个警告,因为没有定义a::$myvar
1 F( S8 U8 O1 h! w2 WE.什么都没有8 {* R; J# h* E) [: x& x! Z
; z$ i* v! |! |3 ?- m
$ |1 @ o5 A3 _- F1 y18.如何即时加载一个类?/ U! x; H i7 M, [# a
& h+ C) E' i2 a9 A6 \
A.使用__autoload魔术函数( o9 w. X3 I" m3 S$ A! j O( E7 }
B.把它们定义为forward类8 q/ t! v7 ^3 X+ v; {, ]
C.实现一个特殊的错误处理手段
+ _" v% |3 o, E( d4 A! b) e" o" g) ED.不可能5 U/ z" h, Y) Q; a
E.用有条件限制的include来包含它们
6 u( i+ P) W$ }% @; G
* I* e1 Z5 _( G7 C+ |. u/ J% ~3 ]( Y% z2 \
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
; Q4 p' }; S4 S0 h }- C2 y
- |3 J! R; r: A: H9 q 答案:__________! a9 |. _% X3 T! J
8 p" {3 d2 A" s( q( H; W: Q5 O7 q
) z/ \ t7 v0 l5 E' v" `! x$ j/ r
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
1 x' A, F9 S( f! B' S8 F6 T5 dB.一个错误
! G- C* K1 k# ]7 BC.一个警告/ n! b# q* q7 t2 i$ }; _) g- s
D.什么都没有
/ f, @+ g/ T, l% N$ U% h1 ?& J4 ]' L3 {4 G( h1 m' P& n4 ?( p1 R9 f
) ^2 ?) F; ?, J0 Y% j1 N9 z$ T
$ }2 d, n' o. A* k9 L/ f- x答案速查/ }' C( ^! Z6 }" E+ V
1.类
0 n6 ^8 e; ^2 [8 H1 T2.BCD( @! C# a+ X. T7 a g( I
3.C5 R2 C7 p. L8 g. @
4.C r" ]- C* c6 i- ^" G0 q& S
5.A2 G7 N. B+ p. Q( k% u
6.C/ o, ^8 K+ O' i' o1 b/ P" i
7.C( h9 @: d% B3 y- ?4 Q
8.C
: x: K6 T! n' A9 W# Q$ T6 r' v1 V9.D' B$ S6 E9 r" j/ Q' G% Q
10.B
) }4 d! z. p, t$ G' b11.D' S7 z9 [ n- n" M" U8 M# M, l
12.B
7 u- n1 T& Y! I$ i4 c1 V13.A
) F8 i( l8 l, V14.D
. N6 y3 |& J6 j+ Z; E4 F, x/ J4 \2 T15.A
& s; T" l7 O. @6 f' |& `16.B
6 j/ |9 f; A; v+ \" M" @6 h" C17.A
) @% O: o: ?% v% Z6 j18.D
1 d& w' x* c* P( v H19.设计模式
& D0 n+ H% F9 f20.D/ l* |: e/ P5 Q# t' m, z
& X8 ]" ]; Q4 p9 r1 @# R1 O4 D
- D; ~% R, B3 ]; h) O) E# Z, Q: |; z, z
答案详解" H+ I' ^9 p: v$ e1 a! l, s5 L* j
! `/ O5 u$ a- J1.类是对象的蓝图(对象是类的实例)。6 P" X/ H: ]8 C2 g# g+ H, e
1 V |( w3 U4 _( f/ B k2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。; d4 I# J2 X( ?* N, Y( A! M# \! ~1 Z
8 I9 }; Y# F: b' q2 E3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。. L2 w3 U* J2 V5 i2 c
# K3 z- j5 \% a4 f
4.单件模式可以限制一个类被实例化的次数。) y8 E9 W: D/ ~; ~- m2 D3 X) L
) \2 e& b+ F+ r5 m4 C
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。' U7 q! c4 O0 I2 l
% |3 k9 I" D. ?9 X# J
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
* y$ ~+ M9 B2 T3 a4 Q! r7 I r2 @. {, W3 ?+ H/ D
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% s7 t8 _9 ?) R
) Y: l* N, p$ F2 |" ~- O4 C# f
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。2 x9 X& i% G& B5 ^, t$ q
: K. |! K" c- T. I( ^9.PHP4中没有题目选项里所列的任何一个概念。答案是D。' ^' P' h4 m0 n' b& e5 n
O/ w& V% P3 w
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。! E' ~: T9 w& t I
: F3 F, J: d0 D- p* i! F- ]' Y11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
; m7 O9 n, B$ W& K: R; v, K. D N5 ^8 }& W6 `" O9 c7 J) o
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。9 M$ S5 h: H( _; x, B
4 F) B2 a( E5 t B# q- G* }( K
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
2 a- @5 O# H' \5 Y5 g
0 r& P- X: l' y# ^14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
4 R: ?! n( X9 w( g- A. c回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
2 @4 p- l* t" d: A, n function reduce_fraction(&$fraction)
" c! j) A6 e# \# ~, w( v% w答案是D。
6 w p& ^7 Q. ]% x9 m
Y( |# \- v5 z9 Z0 {15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
: S7 d) e3 F1 t6 f i d8 y6 a! a% G2 K0 \2 g; V9 [' W6 t- x& n
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。# P( W* u! d' x, a3 I; ]8 e
, g" U& D& U8 U Y9 U% v4 S
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。* S3 }$ g) _' V: N7 e
, g+ r$ S+ [; P- Y8 ]+ f* y! A18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。: K+ f$ `* k; p; _: @. n+ N; A
3 ]6 o3 w% R/ ?5 l0 g19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
+ x4 `& ]& R1 |; S# P6 b+ c. z: c$ X: @+ ?) R4 [# J
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|