  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
, n# e1 J/ l/ d/ fPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
2 R. A6 l K. P" ?本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
, \. A/ S, E( b+ U9 |1 u. N
2 g, A6 V$ |9 @9 h! \& S" `# b! a' |+ V问题
5 \: U( n+ j' e" i2 |" m7 d S2 V# }. ]2 N4 g
1.对象的蓝图是什么?
" N$ t5 G* L& }& ^% j% u: d4 [" L9 Z
答案:____________
- D. i. e) [$ E. E6 Y8 c" b: I9 d9 K- M. \ }
4 B6 L% @! {0 D2.以下代码执行后,数组$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
9 c- T% o4 \ t! I* e( Z, ZB.b$ z$ E" B) j# G+ f
C.a
5 {+ A3 `& J$ R# `: z6 OD.d
0 r8 T; b9 D8 ]E.e
n: t! e* {* X# `8 m% c: }+ Q' L+ k8 n6 d# q" v }! X! c% H/ ~
+ A( E v: [0 ^' p/ d# M1 \3.如何让类中的某些方法无法在类的外部被访问?
" Z; {% j$ z4 [! R# @9 I O
$ T& l3 D. M/ g, W( i/ ?/ lA.把类声明为private
$ Q* G7 l0 f9 R* I2 I1 B; BB.把方法声明为private; s2 q- m3 M) q5 o- r4 t! M5 m) q
C.无法实现
% |/ g W G, P. a: ]& m1 C bD.编写合适的重载方法(overloading method)
6 S+ {7 O1 [) |' c6 D1 c, g& k7 C, d* `
& v8 p1 p y& m- f( a7 j9 n5 Q4.哪种OOP设计模式能让类在整个脚本里只实例化一次?9 z/ K; [0 k. j" A# @ j
" G0 \; f+ L" v
A.MVC模式' h- ]% C0 U! V# }; N: [
B.抽象工厂模式(Abstract factory)' L/ Q4 P6 J( Q8 A. S" t! x
C.单件模式(Singleton) t$ M, U2 D4 B4 g; u: q" E4 u
D.代理模式(Proxy)
/ m) }4 T2 ?3 k+ l5 C1 A) UE.状态模式(State)
: g/ w" n" E, r- X% f
" ?4 f9 h) P. ~' l$ E4 f! [/ f: V% v5 j& w8 u
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?% E) K( ~# G) y: c& [. ~7 d
% q# y* Q& }) z! U1 SA.1个
9 ?; ^$ ?6 r" D# gB.2个. \2 ~+ R+ W: M0 j5 N
C.取决于系统资源
) f" N4 O* X( Q& D' ND.3个+ A6 i& z2 a( m1 ~" @
E.想要几个有几个
/ y6 c# q. B/ L, h m9 \: ~& A1 p+ S! c8 Z
: I1 Q* I3 {0 _2 I
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承4 T, g6 C9 A: f$ R6 H
B.接口/ t) m5 ? }% Q0 j5 A2 o
C.抽象方法
# i- a& R5 h0 j' J- G; @D.Private方法
# C+ `% G5 Z6 ]* X$ UE.函数重载(function overloading)
0 H6 c: y) N9 E6 w9 j- s
5 R$ r& D/ u: g, L: {( o) Y2 Z. ]. ?% f, B. W+ `9 ~3 ~
7.假设定义了一个testclass类,它的构造函数的函数名是什么?: p& B" s+ M; g( w, F8 y( ~
: e: q- q8 [1 t" U" Z
A.__construct; q7 G& h4 a' [5 Y
B.initialize: P7 C9 k* O2 ^
C.testclass8 I! ?0 N/ ^0 I7 z* x% T
D.__testclass( _# L7 T* L# ]5 g9 D
E.只有PHP5才支持构造函数
5 Q A) J+ K* s' ~, y
# K" o$ ?5 j; S' i7 I2 O$ j
( N U) s! ?: ]% h* M. I7 n* J" K, j8.一个类如何覆盖默认的序列化机制?
C# p; o6 @' x2 T) h+ r% V
& C1 h0 X9 G* I" U% L/ UA.使用__shutdown和__startup方法
% }5 c$ C K8 K2 ~7 f3 |B.调用register_shutdown_function()函数 y O2 W$ | t3 ^
C.使用__sleep()和__wakeup()方法; i$ k* o; e/ `
D.无法覆盖默认序列化机制3 I& h' p! e. s$ y: e4 d% E7 h3 x
E.使用ob_start()将类放入输出缓冲中0 E' r; U! D4 w) I
% p5 ~0 p5 [ E3 x2 w* }; a
Q. T/ ^9 s: V9 B9.以下哪些面向对象的概念无法在PHP4中实现?
, k8 n$ x- [' h
+ |; L0 Y3 I" T" V@抽象类" {% X1 n$ o0 i5 R4 `% `* T; e( K) b
@Final类6 j: g6 u8 K J+ c4 e
@Public、private、protected(PPP)方法
! a; e" L" G5 i0 c@接口6 f8 L- ^3 q& y/ P% P- k
0 H" o3 ?3 `" _! X! G( B9 i1 a K+ \
A.抽象类
G N% c' P& r! U2 {B.PPP方法
+ V, Z6 i0 T1 R5 J! SC.PPP方法和接口0 b b8 U1 _ {/ ~% \ z
D.以上所有都不可用
( ^8 z! y& W) }8 D3 u" \3 {E.以上所有都可用% d6 `! _: c$ ^4 O& [2 E
9 o* @* W/ i+ ]
' l9 M' y, U5 e% `" G/ v2 ]10.如何在类的内部调用mymethod方法?
- g. A% ~8 ]& n- M2 k& ^' f- {
/ g8 e- u" B0 I* cA.$self=>mymethod();
; O- i, r. }+ R9 e8 xB.$this->mymethod();
- k5 l, D. a' v, g" z4 n3 aC.$current->mymethod();4 W1 k4 t8 r: Z ]. D. S# R, l
D.$this::mymethod()! h# m- [$ Q1 H" H2 b- V
E.以上都不对
" v1 ^6 r0 }) B7 a; g0 ^6 d5 d
6 D$ x9 ^1 k. q% G9 ?; J0 u1 ^+ m8 C. M
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
7 E# l- h m: L$ j$ u- G6 ZB.Null
( t( K9 A- s: k7 G! x/ L9 q! h6 _, OC.Empty
% x* o' n+ m7 ?D.什么都没有
0 S; J* d5 ^9 X: f* kE.一个错误
7 K4 }5 x5 ^: n9 N: ]
2 N- V3 J. \# T* w, z7 o' l" ^
4 B z$ u" A+ |7 d4 b; z12.以下脚本输出什么?-
- <?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
. { h; I0 a3 a4 F# eB.5$ v; I' u4 |1 B$ T+ F8 | z5 |
C.2# X* ^* c2 u2 U ]* u/ f# i7 d1 H
D.Null# q' [" q$ w' L0 s! O$ w
E.什么都没有- a/ F1 r8 y$ `- r L: u/ e
0 R# B- @7 y8 m: X& R; z" k# O; @% y( Z0 l. G F# y: y& T5 p
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.57 ~( [& N5 q$ Q2 k7 e
B.100 H8 }5 u3 A6 d/ u" ]/ s
C.什么都没有
" b1 L) B* i! ]* R0 }2 }5 xD.构造函数将报错
7 X0 d9 z; j, \% \% w5 wE.510
( z @' c+ c: \9 J# ]( T
5 g% T R" m5 `4 @& @5 Y$ Y, c( K$ P" O$ ]
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函数必须返回一个值
; g. L3 r+ n# Y5 `# _( \B.reduce_fraction函数必须接受一个整型值% c* M* a6 h- f0 j
C.gcd函数有问题
/ P6 C# i3 Y: J8 Q; fD.必须通过引用的方式传递$eight_tenths对象: j+ w1 ^* t3 e" D* C
E.对象的实例不能传递给方法以外的其他结构。9 _# |5 \& z; {) [6 y! ~
8 B1 `8 m, {& H7 I( Z% X
" S: |8 \# I* m- _3 `15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
# g8 E) Z! A/ r3 s8 fB.生成myclass的实例并调用mymethod方法' E0 h9 \7 f9 p( F% ]* t2 X
C.产生一个语法错误( n% y: R6 K9 B8 j- O! ^/ p
D.默认myclass类最后被创建出的实例并调用mymethod(); |) k4 q8 W0 [
E.调用名为myclass::mymethod()的函数. A: L/ ]8 K# O% F7 D# `" s
) R5 F1 a0 p, Z8 k2 _8 q. Q
! g; g+ T$ m- F7 ~/ {
16.PHP中有静态类变量吗?, N* b; o$ Q) l' d! d
1 ~9 l7 G! u+ u, W5 h
A.有
2 v1 c8 l4 P( w O! W+ |" o. ?% nB.没有
8 V- v% o# m1 \. S; R' J4 A# }8 y1 H8 ~3 n
, c+ _# @: `9 S: w
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.1$ J% n. Y7 O/ T3 a* P- j% _) a
B.21 k {1 D* E) t$ h& C2 j
C.一个错误,因为没有定义a::$myvar
* u$ L, \# E9 c2 u$ ^3 GD.一个警告,因为没有定义a::$myvar' G+ p8 x: v* S f
E.什么都没有
! a. \6 [- a. e- |/ Q( l2 Z2 d( c4 [! q7 m. ]' s2 A4 k
7 K) ?( _" Z/ A% Y7 s3 l$ b1 S
18.如何即时加载一个类?! ~; q0 e8 |6 k+ ~2 |$ [
% @" V( q$ d* H# w& s3 D9 A! J
A.使用__autoload魔术函数# y5 w/ R$ M4 n% X* S! \$ e
B.把它们定义为forward类- p/ l3 ^8 D" Y) z
C.实现一个特殊的错误处理手段
/ H5 ]: j/ Z9 ?6 Y' xD.不可能
0 ]0 F8 Q8 j3 U& Z/ qE.用有条件限制的include来包含它们- f% }: n0 p, N
# W( S. h( N, d, G8 ~/ Q# ~+ _9 H# ]) e% ]3 E' n5 g7 y6 Q8 {
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
6 d; y2 V6 X) r8 y: d
' W4 w4 Y* a0 `7 J 答案:__________4 K0 G! B% w; D. H& o' D$ W3 W: J& _. q
, Q# M; X: B( O& q
+ g' [, M- | k& r20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called+ X% d+ c, R a: O4 ]
B.一个错误
7 p2 ^' b' K. S0 N3 BC.一个警告2 e+ w3 ?4 s- n5 S4 T E
D.什么都没有
9 D. A& G- F6 D4 T4 H$ \) L
" m" m( Q( W* P% t! I" Y! @4 X5 u% H% f; u* J4 j1 E% T2 s+ p
% s" V5 ^% Y2 h4 n% R/ j @
答案速查
5 z6 q" a( S# v5 Z: ~+ N+ ~1 c1.类1 U5 U9 E" X' Q/ W" Q
2.BCD
$ T) @ v x/ F" c3 j) r3.C
3 d) m8 I- t& ~& z$ x4.C
, v2 F$ C- L( m5.A
6 \8 G! e, C7 |2 ]7 x& |. l6.C: `8 L( _; k' D
7.C
: G6 Y2 x: z& N" l8.C
+ x5 k- @8 V1 G+ \! x9.D& G! f C. I. j) y
10.B
: F$ x3 \4 v. z0 x; V11.D
0 a8 b/ o0 F5 g4 K" }3 G12.B
; f* ^3 b: j& b7 g1 v3 L, C13.A6 W) u% b5 N) X" a8 x+ N: _% z
14.D
& _1 ]/ F7 i3 O9 s6 B15.A
5 i. n8 I4 t2 E+ @2 M( o+ W4 M+ l16.B
, Z+ \1 r) V3 `# ]17.A
, ^0 k# f1 X$ D/ g18.D
+ t4 x1 k" C* y9 R+ a7 ]2 C3 z" I19.设计模式; W4 |& W7 Q* E) i8 S4 t6 S
20.D; [! X$ J, z( P2 t# T! v2 l
M" o3 ?( w& Y# y* `6 Q2 P$ x
0 U5 F1 W6 G' k4 Z* Z' }- T
7 C ?+ g Y8 \7 i. ]
答案详解
, i% g4 F1 E0 t" a) g
* c1 F) T$ n" O( G5 X1.类是对象的蓝图(对象是类的实例)。 [5 m, y) i! B, Y& d& E
* h. Y9 ^& P0 k7 @2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。# y* n! @! q/ M2 p
x5 X; ~- t! ?7 @$ J3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。: ], [6 I/ @8 |, C3 ?+ N
) I V3 N5 b b. n6 y$ y0 w2 T5 \! w4.单件模式可以限制一个类被实例化的次数。
, ?. r( s x" o
0 J5 d ]" {& U; @6 S5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
: p* X* S/ j7 @9 A1 ~ N7 |/ U! k: H x# p$ w R# F; K
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
' r H0 e s ~8 U3 R6 } B+ c: _! e$ F
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。( |0 L s0 T2 I1 Q* x! H
' s8 A; Z6 F: R8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。6 m- P6 t( @- n0 ^
8 r) \1 Q% B- [
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
, r, ]# h; m. f! {3 w$ M7 {* W* U9 ^% `- r! y& m* J7 T
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。- I4 W( w0 L, }0 O3 z! X
8 G+ i3 _5 X U4 @4 a4 |& ]# w11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
& y8 K6 L, @; K' | |# E0 d, @
5 ?; [5 p* D2 T [5 Z/ I12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。$ j% b% d9 A3 A% |- }
& q1 j4 \4 u& `4 b
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。$ \+ z1 [9 w) Q2 r0 G/ x
: L* U3 |0 W- ^14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。' H/ ~8 ^/ c# B/ C! l
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:% j" `+ P# z6 A% c. P' U
function reduce_fraction(&$fraction)
}5 t! I+ T" J& `$ Z8 c( Y% N, y答案是D。4 Q( M1 b( B; _$ B. c( X, ?0 m
0 }/ C, R' v5 }0 V
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ i; h B- [$ }- l
, [- ]8 q3 h, y5 }16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
~# R' w3 g, {4 i* r( F
/ J3 o( o7 @$ @' N- h* x17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。 h0 m7 D. n7 W7 @
* k: k: Y- T6 B& }* [
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
; D5 O% H/ D/ C/ Q* b4 c- o, K: W
`3 [ x, j' z/ u1 [/ {19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
9 J+ }- u5 [+ i/ \( k
: B1 P/ I2 F9 `: [$ {7 s! c; ^4 V' C20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|