  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14249
- 金币
- 2415
- 威望
- 1647
- 贡献
- 1363
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
; L0 L5 p; g. k; {PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
: Q; f) }6 a8 G$ v" x本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
1 [* L2 U2 J* H6 ?( E8 d
: ~- h0 [7 L M- D问题6 i; W3 c/ ^4 \, G5 l! m! ^/ P
( `" n7 }1 n) Y. ]1 S6 Y4 D
1.对象的蓝图是什么?
3 b5 U% ] k y o% G
! O; e8 X8 a: }& h" P5 w答案:____________% F! H a3 j! E# O' x
, z& W/ w8 A% B! f. [2 z" o! t
; m9 g3 Y% Z4 W) J$ {$ r8 N+ }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
; l' P1 c2 Q$ _8 aB.b
; C1 @& P$ `+ o' H! yC.a1 r4 D; I( I4 [: q/ _, V1 a
D.d
( f( L6 N4 x A0 ]E.e9 W- j: e0 J) a5 ?# i4 b
6 w# }7 b* N C8 U }+ F4 F
) b! z0 j8 [) {' b3 \/ z6 v3.如何让类中的某些方法无法在类的外部被访问?7 J+ U3 Y! w# I/ g6 |
/ i$ H- D! [; S( _) U! }: \" G
A.把类声明为private
% `0 o' }, ]& P& o+ n" jB.把方法声明为private T% z' P8 x9 ^ F. J
C.无法实现' s. o* ^) q% H, L. i5 \% {' b3 }4 o
D.编写合适的重载方法(overloading method)* A& A/ y% z: r. Q$ D
^3 v% R# H }, T- c; h9 c0 w$ d
2 u/ {" L; L& H; V9 J, T4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
" p' `- c. Q2 n" [9 k7 u
( h( ]1 j5 l0 L' cA.MVC模式
' F: P2 b$ G5 k% z: Q& qB.抽象工厂模式(Abstract factory) k1 r4 |; o; y
C.单件模式(Singleton)" W5 F4 t2 x7 d/ ?
D.代理模式(Proxy)
, {. X9 ~3 l5 {% V7 t" C( a) YE.状态模式(State)
" \! c4 n7 }. P B2 Z! g4 ^4 c' R( H8 k7 N' z7 U8 P) |
/ L6 N3 p, z. ~# s
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
: g) n7 `, E) s4 A% T( G/ `+ Y
: }6 l( |8 F2 n- f/ X& h4 }; D4 FA.1个
% u W K) L9 o# m6 ~: u M/ _9 kB.2个6 L0 @: f8 M1 ]( C% u2 o
C.取决于系统资源
i) R- m. U# c% dD.3个
* z1 F1 ]. H- a# XE.想要几个有几个
$ h/ y L, u& |+ i: V
% Z' s% Y4 O/ V/ {1 g
5 z& t# \* q) N) O0 P6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
/ Q2 A% D! F8 t5 Z6 q7 Q/ \B.接口
1 G0 y2 N6 j) Y6 i# pC.抽象方法/ n6 }& L2 q. L6 K! `* P9 c
D.Private方法; l& k2 U+ v7 u! {) Y' h
E.函数重载(function overloading)
/ ]* ~% A$ h0 E/ f" H" G0 Q) D l3 S/ Y. y. T$ J( t9 M- {" w
9 e$ T% O3 Z V5 `% ?7.假设定义了一个testclass类,它的构造函数的函数名是什么?
. i2 t8 x0 ]3 s6 }3 t
1 ]4 W% H9 O* z0 N5 t9 LA.__construct
: L) g2 h v" i3 K0 }# d0 \: }: uB.initialize
A0 }4 V) {3 o4 z6 X$ ~' oC.testclass
9 N! v! ^9 a5 U* i; F6 ^. nD.__testclass ~" Q7 S; v- ^ t: I
E.只有PHP5才支持构造函数
: F+ b- Q8 R# |# w5 ~8 x$ y
* k0 Z. M7 r- l8 `* n! [+ o3 `' d- M' D1 q* g6 M+ `
8.一个类如何覆盖默认的序列化机制?
/ E v- Q# u5 \# n3 e) P( | P2 Y# o0 _ M1 o
A.使用__shutdown和__startup方法. @4 c5 P( l4 V! v6 s
B.调用register_shutdown_function()函数: k9 S0 B: M$ ?6 x4 ^8 h: Z/ D
C.使用__sleep()和__wakeup()方法
; u( I4 ^7 M0 }0 r3 RD.无法覆盖默认序列化机制
2 O f7 g! s8 X' M4 \' AE.使用ob_start()将类放入输出缓冲中
* I( K6 c: ~1 h; L: L" E) k
; C1 J/ j( `' O: l
( O6 D0 Z4 Z6 [+ [9.以下哪些面向对象的概念无法在PHP4中实现?
$ J9 U7 p- d: K' I8 `# B$ n6 t! N" E4 L
@抽象类
: w9 R, F3 I% K4 {' j5 A@Final类
. F( y2 |; W* n4 r1 K. r) T0 u0 u0 _@Public、private、protected(PPP)方法9 i6 t7 Y+ e# B! g
@接口; N, l1 d8 u7 J- N/ J9 K7 z# z
3 Z! o3 j v9 t$ T
A.抽象类5 a$ Z. c7 n" }9 Y
B.PPP方法' |/ J' P7 @5 k7 T$ v) a
C.PPP方法和接口; N" I, w% a$ e/ H: g
D.以上所有都不可用# `3 o3 q1 D; }/ X2 V8 A2 w- Z
E.以上所有都可用1 `9 W0 F& o: ^1 P/ Y0 L
; H4 [5 K' M* J3 \+ }6 p5 K3 n. w
+ C3 }/ `0 D( M. c# }
10.如何在类的内部调用mymethod方法?- I, B, n! j2 A; Z
, \% [! ` z. s- wA.$self=>mymethod();/ ]/ @3 s! V q% a
B.$this->mymethod();
( k: q {1 }8 W4 ~: Z* I) }C.$current->mymethod();
. X6 M$ a. N8 j& ED.$this::mymethod()
0 x0 F/ k3 N* G1 E( vE.以上都不对" X: O# q7 { |! W0 Z
+ o+ v4 A6 D' l% b6 A& y$ m
8 K6 u/ l3 g& s5 ^& i5 |8 g
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.105 T$ R0 u" p- A" M; p5 z, _2 D
B.Null3 k! E, y- O9 ^# i# R
C.Empty
* @9 H: c( L/ V- {1 N* ^D.什么都没有4 j# S9 [7 a3 X# B9 L2 x' P
E.一个错误* G; B) B! }" V& x& n# }/ F
# A6 J3 d h& m6 N. \
- v% n( D0 q' j s
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 r- V: x6 ^! O9 |; a' J2 q
B.58 P% x1 u3 F9 O9 B
C.2+ F; k# \* _. C7 ~+ T! ~
D.Null
T4 c- b2 b9 J( sE.什么都没有5 I! U! g3 b- N
# ]7 v% ]" Q6 A& ~2 }* ]& d
9 `% B% _( @) h# x9 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
6 X+ w+ W# S/ r! k5 m" LB.10
9 X5 P3 J4 k" d$ y# }- p7 [% X7 U) Y0 n( OC.什么都没有9 e( S! D4 |8 |# `
D.构造函数将报错
& k( r5 d/ ~" zE.510
7 v: ?; C. e- o
/ S. N/ D0 v$ B. d% w& F; Y6 Y2 v0 P- F, j* ?! j$ M9 Y
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函数必须返回一个值( H* k9 t; H3 C
B.reduce_fraction函数必须接受一个整型值/ @4 y9 x; V1 c i& P
C.gcd函数有问题
5 {2 l8 j k" K/ A- {D.必须通过引用的方式传递$eight_tenths对象
$ v1 A, E8 Y9 _ B1 e" x, FE.对象的实例不能传递给方法以外的其他结构。2 u3 `+ ^. t2 G9 N; c7 h# \
, `( s& e1 h+ ~: D2 y
+ ~' c! r" p7 S' D3 X15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法$ M! c% z! A" N8 Z9 D) i
B.生成myclass的实例并调用mymethod方法 V; C3 |; l* \' b3 `( i9 ?
C.产生一个语法错误" a4 s; c$ a6 Y
D.默认myclass类最后被创建出的实例并调用mymethod()
% X4 t. L" s5 Z p& [E.调用名为myclass::mymethod()的函数
% H K: [' }9 E! z. @2 `, D/ e
* G8 d _& W# {( I. B9 Q
$ ?% k1 x# e/ n* i+ E1 }16.PHP中有静态类变量吗?3 }) r) B# D, r" ?% v
" Y( T/ ?, @! j9 F- u& ?6 N: t
A.有
0 C! \) K. J) L$ h3 q' o/ j4 x9 fB.没有
7 W) o# {+ ~5 O$ J! _% E6 n% M4 @) l2 @
5 x& F6 A& k/ t; M2 o17.以下脚本输出什么?-
- <?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
5 W* H2 R" v/ H- S+ j; j6 P! u5 J) KB.2, r8 [/ x) t6 p. i1 y# ]/ H# n
C.一个错误,因为没有定义a::$myvar
7 ^5 l [4 _3 {# h7 g6 [1 JD.一个警告,因为没有定义a::$myvar/ q+ `( Y1 E1 J' b/ _
E.什么都没有
9 Y, D7 M& Q( i3 u/ Y; T0 p( x w% f% u8 x3 n) S: {
+ {. n' a/ c# V6 j4 x& W) _; e7 n
18.如何即时加载一个类?
+ d6 B2 s+ T+ D% O0 B& z( E( i8 `' q4 t3 O$ D7 }% Y
A.使用__autoload魔术函数
' d/ D( e# F; [4 K9 f" e1 ~B.把它们定义为forward类
, U/ [5 x) @, M2 cC.实现一个特殊的错误处理手段
) d! i) I3 H5 b( Y7 W0 BD.不可能
# f5 Y" A! M& r1 _: @2 L% H4 f ~/ gE.用有条件限制的include来包含它们0 b4 r/ ?- E& a% G# S/ k
# G0 i; j" C+ M6 V% Q
3 Q' a7 ], {) k2 j2 f5 {% K
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?4 J* L- U7 {/ R
' \5 T6 n4 x+ E: H1 m% F P
答案:__________! }* d/ u) d- i2 Q' _+ B
+ L" @ I \& b( x1 _8 `- S& e) D4 y8 R6 t
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called1 _$ p( L! L; I3 k& F
B.一个错误
. W& u" \- Z( c: ~4 J1 oC.一个警告
, n0 v! ?% W. t9 mD.什么都没有2 W# G. U0 Q. e( N1 D; \2 N
~, G9 O! N; ~, M& E; R* P6 c- @
5 r# _" o& _! B
+ j: V- e& E- m% l答案速查% \' I: H6 I0 f$ A
1.类8 `; j- s$ N C% f( Z0 w( w
2.BCD3 y( j$ Z* J' C6 z4 m8 G
3.C ]' d! e- ? ]+ d$ @$ O
4.C5 C: {5 b/ M. l8 o; U+ L
5.A
, u$ F* _/ U+ @# s! h7 @6.C- D/ i, L' Y% e: R9 @- {2 K9 {
7.C( K) w& `0 n7 i; X: s6 x
8.C. ?, N4 q( x }% p" w
9.D
$ A6 |- j* Q/ |$ g. u) h10.B
b1 O6 @6 I2 z& |5 N/ i/ K* t11.D! \" D. z& L( Q% n
12.B4 n* s7 I4 V6 |2 E6 _
13.A
. g) S: `% F- R- f6 s14.D: Q; R; d: e" S
15.A
2 H* C( @8 v/ d* x2 i' o16.B* ]0 q {9 {! ?) c! \! d1 b+ v
17.A
5 ]/ q" [) j1 `* y" o18.D+ G) v; P' `3 N8 p# I, r- W4 m! ]
19.设计模式1 S g1 d" F2 R F. B
20.D0 z) r U8 w6 w; W" ?! p
0 F, \* o& d; H5 W: m
( R G5 r. H2 Q) R0 _. g
7 E' [% @/ K7 l7 k: F$ j4 C答案详解' g2 b8 U2 |. L1 i0 t* p; r
: z9 M/ U8 |8 T9 Y" S8 N8 t3 `% S; u( J! U
1.类是对象的蓝图(对象是类的实例)。
' b- [6 G' C4 @/ v9 {6 s# U
, f! b) ^" M- ?1 }( e2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。; b5 n2 A) p+ o1 q; p' ^0 b
. j9 }/ X& _! ?* R" y+ {
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。, Z6 F( R% _9 ^2 \+ _5 v( W' Q
) P8 |8 e0 K6 s7 P4.单件模式可以限制一个类被实例化的次数。
6 g" u, a% J4 d7 \
, j( j2 }; e t5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
5 H& Y- A% ^2 ~7 {4 |. T8 B, i' @' z# U
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。5 C) D, }5 `+ @" L
3 ^( u- P7 ^* N0 `( O& ], D: r7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
) M4 {$ A# u% @3 ?' [( m" z( _# R$ V$ I8 D& D, g
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
1 F! p' f2 l& A* o: a
0 M5 I( [% U" y5 f+ l1 A: M, s9.PHP4中没有题目选项里所列的任何一个概念。答案是D。7 x0 ]* }/ l8 l9 ^7 m
4 |! F8 K' p& Z
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
0 B \9 K( L! E" }. \4 u8 I2 b: Z: q9 h% |3 c/ n
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
. e2 ^2 u+ x! t
0 n$ u' Z$ v# M; f$ o: }6 ]4 S$ I12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
6 v3 i& H/ g: K; m4 |( I" n6 W" }+ ^- |1 R0 z6 _# g; w
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。$ T# q A- ^) R9 b
7 g B& s" S9 g3 R7 l7 \
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
) u8 v/ H4 P8 h" n( P1 ~& Q回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
. I9 y8 \5 k2 p, x" m; N function reduce_fraction(&$fraction)% c2 h- I+ k, `6 m4 t
答案是D。; G. u( \+ v4 P* n7 e. B4 _; l$ l* \
, s1 l7 e( L: n! O9 _+ }4 P$ x15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
( L0 F3 A3 h+ c2 m6 F
/ P5 N6 `2 l6 P X: K16.没有。PHP4只允许声明静态函数变量,没有静态类变量。! E% B2 m' X$ U7 y4 v- d P
$ p" I1 d+ t8 q% w
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
, _- Z/ J/ u# A
/ ]. l) L! w6 G18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。+ M6 v( w1 k( `/ i4 t
! w/ V& n& U' A
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。6 G6 L& w' d% F
( ~3 D: X8 h; M
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|