|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。; r/ ~7 |; c, Q4 Q( A, |. F
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。& i) i1 W* ?1 m$ c e9 ^- A
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。7 ?/ Q- a# J& i R4 k& O
) y& @4 B/ ~+ z+ D J8 f( k问题& ?( t9 i6 r8 J2 y1 j* i
6 t" m" c6 [2 V X* s1.对象的蓝图是什么?+ k, Q5 S! ^- F P/ N: l6 f/ V
7 R, q# R5 G3 G1 l: \
答案:____________# M9 J' \9 M' [
1 a$ n0 X0 _* i$ W- O
1 q8 d' `+ A- s1 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
3 ^2 P8 k% m5 p/ [# |! UB.b
- t& p( o% S" f4 H$ Z* c4 BC.a6 O, d |6 ?: ?: x0 S* o) U' {
D.d$ _+ `# G% O/ r2 B# m# X5 P
E.e% H, S( M+ ?4 F7 l
4 ^& L, q/ S9 h. a# x2 A) v8 E
@2 N2 @3 m7 v* A3.如何让类中的某些方法无法在类的外部被访问?! p2 G' `5 w- r6 e5 _( F: s
3 i/ {, g! V4 N& L8 L8 x8 X
A.把类声明为private
: } F8 E8 ?/ S5 S) F8 [9 AB.把方法声明为private4 y8 M0 }& {: K4 C& {' R$ d
C.无法实现1 k' z- O8 R( n
D.编写合适的重载方法(overloading method)
U, i. M" l2 r" S' T: w8 X, @
+ r. x: D: |9 O+ }7 V2 U! t% A8 |5 x+ k/ B
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?7 t1 m6 P0 r2 f3 H- H" d
) Q5 f9 I' R3 L& K5 M {
A.MVC模式
; X7 T8 ^2 m( R& K/ \B.抽象工厂模式(Abstract factory)
, j* R4 `7 N8 c9 H! M" t d$ H" T+ hC.单件模式(Singleton)
/ P. X. @* n# a& `7 T$ g2 }D.代理模式(Proxy)
' W1 Y4 z, r6 ?; eE.状态模式(State)" c% c Z- J1 I: t5 d8 Y
( r4 ?7 g" n+ I$ c7 }! p/ M+ Q( o" ?
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
8 s- A" ~* A; g+ B: @. O3 Z( k9 w
/ p7 y) n% p1 d; G0 A0 }& eA.1个
4 R0 ?2 l1 Q7 D8 GB.2个
, y- G! Q! v4 N& n0 SC.取决于系统资源
/ n t0 ?/ W2 F. S/ M+ hD.3个2 Q8 _; r# e/ z- R3 q
E.想要几个有几个& s' ? X" v2 Z3 G. p8 u
% W5 m; e5 g" E7 I8 X$ J$ h) d' T4 B% ]3 R
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
% ~3 d5 U$ s U9 dB.接口
: d8 m" @3 k% T9 h; S {9 WC.抽象方法/ _ U, } q! E$ _, o% B* O
D.Private方法; n, R* S' J q8 Q% w. {5 a+ l) x
E.函数重载(function overloading)
2 {9 W6 j4 s( f7 g8 j4 ]
0 ^4 B% ^" \" G& v
. K \+ u! J! K3 N" v7.假设定义了一个testclass类,它的构造函数的函数名是什么?
- |2 k' ]4 w( t( m4 c! D" P; I z _$ C% U4 k; P! I* s
A.__construct
4 h+ ]" y* z8 n- w1 J5 k" ^ w! ~0 k6 V; W/ PB.initialize0 s; {/ ~* o( A0 A: t5 y* I
C.testclass# ^7 \) r+ @. G2 s# C) k
D.__testclass
2 }+ }+ H7 l) ?" WE.只有PHP5才支持构造函数
! L% R7 B* d2 C2 `
2 F7 o1 g% P8 _, k8 N' C1 {" O% b7 U) R& ^
8.一个类如何覆盖默认的序列化机制?. E+ |6 w5 i& x3 T/ g: @/ s
2 b* w; L7 Q5 @3 I2 |A.使用__shutdown和__startup方法/ v/ A$ i4 R- y
B.调用register_shutdown_function()函数6 m9 \ j/ }0 l" ^% A/ Z) Y. i
C.使用__sleep()和__wakeup()方法+ z- i2 ` ^$ F
D.无法覆盖默认序列化机制
1 f3 L3 G5 i5 R! M/ |* }* B: EE.使用ob_start()将类放入输出缓冲中
8 m. {& q j% A& ~/ K9 \" O
: R$ k3 k/ v2 ~" Z @8 B; }
p' _ z* C9 P9.以下哪些面向对象的概念无法在PHP4中实现?* h& t5 m8 h4 j9 l* Q
8 T$ B" ?- N& F7 m
@抽象类
+ Y$ ?. _; A* ~# C: z7 N@Final类: w/ q6 H% p3 E. I
@Public、private、protected(PPP)方法
' h& }9 g* s/ q" r' U- b$ V2 m@接口+ E& ]$ p, f: l+ h
. _, U: [; L- J$ \4 ]! yA.抽象类; [/ E! b: ~" B. q
B.PPP方法8 T* W1 j( m7 x3 x3 X
C.PPP方法和接口
, F, d, [# |$ S; x& mD.以上所有都不可用
; `) c/ ?) r/ ^# d) JE.以上所有都可用& d* V: t1 b$ Z1 \+ g
7 u' f/ E/ Y/ I8 O6 ]
5 \& D1 f# I9 |; m, u; t9 N+ u10.如何在类的内部调用mymethod方法?3 R2 \+ P& {( H$ s9 a- F
8 a# O- l+ i" X. W eA.$self=>mymethod();% i, D2 S4 {% ~! ?0 ]2 n/ Q
B.$this->mymethod();
" z' T2 n7 A/ j9 M+ e* y; {: mC.$current->mymethod();: V& J, p2 }1 p b9 d
D.$this::mymethod()
5 Q8 z1 V2 M- J$ |E.以上都不对5 o" `: T8 S5 H1 X5 S
6 K a8 B; l6 m: w$ e( |
: B, j n+ ^5 H2 B( Y* |; U# `# s' D11.以下脚本输出什么?-
- <?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.103 V6 ?' j) z$ c
B.Null
& `# M( W0 [# x8 wC.Empty, r$ X/ @/ V l0 h2 k4 ?
D.什么都没有
% z/ R$ B, U( ]1 W" ~6 e( Q3 JE.一个错误/ ?8 f: f6 T! n6 X" ^' ^" |, c8 l% i
+ z' ` w, G+ A9 P3 h0 W9 i+ {
) O& F/ H* M' m+ H1 a12.以下脚本输出什么?-
- <?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! q1 ^" G; \ l7 [& s! n
B.5
- K3 Y. k0 b* o" `C.26 S0 j/ r# l2 u9 w# P
D.Null
% U* U; |; d+ h3 kE.什么都没有. A- ?* ]2 |; s, ^
4 X3 o3 g" Z9 c9 n e4 i
2 a. g2 _/ n4 G4 Q7 J13.以下脚本输出什么?-
- <?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# P, l9 G% b. A/ n
B.10
0 z) Q# K6 T' O$ E/ [C.什么都没有
7 n2 `; Q% [' F- M- w9 T' C' f% ?( rD.构造函数将报错
9 f! \8 C5 G5 o+ U0 dE.510
2 u# ^' E; q% _3 {; p1 h" N1 ^% _4 W; l7 ]3 z: S1 _$ D
- m+ ?& ^% R3 c- v$ A1 }9 |8 Z14.考虑如下一段代码,执行时,$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函数必须返回一个值
- q" K* ^" G) [7 X3 N( G& HB.reduce_fraction函数必须接受一个整型值
5 E( e+ y# Y. q* Y+ n( i0 \C.gcd函数有问题
1 c" K+ u8 W Q& Y. @9 wD.必须通过引用的方式传递$eight_tenths对象
& l% {) p; }! u# A5 H$ pE.对象的实例不能传递给方法以外的其他结构。
) n5 H4 t/ E2 W1 M2 i7 Q
6 {! ?) N- q! W+ Y/ O4 _7 d2 x# O) u& k; F7 y v" {8 ^
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
& y& o2 |* c& l( M, NB.生成myclass的实例并调用mymethod方法) }3 [: n$ g+ J% U9 J& [: I c$ O
C.产生一个语法错误
0 w- ]. c/ n% B, Z: Y2 g! jD.默认myclass类最后被创建出的实例并调用mymethod()
: g, c1 A6 w) D; {2 f/ r6 ?" e! iE.调用名为myclass::mymethod()的函数" a; y1 C6 s* S2 w" K* D
4 h3 T6 q' s- I' ^ n9 L/ Y
$ e/ Q) o1 K6 y1 {- g4 y; T
16.PHP中有静态类变量吗?
2 n; }0 C4 Q5 V- l# m' r* r5 X6 u8 u* z' F0 @/ o
A.有/ o d! L. H7 ?
B.没有9 z: I. J$ E0 r2 N+ r2 L
* k, g& |/ t1 g9 V
+ L; N4 J0 E- i; M17.以下脚本输出什么?-
- <?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.12 i. }& S1 ~* S: t! Q& z9 O
B.2% J( p$ B4 r4 j% ? i( K
C.一个错误,因为没有定义a::$myvar% N0 }* T) j8 o8 S% M
D.一个警告,因为没有定义a::$myvar+ e0 l" }6 ]9 |# {; ]+ O+ R& \9 x
E.什么都没有
+ N$ I/ f. y1 W$ L5 s. ^+ ^5 S6 a4 X/ ~8 d: @
* F, {& U, v! r" N# _18.如何即时加载一个类?
+ D3 t' A8 v( ]( p c* U3 a1 ^7 C- P7 c, g3 p: p+ D* [* u
A.使用__autoload魔术函数% `& q! a) T% s2 Z
B.把它们定义为forward类
4 r& A: P f5 j% QC.实现一个特殊的错误处理手段; g, d. v5 Z) Z+ F! ~
D.不可能
* x/ d4 ]! `& p. x1 B, K c/ dE.用有条件限制的include来包含它们! f; f" U" w7 m0 E; D: T8 r
1 f* V+ P0 \1 ]- r' L6 O+ B
9 ^8 Y, ]* p. A/ H2 T* R8 s6 C19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
- J& N+ a' E6 J% I( O: y! _; I
. j/ p) Q+ a% M3 @9 E 答案:__________" [/ H4 [3 S" C$ s' @+ z j) P+ e
5 H, x9 p; ^2 f! r+ X8 ^
% ^% G- t4 Z1 ?9 k6 Y$ D) Y20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
' k4 Y$ g" b3 h, F1 e5 }" {1 xB.一个错误
5 W5 z( ]" F' i) ]C.一个警告5 Y2 e. o6 w, v, L( _
D.什么都没有
0 M& q( \) z0 @5 p+ E9 [3 p
5 E" C/ H. N! D! [5 V/ B. Z2 N0 S! M& t* ]
{; G0 z: D1 H) {9 P
答案速查1 L6 _4 C' Z: @5 S9 ~$ H2 e
1.类 ^) M3 R! w$ a0 ~
2.BCD2 p2 G) @4 B( N$ D' e. e& _& j' m' D
3.C
: h" e9 ?! _) `2 a4.C
% D* V4 h. u: J& q- ~" ^5.A
$ R* S2 ~! g h0 ?: o" U8 z6.C
) V( R4 H, _8 C& X7 g7.C7 \+ J) b ~" M* O
8.C4 P( m4 p7 p! |0 A0 e* e: \% O
9.D1 N) e# S7 {( Z! V; E* W& g5 r+ U& h
10.B; b; p) L9 m6 l+ r
11.D
2 [3 r/ v- i w& E12.B
) N) Z/ `/ D$ \3 f13.A
3 a+ z# A8 z3 v/ ^14.D
$ u1 `* P; `: ^$ T0 ?15.A( |. f) d: ]3 a) k
16.B* _) V9 ?+ ?9 @& a( c) a
17.A
8 k* c. p1 m4 Y* f( @) j1 ~' a- N18.D5 k2 p) N( N- e# H4 d" Y5 a% l |
19.设计模式7 {0 ~8 p( ~. q
20.D
8 ?7 J' {: [* S) n. V
8 m( d' N8 e, \( ` p
. H" j7 j- g2 G, `; ~! C& R! P: W# P$ L. W. f# _
答案详解) d9 X6 R0 m! w5 u+ }
! w: V: ~3 ~' D' I5 M4 d
1.类是对象的蓝图(对象是类的实例)。
7 |9 w- P: s @6 v) z& J
* r8 z; g: P. ^% Y" z& P! l/ Y) f2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! c2 [7 `# v2 @. u
6 U1 q* X/ ~1 S6 r5 u6 ]/ _- Y3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
' o) |! y" M7 M, w
" M. O/ ?6 I9 s" {5 \4.单件模式可以限制一个类被实例化的次数。
8 y$ e1 _+ G% F$ X
2 s7 ?( L& e4 n1 F! e5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。3 T' z3 Y8 `7 n
: ]. E0 l3 D0 _- O
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
7 _7 L6 o: [) I+ l2 n
1 ?. ^" x: m) M4 c( h/ n2 ~7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。. B7 |! k& _$ l/ s) L8 J! o
8 V% _5 { i+ U- d1 [4 v+ J
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。# H K$ s$ m& {/ n
2 v4 ^- c7 T& H3 e: R9.PHP4中没有题目选项里所列的任何一个概念。答案是D。: N2 |: Q O$ O7 Z8 a! H
. n7 [2 J2 O# }7 |7 g" ~; T1 M
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
8 p. m4 j, }1 x: ~" X' S) [
$ y/ W2 p5 D: E) B# w& [) N11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。5 y! T9 I! M/ E/ G0 S
K/ Z$ ^, n2 O5 h$ L2 V12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
1 ]; D' f: Y3 w0 I$ }) |: @" K) z$ ^" o% t
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
& J$ Y; m0 a; w
* B3 C9 U% K) D z' Q14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: E/ R5 _! C* U- X. v, e5 u, @
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
6 D2 b: l2 g, w" E% ? function reduce_fraction(&$fraction)
* \$ w- s! \4 ~8 i2 T答案是D。
6 c ?% y7 X( @, w# t; F$ d/ A, j$ B; G' S! f( B
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
7 A1 l |7 f0 h4 g- [
8 Z7 g3 S+ c& V- ?0 x! p16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
0 }) Y+ S- h2 @4 ]" f
; c$ i* C' y5 m/ d3 a5 O17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
$ X4 z) s J# x' U u# V" f5 A+ D+ E3 v7 t. o! }- q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。; r; S/ a* Y: t: I1 f! M
9 }6 V, D% @" s" l
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。2 \. B/ D# M; f- G5 G6 t: `" r
/ W$ a6 q+ k$ I, ^7 O20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|