  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。# `0 l, H+ t; z! j, {
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。1 ~, ?3 ]) M& {$ s5 a# k# k! R
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
0 g& x6 J. y8 B0 c; H5 z& ^+ v" B' e4 i& N( n8 n7 a' a
问题
3 i$ h% L( m2 F
1 V1 `, E" O4 ^1.对象的蓝图是什么?# s! z" Y4 @+ D1 D6 u3 K% k
9 c3 a5 K% r2 _1 ~2 H' e+ O
答案:____________1 {' c& I. q, ~. E" r- p! Y1 w" f" |
5 V5 l/ j- G* q+ Y8 J4 P7 ]
\! t/ n4 o" m- I- X+ p& O- `( P2.以下代码执行后,数组$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
# \* e9 P* u1 [! g; M6 V: X; `B.b; m7 W6 f9 j" f- _; @% h( N
C.a; ]. _) n- W( ^3 R! O
D.d( C1 G, I" V( H2 r9 A
E.e; {, c; ~( o% X
" x/ L! @0 x# r" [ l( }
- ~$ e6 \8 B4 F- v+ H5 o% a3.如何让类中的某些方法无法在类的外部被访问?
6 _. H, E7 X0 D3 s! r$ B/ u
8 u: c( p; |5 y) R! r3 Z+ ^A.把类声明为private
, B& D4 `- u `/ ]& x2 Z- XB.把方法声明为private8 b2 o. q. m& F0 l: O' l
C.无法实现, f4 o# j% _( e5 P/ q
D.编写合适的重载方法(overloading method)0 b& [$ e( k# D5 G1 O
, }; t9 Q* h0 Y1 k
9 w& @7 M& q1 z1 H& `4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
+ v/ O, E" ~4 i/ L4 w3 {% m
% A* Q$ m0 a$ k5 }A.MVC模式/ r4 {4 W; b( O' C1 _" y& S
B.抽象工厂模式(Abstract factory)
+ W8 ~) T* u1 r# d! uC.单件模式(Singleton)
$ P+ X0 R! N( E3 @( xD.代理模式(Proxy)
, m7 w# L" W: F$ iE.状态模式(State)
8 E( R: k3 Q. F: Y) W2 W7 a/ p- R
; }+ t6 w. w7 N( w) r, T! l, i- i# @. `9 b2 x9 \1 x3 A5 e' W
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?) O7 N; w( v) H0 i; }
$ `! d" } E% e& L$ o8 D# H
A.1个/ e( m$ e* m/ E2 |3 I# W% g5 i
B.2个+ I4 [' t2 [+ y( m1 k6 | j$ _
C.取决于系统资源- s4 o. t! W- b- l; Z: q
D.3个* E J; t/ [5 w8 n9 }1 h5 v8 l
E.想要几个有几个
) S$ V: H; {# r9 F: x8 u
4 y4 R+ G7 }3 o! A7 e* \, `4 s0 c( ^, g0 d2 P
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
. L/ j7 w* O b7 [% x0 N+ ]B.接口
0 q7 \( O* ?( G' J( TC.抽象方法
) Y* a$ a9 `9 s6 e* l, o3 TD.Private方法
: S; q2 r' }& ]3 b7 r R- e bE.函数重载(function overloading)
) D- \1 w4 k: y& h- w
" w6 o5 E& L7 x2 z1 a; N9 [8 g. V
* `# a5 I$ c) h/ I7.假设定义了一个testclass类,它的构造函数的函数名是什么?2 W- g9 a3 j9 |! x1 A
- T Y! A7 T# A. C+ h1 n- GA.__construct. p. `' O+ ?% B# H2 ^1 F/ P
B.initialize/ u! d- T2 Y# v
C.testclass. ~0 x( `0 d, h. d, X5 i
D.__testclass
6 y, y+ I; n& P6 u0 S8 mE.只有PHP5才支持构造函数4 P2 K' C+ x3 n$ j' F6 b
' G) O7 i1 Y4 E1 G7 Q8 N7 M J& H% v2 a
8.一个类如何覆盖默认的序列化机制?) U5 k; P! b& Z' _1 ?
; |3 r/ [ k7 }
A.使用__shutdown和__startup方法
5 T5 B. b% O0 B0 [5 [4 lB.调用register_shutdown_function()函数3 ]6 X+ h( X: |4 _$ O
C.使用__sleep()和__wakeup()方法
' N" S# g2 H Y h4 gD.无法覆盖默认序列化机制
) {" V2 b0 C1 V4 Z* ]9 pE.使用ob_start()将类放入输出缓冲中
$ X" i, b, L6 }, K% `- }
( w9 ?) ]% P/ k5 ~- @1 E& ? C4 F& w! A* k7 `/ }) s2 D
9.以下哪些面向对象的概念无法在PHP4中实现?
9 F; }+ R- a g5 f4 t' w6 [3 O a) E
@抽象类3 \% Z* r/ @% d6 e2 u/ F
@Final类
( |, a7 b. l D/ @+ G4 F@Public、private、protected(PPP)方法
5 R4 A: w$ H8 @@接口
5 x1 I0 K' _2 j: _9 n& ^& ^6 I7 t6 i# N( Q: e4 g; K
A.抽象类
' D; v/ N- p6 N9 MB.PPP方法9 x7 f/ n' w- M- s' Z2 x
C.PPP方法和接口
: D) w# j% @1 s- z# ?6 }5 O$ hD.以上所有都不可用) ^5 V+ O) n) ^: w5 k. l
E.以上所有都可用7 j# o( e: P4 h* E/ u/ a7 s
$ s( [% a, w9 |, P1 v# x
& `- C: ?, h$ \9 w! e: u10.如何在类的内部调用mymethod方法?! M9 u( U$ F4 e% j# p5 M- R
$ _# x$ s( v% iA.$self=>mymethod();
z4 d: z& G" j4 i/ Z- `B.$this->mymethod();5 M/ E! V7 G# G
C.$current->mymethod();; F3 P6 Y( v3 a3 `; Q6 _( D
D.$this::mymethod()* Z4 `2 }2 ]3 e' Q
E.以上都不对
. n+ T) h j5 _1 o3 G1 a
# K; K9 h/ g! W3 v* d) V S7 ~5 E
2 q2 }3 G( I9 r: p5 ^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' @0 F8 g% L( g' u3 n" H, Z
B.Null4 z: n/ \9 F* T9 T/ e: }
C.Empty, n# l5 r& a. ~5 ~4 u* S& F2 h
D.什么都没有6 {" u5 v( Y7 L' W! o, o: C0 @
E.一个错误6 S; P/ J/ X/ q2 C
0 D0 Z. d7 i6 F5 Q' }8 L' w5 O; b
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) q( x0 J n2 {4 _, y
B.5
0 s) e/ @( a( T" _: \! X4 jC.2
+ S! J, B" i" XD.Null
4 n6 O4 h, J( ]9 W: QE.什么都没有
1 b+ h/ R) V0 x
+ ]9 d$ y% W% Q3 @ }5 l% h
' z, Q! u9 w3 k, P5 s6 x13.以下脚本输出什么?-
- <?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& o5 ? D D0 c
B.10
: E* c' Q9 [# GC.什么都没有
0 h1 O1 F; e G! w. [D.构造函数将报错
# t* |1 y" L: e( s. U9 [ \: iE.510 J6 a* A/ K) d2 S
5 M1 M' j t* a b( H
. V8 L/ y* J5 c3 @* o+ U14.考虑如下一段代码,执行时,$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函数必须返回一个值
5 |& p$ J! U# j$ D; ^9 H" l, k9 BB.reduce_fraction函数必须接受一个整型值" F. F9 O% }) v( U8 b6 R* |
C.gcd函数有问题
6 k, Y7 W3 l" X. S) oD.必须通过引用的方式传递$eight_tenths对象4 g1 R ?; j8 n$ z# p& |
E.对象的实例不能传递给方法以外的其他结构。
9 S9 `+ S& {1 d7 o/ L! G8 D+ ]0 X
+ }/ L* f" @* A# k- \% Y
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法+ G# B! [* }5 S3 @6 q# d+ s7 P8 \; \
B.生成myclass的实例并调用mymethod方法+ q0 J$ m" [2 o9 ]
C.产生一个语法错误
$ n: _4 Q- I. z6 J/ rD.默认myclass类最后被创建出的实例并调用mymethod()- S7 }1 U, o3 Q# U# _: J9 D/ ?
E.调用名为myclass::mymethod()的函数
|7 r- _6 b7 W& e
# }3 i6 ?2 o; L8 W4 Y3 {! w$ v& g" g
16.PHP中有静态类变量吗?* C$ c% X, @" ~7 }4 Z2 h
2 N) F9 U% M3 Q5 T$ |2 o8 Q
A.有
% R* i0 H" h/ T. B) j1 x+ w' F) CB.没有% |8 j E! S8 T4 _0 d0 s8 e
8 B- T8 d- I% D9 z8 ^
2 x" V$ ~9 L9 x0 f17.以下脚本输出什么?-
- <?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
8 l9 B2 x, L4 I6 pB.2( H9 O7 N, j+ B$ R& S$ Z
C.一个错误,因为没有定义a::$myvar
" m0 m& O' c( F5 c0 pD.一个警告,因为没有定义a::$myvar
( T0 _8 J% J1 X$ w) O2 kE.什么都没有
* F$ ]* f$ X; t0 U$ E& y3 R% z) F# E4 \: r. `& ]: [2 |) k& ?3 @1 S) h
" R- u" y: y$ V
18.如何即时加载一个类?+ }9 b f* B1 }5 t
, J' {! x; W4 L0 ?* e* bA.使用__autoload魔术函数
; ]7 H9 G& G# T, E: U& `2 YB.把它们定义为forward类& b' }8 v$ k* d- C# ^
C.实现一个特殊的错误处理手段
0 v( U" r0 z) S' g, N; d7 ]D.不可能
: A, K! Q1 _4 \1 V% S! j. DE.用有条件限制的include来包含它们# L+ J w. @9 m0 ~! s- |
* {* o; T9 z' P" u& k7 B' x
9 ~, @1 M5 J1 I19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
4 t6 Z4 v) R) a: j& k; ~' T! w3 E f5 x0 x4 d7 [' c% d
答案:__________
5 e3 C4 G) W6 A. A, s( v
5 y2 _( M% v% Z F( a" t9 C) @. K B; t1 a: r/ G1 e
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
( _- l$ f) [5 c- P4 @5 WB.一个错误! ^; \3 W+ K' L, l D" o
C.一个警告% ^& w9 u4 Z7 Y5 ]0 d+ {, }
D.什么都没有8 n$ N4 f0 v7 p! e# v9 S! O
1 [+ }4 E" c% q7 m" j* w5 B
+ Z3 H. s5 g* H1 q7 [4 {( e
D* K+ \" ]0 i( X
答案速查
" C5 E* e( z% O8 f4 @4 e1.类, Z2 k1 P8 O+ g N6 c Y
2.BCD
9 A1 A: d7 y3 x: J" K3 i9 T& u3.C
, o1 `3 B# w# i8 i h9 O( Z4.C
: P, ~8 I- T/ Q3 n" y5.A
% I$ z- b0 Z( ~8 r( B' c1 w6.C
1 C: N8 M: v: F. L1 N( H( G7.C
& U! C9 o, B P) @8.C
! I: Z c- I l6 h) [5 ]3 g9.D
. X3 k# y* H# h6 i3 R3 o/ F10.B
' t# G( x. G- b3 p' d+ N11.D
6 _, ` Y5 I% _$ P* }12.B
3 D4 r0 s0 S V- @+ Z13.A3 @ e) _* F$ g C+ N9 A0 Q
14.D
1 k+ Y" z0 g& o7 w7 |5 K$ E15.A$ N) e/ U& K0 I; v. C
16.B P8 }" k/ W8 h4 p& _
17.A
$ O: {" E( r# z3 S; }) c: d5 `7 }18.D
- n2 n. G q- t, n! R2 M19.设计模式+ r" ^1 [3 E( V3 c
20.D
3 K" l, h6 z4 J z+ s X* _; M" Y, h5 K7 C
& N, ?8 K: H' r) m8 r, Y4 e; v# `+ f2 {+ t* `9 c7 q
答案详解! r z$ ~* q$ L8 t
7 N* d+ B& E0 _9 m/ B$ i
1.类是对象的蓝图(对象是类的实例)。% @' j8 n1 P( q& A( w5 I
2 g% L9 d9 V) [. E# Y3 v$ O v& e( N2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。0 ~/ Z% i% h' Y2 \ Z0 p
i) G# r( x! O( o1 a
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。$ D$ j1 P" @6 r
; q: n7 o' ]3 h7 d( a" b" |4.单件模式可以限制一个类被实例化的次数。
, C& l% L2 B" X, s; L& K) f) N1 }. H. ^1 i4 H3 t
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
* b2 z( {8 O: U. n! W- ?
, _ |+ m$ p! y4 P+ t" t6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。9 @7 x; S9 v1 L2 v- _
5 y; f9 d8 F6 [; U3 c
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。- \& E' i* n# K5 ]7 W! Q7 [- I
) }6 |! o* I% |9 x. ?/ v \3 u
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
/ `) j2 G& S3 g5 H8 U" g K7 m
( T, W; V' ]7 c, \; L J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
8 o6 p, F/ p9 W1 ^" Z/ z% D _5 N- x/ r4 g
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。" a3 J' b5 W b$ i' I
- `* H g+ H5 y! K
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。& H! M1 [; k# q3 q& r4 B( @: \
0 Y& T( T& C# V/ S: X3 X$ D# T- H, E12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
) I# q5 d! ^$ D" I6 l! d) {0 ? N* X+ s! Q
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
2 O7 Z" w. n+ k( f: a- Z6 q6 ~/ X7 D8 d" \ j5 E
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。& @& f& W* B( ?5 U0 ^5 \4 I
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:4 H/ r0 Y+ B6 W: N
function reduce_fraction(&$fraction)
% L7 j$ p9 b" s答案是D。
2 h1 _" o% F/ V3 b% M% v( J0 Z/ i
' {+ ] m, e8 s/ ^. l* Y15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
( C- k3 Y! r; i$ s; m/ g8 d6 S
1 t: p" u9 h! f+ U; ^1 s2 h& h4 L16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 n! Z7 m+ D: }9 i( F
# ]$ c* d6 g( K% C/ C" b17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 F7 K6 S# f6 M" E8 k s1 z; t; a f. O# s
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。! | c Y3 |5 G) V# ]1 _
* I8 h9 f; W* q B19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。0 T2 l% o9 }) N9 g+ {1 R
* N9 s/ H- j6 T20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|