|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14341
- 金币
- 2456
- 威望
- 1647
- 贡献
- 1404
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
9 b4 G! P# K5 \8 i/ w% LPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。: ]' R3 p1 l/ s: E1 k; T& u0 K# j6 J
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。/ [8 U! r' ]5 ~, F# {
! s M* s* C \9 V
问题9 s1 R G' i" \
8 U6 \5 j& }# F: A \6 Q6 e1.对象的蓝图是什么?
+ X- m8 j* v8 _! I* ?; E! A# |' T3 {+ T
答案:____________6 D& j0 n( D- @; j2 `# X# _
9 i! m: x" z/ y
7 v4 V8 z3 ?3 ?. w( n2.以下代码执行后,数组$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
7 R$ G) Y* d9 |B.b
/ o5 M, y( _9 i3 M8 l$ M/ m2 uC.a
% }: a- d& `5 M" I6 b4 GD.d! L( z T" O% d, B6 T
E.e5 O+ L4 H2 D& P
( k/ v3 q9 ]5 o! w4 C! c# m7 b
! b2 A/ N0 `: o3 p3.如何让类中的某些方法无法在类的外部被访问?3 \+ v5 B- f* o1 h% k7 d: I( m
$ H3 j/ z3 L; L. ]
A.把类声明为private
+ K7 A) j* M. H" x$ k. y2 ~3 XB.把方法声明为private. v4 m- T' S) U
C.无法实现6 q- e y& p5 c t4 B
D.编写合适的重载方法(overloading method)% u$ b5 m/ j$ K N; p
; X. c* L7 U% O. T* S
8 G. `; u( k, f: s, C
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?% R& ~( o+ C5 C0 f- Z
# L( v) \/ O; @6 ?A.MVC模式6 m6 k N1 j2 ^4 i. x( X
B.抽象工厂模式(Abstract factory)
' O2 i/ ^! K9 g8 i" E$ FC.单件模式(Singleton)0 M' d+ O9 e7 i+ F8 J- E/ T8 j7 V+ |
D.代理模式(Proxy)
- j! a w8 ]2 `$ g4 L$ \& v* YE.状态模式(State)9 I g+ c$ @6 @5 K( m9 ?5 h1 p; ]
6 V; L9 `' {; r3 E3 @" Z) t( j% n# L$ T: p4 H3 E7 Z. ^
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?+ s3 X. r* I( ]
3 d; d5 ?+ S" q3 {: s2 JA.1个" J4 Q: E; {$ U" B/ Y
B.2个6 G9 k! @ P- m7 E3 {
C.取决于系统资源. _2 t2 ^7 s5 U& X0 S, v/ O# j
D.3个6 f5 l! Y1 j2 [) Z# K! {
E.想要几个有几个" T! z- v0 R2 r, k# Q
% t" n' G; l O7 k9 H
, p, D! u6 M. Q3 i5 a, d4 G6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
! R2 n' u( B' e3 a5 G* tB.接口4 {! L- S1 \, h0 c* V
C.抽象方法
! o |/ k4 r2 O) YD.Private方法3 G1 z0 D( E+ v. j- E6 D( w" D
E.函数重载(function overloading)1 l, K7 R4 |/ u7 D* K5 c5 L8 e
) q) S0 r( c+ Y4 ]6 j% _
8 H' H5 x4 L2 K7 c; x' I' |0 e5 `
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
. b; w- R& T& L7 ~7 L
5 ?9 N7 K$ w2 F# eA.__construct, X; h& T0 T5 c2 E( U, b+ d
B.initialize
' ~: F9 E- J0 E% y) zC.testclass5 E! T0 \5 l5 o) J6 K5 \
D.__testclass0 q+ t0 B3 v9 I# y5 \
E.只有PHP5才支持构造函数% w5 ~1 K& y9 G$ _+ Q7 M
6 b* D: R7 `; y! P$ T! [
9 v4 h0 V! I' C+ @- Z8.一个类如何覆盖默认的序列化机制?
6 ~) T7 H8 \6 k$ ~& `3 `7 K% S2 A. S. I
A.使用__shutdown和__startup方法( z9 o! Z+ K6 e$ z+ G5 Z2 h
B.调用register_shutdown_function()函数1 S3 J) x9 M7 ?- ^2 _
C.使用__sleep()和__wakeup()方法2 G- \0 {& N$ z" M" d
D.无法覆盖默认序列化机制: Y I+ w; m5 \" M# C
E.使用ob_start()将类放入输出缓冲中/ x1 g' M `/ {2 b
/ n7 e2 ?0 ^1 f) q- ^' B' B0 K0 d; o2 m4 m/ ?/ }
9.以下哪些面向对象的概念无法在PHP4中实现?* Y' J' w$ i/ O8 e% l
, R4 @& x4 @$ s& @& ~8 W@抽象类
/ P7 t( w8 H- u9 b, J4 O@Final类2 V9 ^9 e0 d5 z( [9 f
@Public、private、protected(PPP)方法9 r4 Q, }# F( m0 o4 i1 |# D
@接口
3 D! Y! O& @! S4 e5 M) \/ w$ ~$ }4 k9 G! X! u/ s9 B- ~
A.抽象类
: x( ?# W& e& U- e" cB.PPP方法
6 ^0 C" v7 x* q8 ]1 D1 \C.PPP方法和接口& ]$ v5 t. K9 }$ y
D.以上所有都不可用
6 W' `+ w% t n, v3 |' C- s1 mE.以上所有都可用
% V F( G# Y% G6 w7 l' g4 ^) }9 o& }& [; B! C
+ q5 n9 }" w$ R* v: a& Z6 j8 _
10.如何在类的内部调用mymethod方法?
# O* u& Y9 h$ q( V1 U- X# R' Y
9 e1 {1 M- n' L" xA.$self=>mymethod();6 \3 _$ Z9 _1 S6 Q9 d- _7 t
B.$this->mymethod();
' _6 ]. t/ W4 }& I0 K# R, z: G- PC.$current->mymethod();
% J8 |9 u _) g% Y6 }D.$this::mymethod()! P" E4 t3 d3 e5 ~7 b6 t% G
E.以上都不对4 k+ F/ O8 L% ]4 C4 z& p
4 J( ?% J; w6 n3 G! u. U4 `! @
- y* X3 d+ g# O
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+ {. s. Y6 h0 U( K
B.Null
6 m& L9 Y) O. H. n/ Q) d) x" E3 oC.Empty0 W# j3 S7 B6 S; Q5 `
D.什么都没有4 |2 Q* v3 S$ B7 f0 |* w- z# O
E.一个错误7 n1 S# U) U9 m A& ~7 B" w/ ?, H
) a9 t8 G; i/ `. m) B
. w, q) ]' W* D0 J12.以下脚本输出什么?-
- <?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* f; I- K4 V: t8 o8 W
B.5
0 e) ~7 w9 P" k. m3 g* aC.24 I+ W2 r* r' q0 ` Z
D.Null
6 E9 O/ N% D8 g' a, {/ xE.什么都没有
6 W1 B ]3 B2 V4 {1 h) K( D! `( y. l1 K! L$ Q* I* F
! h+ s4 v0 I# o/ I+ @8 J; G
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. h0 a1 w6 l' q5 [, a& p3 a+ w
B.10
4 U& \) m6 F& L4 ~C.什么都没有' M$ \. q0 I: Z. _8 J6 c# _' `- E
D.构造函数将报错
+ z7 Y% `* o7 PE.510
* g' O3 u+ d1 p H2 g i0 b0 Y
3 z+ @6 x7 E" J O9 \% |; _& _! W- a( ^) j- J; u: p6 i+ x1 X4 x9 m
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函数必须返回一个值! b' `4 O+ `0 h% O$ t3 ?
B.reduce_fraction函数必须接受一个整型值
/ S$ [7 b' i, x% B9 `3 Z; cC.gcd函数有问题
+ x* n- ]; l% d3 I, BD.必须通过引用的方式传递$eight_tenths对象
% `: D# A7 f3 p1 u/ Y2 g. n" k. uE.对象的实例不能传递给方法以外的其他结构。' r8 C1 w) m; q% {
. L# B" A }8 g: k- `
, B" r: }6 V& X( ?, l% l/ e/ K# T6 D15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
2 z( I. P( t p- Y, eB.生成myclass的实例并调用mymethod方法
# {3 ]. Y! s" ?2 w) h1 J p/ u9 w$ {* OC.产生一个语法错误: @+ J7 C6 \! [8 L7 B& \0 f
D.默认myclass类最后被创建出的实例并调用mymethod()4 {7 }" y% S/ Y% P* T
E.调用名为myclass::mymethod()的函数
9 t* X8 \/ o C$ Q& T
2 D) j7 K, q# z' @1 e
1 ^; _/ f1 o {6 a/ o16.PHP中有静态类变量吗?
% k7 @& U+ y2 g1 K! M/ Z5 Q _
( M* \' B _6 `- T# }A.有" D8 C7 N y# u. Q
B.没有
& }; |# n9 M/ D% Y* v7 n. O* M' K4 Y G4 U
$ P8 ]/ ]$ k1 U# g6 F6 E' V
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.14 [. | C. P/ o5 s
B.2% @# J9 J8 K$ I
C.一个错误,因为没有定义a::$myvar+ z# P. B. J5 p
D.一个警告,因为没有定义a::$myvar
% \7 n- [& ]# ]4 y" {; wE.什么都没有5 J" u' S0 t# V" o8 |5 w
; P1 j# y+ j$ ]5 b
3 r- f# @6 n; G" p6 V18.如何即时加载一个类?! @! m+ j( ^5 u3 D% F; M" X2 J
% a z1 h. a2 n5 PA.使用__autoload魔术函数: p. t3 ?0 D9 s! Y1 |" j, Y; t, X4 A
B.把它们定义为forward类: c8 N$ v- @: p8 b: B
C.实现一个特殊的错误处理手段4 v* s3 o ?3 B; h& ^
D.不可能
1 `& X; }5 N! [E.用有条件限制的include来包含它们5 B6 n( T8 }7 a' i
9 v! Q0 {7 J! M; ^. X1 Q3 v
0 \6 ^1 H% D! ^9 I
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 x8 `2 W4 t# J( O4 L( s6 ^$ a: p% _6 z% _1 E5 {
答案:__________0 R# y! ]2 }3 o. G& I" M7 W! G; N
0 C* K; E# [6 v4 h: A1 v P
6 s. ?0 B1 Q/ ~ ~" M2 N! J20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called* `7 k5 }% H9 Y& D. v G7 A l
B.一个错误
7 S$ U9 |% a2 p V' D, j# ~C.一个警告
7 h: [1 t* I5 ?( nD.什么都没有0 @. w I# V9 U! E% q X% h
& M" ~+ }0 A+ n3 R8 @' d! N
& K) J( x% }1 B4 \8 A' N+ P' N, A: E0 O# y. Y5 b
答案速查
3 y3 i1 w. V4 b( O, @% H1.类
9 b9 M; N5 [4 X2 ?6 s2.BCD* R! B' W5 Z& g: @3 l. k% j' s
3.C
- n2 r% G" B; U$ T6 c; }6 T4.C0 t8 {7 P* F; g7 J) k( l
5.A
$ m+ d! ]) I! }6.C8 @* [3 I/ n) D$ J9 ^
7.C
$ f5 ~ S7 }- {) }7 O6 ~" W8.C. d: q$ z- g& g& q
9.D! G% I! C, V9 k
10.B
& N3 a2 u6 u, z11.D& v* h' @7 j3 s. p/ d$ B" @
12.B) K* l* i3 J" B, H
13.A4 q f8 s" @! K7 P( W( f
14.D0 d* u5 H: k4 d" l
15.A
% S5 H' M. `( t: W2 Y- ]/ }! q16.B5 Z# {! z( }$ t, x
17.A
# V1 F4 s4 j, W0 i; k18.D" A# \% P+ Z1 f4 U# |* u
19.设计模式
8 g E. [; ^6 o# y! P/ `20.D
$ o4 i7 M8 G6 W0 Z
3 I! A; _# V. V* P6 s) A9 |! I+ r! K- f( t' J2 {! P# Z
7 X t6 R9 X7 V4 [' c% f0 u
答案详解0 @, l6 U' c2 g9 T
; @# i# C* q( i# u/ N: X: d; O1.类是对象的蓝图(对象是类的实例)。
* t- [6 ~/ J. _4 S+ V1 T. e o. W7 a5 N/ B* Q* A+ Z$ ?
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
; |5 Z4 K# r( V7 `8 [0 j& w5 }4 O5 G6 }% W
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。' D: Y" g: A% n) n- d5 q
: `; p4 {5 L9 A! A: z5 V, B( i4.单件模式可以限制一个类被实例化的次数。- h! s0 f0 X/ f2 `6 U2 s
3 y& u0 F% d& A2 p
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
7 M% q" Y+ F, U
. {* J1 o; [6 w4 e3 H6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。" i7 [% l7 p" c0 b
+ |" t h" c7 w( c% b9 e7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
9 }; ^' J2 J7 a: `* v q: u" K) ?5 }. [: c0 S/ E8 P' F" G
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。: [9 B7 Z( O) t1 ~3 x* i# A) K$ f
) `/ E, g+ r1 Y2 y+ [5 ^9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
6 v, _+ H' W2 Y, s$ ?; [
, n+ a6 b- h6 ?' H) @10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。6 Q v$ @6 ] a: D. q' {% _5 i
8 }8 K% X7 |3 x; A$ l& x$ {
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。# t/ ]. V. A T: n0 s0 K7 T# g
$ X6 M! [+ L% H! g- V12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
4 X) z" K1 g! b! Z9 T
+ U8 G- {" o# D4 |5 w/ X13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
0 d7 \6 ]) Z9 _0 I9 N$ K, D: h5 T
- _, d" h' Y" s% T t2 q; B$ Q( U14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
4 Z5 Y4 c9 M; G' Y回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:7 B+ ?2 U+ p1 N
function reduce_fraction(&$fraction)
8 n' k: a z4 J$ t# i6 Z2 e答案是D。
! t$ C9 p O* U& K8 O7 M7 ?/ G
$ ^4 f6 G# {# T4 h) Y2 K15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
! U8 w: J* ~/ c. e- y4 l, F4 U- g, `: J7 x
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。" \! s; [9 d( v# E2 A# M: c7 W8 l
% H. Y. H: E- K1 g5 H) E
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。/ Q! A h6 [+ R
$ B$ }0 d1 y# f+ L' q h f( {( B
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。% I" _# f, Z& t6 V/ I5 g
- k! B6 P( W3 @- C. ~0 W+ x19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。" N9 k$ x/ n$ }% A: g
7 s7 L- F* O% J- f( n V4 u" a* Q
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|