  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。. ^, k U, E r3 a8 ?
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
8 x! b& s! S3 X7 Q! a) s* U本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。6 C& n; ~) V. u$ P7 T
- w2 w* U% [, h: V7 y) N
问题
- X: J# m! g9 ]4 r4 E/ l' X/ `5 M( d& V* T- L% `1 _0 T h0 _7 l
1.对象的蓝图是什么?- n- c7 \" n" f0 u/ h- ?- W: ]6 U
6 w% ^' a: n' e# _* e/ }2 p答案:____________# H, e6 E8 t3 G I
; H0 c" Y) G& U; A% J- s+ }; z( G! P' G. ]; k
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
( E( O. o* L% o! z( m4 h3 bB.b
. Y) ?+ S8 W8 OC.a
. C3 }: h3 |4 ~4 v f$ \D.d+ F3 ^. ?2 W4 n
E.e- q8 S4 s" d E# }7 q! `4 E2 {
$ w$ H) t: n4 b- S# s+ c& ~8 Q! @7 S1 U& P
3.如何让类中的某些方法无法在类的外部被访问?
6 f+ e$ R) D+ `; E6 W( x, L8 ]& _' \: g( q! Q1 w
A.把类声明为private
' m7 H% q$ n/ Z& }" V& e5 n2 S. jB.把方法声明为private
3 z8 N$ @) q& e' \4 t- @C.无法实现
( ~! _* v3 }1 Z0 P: }D.编写合适的重载方法(overloading method)/ A; [7 k7 y, o) K- R
" g4 Q) E" Y# J8 [ d) s ~3 S
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?# h& y" B6 P2 ]( a6 n! N7 g- F
' ~" ^% P% u( ?4 }. B/ |
A.MVC模式
2 c& c E; l {5 g, \ M5 ~B.抽象工厂模式(Abstract factory)
1 g# ?5 Z' r0 t, b1 _: HC.单件模式(Singleton)" X- L J$ K- M1 t
D.代理模式(Proxy)
R n2 X$ S9 @1 _E.状态模式(State)
) B) z2 [7 P1 n" ]& q8 l* y
$ R( i" I7 _) w0 p/ d8 h% @6 a' f# m2 ^) c
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
1 h; \* d0 k: q& F3 V' q% P( g4 V; r4 j* K' h
A.1个
9 S7 B0 z6 k, V; L; Y; sB.2个' H# I( q' x; D+ |: b7 r5 I
C.取决于系统资源% u+ H' {( ]/ B& r
D.3个
0 k& i0 F0 B" P) h) i- i: M7 uE.想要几个有几个
" e$ }0 B. A( }- x$ J+ v' E' D3 a: k* {% @# N0 C1 x8 \* v& S
: [% Y4 { ?5 b; D
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承9 H! d% |) j1 d! m' ~7 l
B.接口
/ p8 t5 A+ N% K0 [+ B z" p3 AC.抽象方法- `8 N2 j. N; v4 j: t: M0 A1 i
D.Private方法
6 ]5 A1 W* T) |8 {& VE.函数重载(function overloading)1 J0 ^0 f! y& y& {
8 w; w& }4 f$ o/ ]+ u1 o5 `
+ d7 r4 T' ?' S2 ~; r7.假设定义了一个testclass类,它的构造函数的函数名是什么?# |: O4 Z) e) x [8 ], x. z! }: X" J
: g+ r3 {/ l; m# m4 H* J7 C! A
A.__construct4 T; T* A. Y- u0 p- R U; M
B.initialize5 Y" @ p7 m3 G2 }& o
C.testclass
! N3 ^8 z' _: n; x6 |: |D.__testclass
: n7 I' s9 K0 a- NE.只有PHP5才支持构造函数% S( m7 ^- d- m+ U" t* c/ J' l/ }
* w X$ o9 w( Z; ]
: e* N& F- S: g- P! ?8.一个类如何覆盖默认的序列化机制?. L6 o; ? _. v6 h" A; ~
4 T5 ^/ X1 | Z; T8 w# W8 aA.使用__shutdown和__startup方法$ O4 B* \7 y$ x/ r. e
B.调用register_shutdown_function()函数/ p* ]1 s3 Z% C4 ~5 q8 m
C.使用__sleep()和__wakeup()方法. ?& S+ I0 ?8 A, J( h* W' `
D.无法覆盖默认序列化机制6 B1 y$ W4 H4 k. \, N% ^
E.使用ob_start()将类放入输出缓冲中
; A2 }; ~! l0 e" \0 _! z/ K6 V
0 c- l9 c) {- H2 l' b) U8 B( G
* c+ K3 Q4 y* Q( V1 l7 v9.以下哪些面向对象的概念无法在PHP4中实现?
. {$ C1 |" \5 u2 s
$ c# H) Q+ v- Z* K& @- ?3 N@抽象类- T, u! a) a: f9 T) |4 N5 ?! j% Y
@Final类
. t& p6 R# e( C& @8 ]! c@Public、private、protected(PPP)方法4 j6 W# I; I' Y1 _1 y
@接口$ I' l H6 b4 D; b, i
' ^- v( A! F, U0 \; E) G9 U
A.抽象类
1 c" r# p t; T6 @/ G/ d4 rB.PPP方法
% M+ m: b6 \# s3 d9 o1 s: s nC.PPP方法和接口
. ]6 Y- V6 V$ t$ ^# WD.以上所有都不可用% M6 r6 B5 f8 C0 U
E.以上所有都可用: l% ]/ ^6 x; z
- E7 L6 M0 R' i9 \! r% ?0 ~+ @" k e" n2 v8 k. y
10.如何在类的内部调用mymethod方法?" s& | Z+ i0 z* K$ U
" b% @, z5 o/ e w
A.$self=>mymethod();
C7 Z6 j! `! f6 N4 _( t. B- GB.$this->mymethod();+ I- P# b6 U7 [' [9 Z, \" h( _
C.$current->mymethod();
$ \9 x) z7 S1 n' a+ ND.$this::mymethod()
: D$ S6 q1 y8 T5 l1 {. b9 _1 m2 [0 cE.以上都不对6 t, O" r! {( I7 r$ D) C3 s6 a
' C! M1 v3 y' h
( m% b; U" {5 l. \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
$ x# W) G% w, d" }; }2 S0 pB.Null& {/ F! v* ?3 P
C.Empty
6 `) ~6 D7 Q4 I2 K1 qD.什么都没有
! H- L! N; \6 b c* @. t3 c5 m; gE.一个错误
! m. P2 ~% n6 L" g7 C2 d
* c8 t3 U1 w6 S; e, U5 i7 X2 T& H* Z f0 s1 l' w4 u
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 d" M" g+ v6 {
B.5
. s+ m( z' Q4 Y5 b: HC.2
. r8 p, k2 b% k) V. l5 _D.Null
+ F8 E' L$ ]9 N/ l# EE.什么都没有
! [( @' I: r7 n0 Y1 R1 q
Z6 Q% }+ \ A+ f. @+ q3 U/ f% K. i: y
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# B S3 `$ ]& T2 ]5 v+ V
B.10
' t% i9 T3 n2 gC.什么都没有
( z) x' Q! |" i7 A3 [$ C& jD.构造函数将报错 Y) p* E) H, E+ r( B
E.510
/ Y! E. E" |, e5 X* C" m5 ]' Z& Q
! D/ [+ k# b5 W: {3 X- n, [) c
& w! j1 ~& [* Z6 S0 \: s& K" F14.考虑如下一段代码,执行时,$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函数必须返回一个值
# R7 p) {# V/ UB.reduce_fraction函数必须接受一个整型值
( v! F4 q7 ^! K( j; x# j: KC.gcd函数有问题
. Z# F8 f1 r* t" f: z/ Q5 E, wD.必须通过引用的方式传递$eight_tenths对象
7 I4 ~3 v/ P4 K( I' ~6 mE.对象的实例不能传递给方法以外的其他结构。( I. z6 j. l2 { m& ~" i- J( ^
& \, P5 Y" s/ N+ {3 x" m# x. t2 i/ I
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法; [ O8 n( T& ^- O, ^* @
B.生成myclass的实例并调用mymethod方法; u: C8 g: o9 ^5 ?$ H" W
C.产生一个语法错误( h5 g8 t8 t/ }5 ]7 n8 |; L
D.默认myclass类最后被创建出的实例并调用mymethod()
9 I9 k }; K4 ?: K7 T: nE.调用名为myclass::mymethod()的函数" I/ L5 j0 S0 C- f, K
0 u' i7 m, s0 b/ m, z- P
# k- `* Y5 s/ p3 P n% E; U0 A4 ]
16.PHP中有静态类变量吗?7 Q; n0 n, Q2 g: B7 R2 N/ X# f
) W/ }, ~5 z8 f3 z* S
A.有
$ D0 [8 O/ t6 R9 x& n- ? d4 s) c# s, MB.没有
% }3 k! h/ Y. f7 ~; e
( X9 I/ f0 q1 ~6 B$ @/ ?2 A! b+ Q+ j
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
0 l; t0 M6 x- G! j$ V aB.2% P. Q: e6 H7 ^ T9 B) F
C.一个错误,因为没有定义a::$myvar
: Z! A, `& }- b7 OD.一个警告,因为没有定义a::$myvar, a& i1 l7 {/ } E$ b, @
E.什么都没有
. e1 p9 c0 s% M d
5 r8 `9 k; E+ H* x6 A d3 _! T |# e. d ~' N6 N
18.如何即时加载一个类?; s8 g# i9 E/ i2 x
6 m5 t+ y$ N; q- b! y* H, G6 f
A.使用__autoload魔术函数4 R9 ]3 \7 f7 t1 x2 y
B.把它们定义为forward类
/ o8 }" y4 C4 d- yC.实现一个特殊的错误处理手段
7 A2 n. Y- s+ k# i4 rD.不可能: {8 k6 ], k1 }/ E6 J/ _, w( D* G
E.用有条件限制的include来包含它们
! X5 N6 r! z* U' k @4 _# A% D3 D3 Z3 i0 j) S
2 D1 [+ E. T. `/ {- T19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
* s/ w% Z$ h" Z+ |4 L9 O& x C! h! r6 I
答案:__________
# k( c! g" E( d" _$ f p; V
% J, M8 d% y* |" E% M8 J) F
" t' [1 R1 D( X/ H* K, E20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
( a0 Y( z) O1 `0 z; K' T5 S0 I7 TB.一个错误0 Y P; q6 D. J
C.一个警告4 U- H# A N, O0 S7 b' O
D.什么都没有
, t- L6 Q! p+ h' y0 _1 }5 f) H9 j9 f, s$ T5 ?8 [2 f0 f4 E
3 r% ]& H7 ]& H- e) m$ D" ~& f; o9 d- J$ \( L
答案速查 T z" g* R. ^" Z
1.类
2 c/ H ^- y: I1 j( i9 U4 Y2.BCD u/ B0 ^' e( g% m5 R
3.C
- z6 m, l" X! ]! o+ x4.C
" u3 F8 ^' b) v/ ^& O0 _2 `5.A* P. A) q! }! l# f' v* _) z
6.C) P$ M# P% e* `. x
7.C
_* D8 C( ~& I8.C
* r) V+ F1 S3 I% g9.D
3 g; ?8 t4 f' {; ?) {10.B
8 g% [1 e1 Y" R& D, Y4 z11.D1 X7 [% \" L8 v) V% N
12.B
% h; \& V8 U$ m' n13.A q. \- {3 P( q* F8 P
14.D
' e3 u# z) \5 N8 w9 O* u15.A
, c) w( w- \- c' \' q16.B9 V# I* n+ n ^+ n% Y
17.A
: K& {" X% U3 n18.D
5 d' F8 Z& _1 N19.设计模式1 G. p, W# F+ v; k/ ]! w- {
20.D
) [4 y# U; T+ R* u9 I, T3 ^4 N/ @! w/ W# ]& [1 v- _% v
1 ~2 q& g( ]0 R* Z/ z. y6 [8 E7 v) h8 q9 z8 I) v' @2 E+ [
答案详解, R% J/ r M* l2 C; g. ~8 g Z" ]7 }
/ F) w9 @' }: d P8 F, B1.类是对象的蓝图(对象是类的实例)。
# H3 b& g) S3 W% c+ ~1 B1 d" O+ ?. c/ s! }& D) W8 P0 X
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。$ l7 l" R3 s- i* s
# U, Y. s/ D ~( e3 T% D: b
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
8 e/ M& ?2 b; ^ s- Y2 E1 g# W& _1 b
4.单件模式可以限制一个类被实例化的次数。& v' i8 I; V- s; v1 C+ i7 g
$ v1 M: D! v' W
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。3 Q: q0 M" n, J- Q" y
6 H6 ]5 a: Q0 y* U# r/ d0 G; U
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。* m2 g4 J: x/ t
- O8 b0 o& y. Z) v8 S8 {
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。, {* m' X+ u* B D- b& C
2 @& S5 F. h, }3 u1 x9 N( n! u; e8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
* I6 M* ^* R5 w- o) u$ T0 ~# ]0 H" [; J9 D
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
$ m" E7 d, ]# T: U2 r
! v; o4 b- T) a0 }10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。2 t$ O" h9 i+ O F% c* O
9 x! I: ?! p" |
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
9 i8 c/ Q0 b7 Y
; W( ?4 V0 c: Z( ?( @1 \12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。) [3 l+ O9 M! f+ y9 H1 P
/ q- |/ I' I7 Z% m
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。. N/ W% [, f) O4 F3 J. P1 d8 y' p
" C3 B# r9 v5 K* ]
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。+ i A* H0 e7 a$ W7 \0 p$ ], j
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
. O' q; w/ t2 d8 C- C2 O. m& ^ function reduce_fraction(&$fraction)2 {7 ]9 P: D9 M s! n- n
答案是D。1 s* _* ?5 h! I
5 [; V4 b; D6 H1 J, _15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ g0 h4 K6 r$ W! A
+ @1 l( ?7 O/ [& l2 G5 ?16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
0 _+ _7 J( D: f- D- g0 p n" t" e" Y# x
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
" t) R5 f" p5 }
, a# Y! Z- j' M9 A3 `( L/ G18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。6 s& v' \; m6 I+ U4 M& ^
; D8 P1 j8 L0 f/ r+ \1 z; x19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。" F4 i3 n2 F+ {& ?# B5 U
) C5 [1 N3 @7 B2 w( |5 Q/ V& D20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|