  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
9 Q$ Q5 q/ z: p7 ePHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。* B% ]# T$ c$ m
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
6 l5 i' m( c1 Z: U( J: V
' ?# e4 h' s% B4 ^/ l问题5 i% \$ I1 S k7 D( ^' r! R$ v
5 s+ M7 j0 b4 T
1.对象的蓝图是什么? I- D% e( K& R
: [" Q1 ~; R4 H1 A% X答案:____________0 I; U3 J! F' T8 N; n6 l6 E# c7 G4 h
* g, ~* s4 x0 ?% X
. h; i8 z4 |" M) k2.以下代码执行后,数组$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+ m; c" {" p2 ^2 l5 Z, w
B.b
- P6 }6 C3 _# W) u4 {1 jC.a( }4 ?& O! t" H' z: ~# i
D.d! K6 R) t' ^$ q; c' R9 }- i
E.e1 t2 y G+ z3 q7 ], W! p# `4 p
( F% T4 L" u1 b3 X [1 K
7 Z& }: T9 g \8 C
3.如何让类中的某些方法无法在类的外部被访问?! B1 A" K3 x1 Y& V( q( |: f2 N
: O. _- \$ _9 x- M- t
A.把类声明为private
/ }6 y' |+ @' G+ c5 H/ sB.把方法声明为private
- D- ?7 i! ?$ X; B# ]C.无法实现
q2 R; V* [$ \4 E- vD.编写合适的重载方法(overloading method)8 }: e, B& x% G; ]
/ e. g }# x# V3 s. q3 e- q2 L
5 h" A& E9 {) u8 A# V' r- Q5 M4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
x/ B- y; G5 d1 Z$ J* ~, N
0 p5 [4 ~4 C4 H2 _A.MVC模式. x2 ]: p) z2 V) D& w
B.抽象工厂模式(Abstract factory)
3 o) {: W( N! |! ?) c/ ^C.单件模式(Singleton)
. `" b7 w: F" Q+ s5 mD.代理模式(Proxy)
' g+ ^% B, m0 J0 o! b- y" G3 K3 ?9 P/ hE.状态模式(State)
/ I* M& v2 I" e) D# R5 [ Q% Z: }
: r+ @- \# k8 a9 E) F3 P2 o n0 z* ?
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?% F* l8 F( E3 X) }6 S5 b C& ?
2 W0 E/ W1 O6 q4 M% n2 p8 J
A.1个* r s% p; C- e. o
B.2个& h& Q! E, S8 {8 b0 q
C.取决于系统资源
3 R# z- a, G0 K: Y. JD.3个
5 j7 s- Q/ K1 j; A9 eE.想要几个有几个
; J; Y$ _: ^5 o; [1 b |
$ U/ L4 w# W% u- A h2 J1 U9 z) C. p- w+ W( x( S6 ]
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承% x# U6 Y* V9 W1 ~$ N
B.接口
1 _0 q: L7 U) [. J1 z" M: E4 uC.抽象方法
* [7 Z1 H. x6 e1 sD.Private方法
! E: x; }. {( o5 | A. GE.函数重载(function overloading)
. u5 V- R3 M' o. w9 _, R
) d: L! w+ l ?) s0 E/ p2 D; O+ g2 [* l/ x
7.假设定义了一个testclass类,它的构造函数的函数名是什么?) W8 I2 G5 _4 ?! A# M! d0 W0 k( S$ R. Q
4 q1 T+ ]7 k' V$ T1 }% K: Z& J1 T- VA.__construct
8 S Q% o! ~7 a1 [$ BB.initialize
& {. M* j" L/ }' ]1 | BC.testclass) a: N) S: D% h4 e/ p3 C# I1 ?
D.__testclass
# }4 N& r# c5 J/ u) h: d$ K5 QE.只有PHP5才支持构造函数7 A2 ]* H' E& V4 x' z( Q' n8 O& Q' _
) q1 V9 f' d9 K v! m
1 Z- \3 p n, x" V: d8.一个类如何覆盖默认的序列化机制?
, ] h' L; C. ^
9 N- }/ A0 ^" r$ bA.使用__shutdown和__startup方法
3 d- H' G$ R, s+ M$ |$ Z4 X h2 _B.调用register_shutdown_function()函数
( y( X) r" c8 R8 SC.使用__sleep()和__wakeup()方法 P7 i/ d( F: Z+ R) b# o! Y
D.无法覆盖默认序列化机制1 S$ d8 ]6 ~9 F! C9 v
E.使用ob_start()将类放入输出缓冲中
$ Q9 z0 ~9 W2 X2 v# m9 Z% p. A( i7 Q3 N# j3 C* R j
$ u- ~. @' B: {- f* q7 a
9.以下哪些面向对象的概念无法在PHP4中实现?
2 J0 n& h6 p5 N7 C6 Q! ^2 f2 p% Y# p9 m& s! {' Z2 m
@抽象类9 I; g! T- u4 d# J8 C* d/ Z
@Final类
/ u+ W1 A, N9 s3 ?% [@Public、private、protected(PPP)方法" g& ]* j& M& \' a
@接口
7 _2 a9 Y. J; o
! O5 O' {2 R/ OA.抽象类( T& V- e4 ^* n! f* B D7 D
B.PPP方法
6 p+ H8 v0 L- sC.PPP方法和接口% c7 S( p, H, |( m2 Y
D.以上所有都不可用/ @2 p# j8 j+ [. k; Q F% n( n6 d
E.以上所有都可用# L( f) \! _# f! f1 r5 J
0 t" k- g y% ~; f. r h1 b, w7 w# x
) h/ V# J* G5 v7 P# v3 C10.如何在类的内部调用mymethod方法?
+ w7 Z; d2 R: K9 Q. y+ ]7 `. {6 k) o5 x/ ?9 v5 m
A.$self=>mymethod();
/ F. C9 D2 c7 g+ h0 [B.$this->mymethod();
2 e8 g$ a- _, R: @; o7 rC.$current->mymethod();5 B" P5 T/ u& ?/ H
D.$this::mymethod()6 ]! r- r+ i" t8 G7 R9 M k0 M
E.以上都不对, | q- w- _; F5 p
# d9 t5 C6 C" L4 W' z9 W6 v8 K) F$ J& X" r% K
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.107 P) r! t2 X8 {4 w2 r$ V% [
B.Null; ^& p8 ~8 t1 ]; S
C.Empty
, k1 L& A+ B& k* s6 HD.什么都没有
' E+ o2 @. y0 VE.一个错误
3 O; Z) f0 h$ ~! `. J1 R
* a9 O1 O6 o2 w3 Q, Y1 ^+ h4 m4 h0 X/ K- ^0 p
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
3 g9 W' t4 j8 G& dB.55 c9 e+ a2 l/ N5 l+ I% G0 j
C.2
8 V" ?' ]# ]! y. H' R/ n$ S3 A) mD.Null
" c& V! Q5 v3 o8 \* [" [6 _E.什么都没有
! h5 R" W9 z+ Q8 `; Z+ r4 p5 n0 G2 e$ U
9 j! g# [% d( h R7 ]: k
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 x% g; D* d- E' H! R# J
B.10$ @6 Y2 M4 V4 o6 ]
C.什么都没有+ N7 P& d1 j: m9 T3 W
D.构造函数将报错+ n. v3 F: s4 d% {2 \0 N, F9 {
E.510: B1 z2 b1 V' q1 Y
j0 L) Y) f8 q |6 O: D1 P5 }
- h/ \, \' N) P- l- L7 h1 Z
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函数必须返回一个值
7 l' H: |+ \/ o& G! a/ ]* uB.reduce_fraction函数必须接受一个整型值
& w; F5 _9 t* U, `2 H* RC.gcd函数有问题
4 f. i- K* O/ f# r$ T3 D5 mD.必须通过引用的方式传递$eight_tenths对象
4 ^. Z$ [% j5 H7 v& ] F0 [6 S. SE.对象的实例不能传递给方法以外的其他结构。2 R7 ^# o' {3 u
' ?3 G* x, K2 f
$ u" _+ c; m3 r& c* [$ C% L- @: z15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
" U$ i; u; n' U7 `B.生成myclass的实例并调用mymethod方法; o" I ~# P- E6 D @! J
C.产生一个语法错误
2 ]+ m; f7 \( }D.默认myclass类最后被创建出的实例并调用mymethod()
8 V' N/ e# u p) L% XE.调用名为myclass::mymethod()的函数
8 K! T2 F5 s7 e
$ w) Y! e7 G' F6 B7 U9 |: J* A
16.PHP中有静态类变量吗?
+ I3 {2 x8 k, b
; S' C) Z/ n0 o8 g6 d/ `. F" lA.有2 h! D0 y# I7 d/ x _/ u1 u
B.没有
" a/ I o3 u5 K! F8 L7 {, l( {
+ e6 U! x" A8 C* W3 i
* K6 D& h/ Z: C, Q1 P7 @+ B% 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" [+ k7 t( h. K" C! k
B.26 k; H2 E6 s$ U+ o3 L8 N' b0 H2 D8 e
C.一个错误,因为没有定义a::$myvar
2 D, e. ~' Y8 `1 z RD.一个警告,因为没有定义a::$myvar; k5 r6 r' o0 `, O- ^: b
E.什么都没有
& }* Y. C! o5 U
7 u/ w( N- g7 P9 E) M0 g# J0 a3 R4 v7 x, L6 z
18.如何即时加载一个类?, i. F/ k" c) m! j
( j$ R) u# y0 z* w! AA.使用__autoload魔术函数5 S& m* _1 h3 r5 n2 a# V
B.把它们定义为forward类2 G2 B; N/ q7 k# F2 M6 `
C.实现一个特殊的错误处理手段$ o8 L( [( f7 B9 A% {! ~6 M, d: M
D.不可能- T. `" z3 m8 J* U- s T
E.用有条件限制的include来包含它们: n+ j# u1 z" |+ S7 k
" }) _0 I1 T/ [- g6 O: N# v6 U
: j. |! S I( t/ F6 P- W* J* f4 f% w19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?6 r' ]; ?. H/ L2 o" H
3 Z: i; c# r: e9 K4 N 答案:__________6 Z9 p$ ^/ ]8 i% r+ S
2 O+ w6 k, z, }1 Z# I$ q" F! G: ~& t9 v% [, M! d G" E% S% f
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
2 ]. a7 r s- d8 E2 w! ^B.一个错误
/ k b: u! |+ yC.一个警告
- E% g- P' X' d Z' Z, GD.什么都没有
8 |+ _8 D: |. k% y, R' {2 w5 |! i9 J6 W# x
; N$ B0 }# n" s/ l7 F% {# m5 G; _; L, e$ T. i. n
答案速查: ?$ i/ w3 X+ b; k
1.类6 N8 h, k$ a$ e0 Z( X) r: u# p4 Z
2.BCD
2 D0 ]$ d" ~9 h, _. y1 X3.C- }# L: x, U6 }5 r( e
4.C
* [. t; g8 q y9 D( o) ~5.A9 J+ |; L7 K( K! s$ [3 d6 ]) r
6.C4 C; [ |4 `4 n4 u: q) @
7.C
0 d9 ^/ o( X/ Y( T% n6 r8.C
' y& Y. P+ i/ G* [; X/ z9.D
: ^0 t1 [) I" c! Z10.B' p/ \/ H2 K0 J: |% ]& d4 b
11.D" k/ H" H9 Z$ f6 o) O
12.B
1 B9 [' W/ ~3 L3 U, o13.A2 x# i- N) o V* z4 ]) d5 X. @. \. w
14.D
7 s& h7 j" U5 t; t% x) s15.A; `) k. ~* r1 I8 U; M U! ^+ g0 f
16.B
" x, U% C, d: |- t! P! G/ I17.A8 e1 h# D" i" n
18.D
* G3 ]2 I5 _. f% Z$ y+ u1 e19.设计模式
/ Y9 ?" J& ~! u3 a& N, h+ I6 _) l20.D2 R% a' O) L: t/ p2 p. x
7 W6 `# \8 y$ ~0 k+ `; a# b4 D
$ ~: G$ x0 o! r
H e/ U* A9 l1 o+ @答案详解
- A# A1 d( U, l) y5 h, b6 E
/ ^7 z' D' F/ K( U0 x) f8 V1.类是对象的蓝图(对象是类的实例)。; |0 Q- N. Y$ B. b1 p+ `7 E3 u: Z
) J$ e# Z5 i& W' x
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! k0 h8 h1 {! n
: Q, K' t+ H# q( \3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
6 _4 S7 @+ M( F; c$ ^- `- c: F4 Z% `7 c# z
4.单件模式可以限制一个类被实例化的次数。
4 t) V1 `8 P. C6 E9 w. z8 J8 K1 G+ `9 u; `, a
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
) C; a* ]0 F E6 o) a$ e( r! E& D, m, W
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& ~; d% S5 |9 U' v5 b' C& _8 |, u8 d/ y5 K4 E( T# U7 I$ K( u
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。1 C( I3 A! J t
8 H& c/ |1 f) t8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
- H4 a- g" B' _4 ~ X! g- }, l% A; c( j
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
7 E, R5 ]& U( A% M) d2 ^5 \: m# _; ]/ _9 ?. `+ M, b
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。: x3 r9 X! s# c; q
6 M, O' Q% h F1 q. F
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。7 k2 r; \* V9 r" G( P6 F
( b5 E3 }% P$ F6 i. a# F- O12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
* y% a4 ^+ H4 j/ ?& ^% _: F: R* C; P- a6 e* q8 r {) A+ B
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
4 l j/ K5 n8 N) T3 F
& d; v% l s. h! A! ^! }14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。1 @1 R; h0 \( ]* ~) C
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:$ K( P2 `, ]$ O
function reduce_fraction(&$fraction)5 H6 }( j+ U% [, r2 M7 o/ y+ g
答案是D。
# B7 v( L) N+ G, m& C; ]
' ^; M& d5 t. y/ Z15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
, Z' i" W! p& l/ I0 ]: G3 Y2 Z3 ^7 z( J+ K- T2 G' b$ i1 y1 l
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
) r7 ~$ O8 S" n+ s
, ^* \ {4 T" x+ x$ A, C. B, ?17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
" _' A/ P' Q' O* P. [7 W- n# Q' ?1 m; y: C
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
+ m* \" M. O; R! W1 Q8 a
( `. `) |: D0 s7 Q9 p& z- N# a0 U2 ?19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
* x, u% c2 c5 w7 s$ S
$ r, F* N& C! Y, y' B/ z. H5 r20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|