|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。# F8 f' o& l8 O7 x+ V; w
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
! C6 _5 |/ v& {4 f( n本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
: R9 w+ T U! B, I1 n( m% h4 ~: W! {& X ]! H
问题: v- m1 j$ B9 R2 N: G
! t- D, `* O5 k2 a, O
1.对象的蓝图是什么?; |6 x5 _, X1 x; c1 J% b4 @/ z# |# h
$ _( ]1 @/ b" r7 a" R答案:____________0 A: W+ [, k6 F0 \
- s- S6 e; ]" x& t6 c% o
^% g) q1 i- Z* Z4 V' Y7 f8 C
2.以下代码执行后,数组$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
1 |0 E# D" S9 J' ]+ y; aB.b$ y+ y& t- l% \ E9 \8 r$ Z6 J5 a
C.a, @9 l+ I8 Q9 y2 B2 k2 }& I
D.d* t0 o8 b [% z/ }
E.e3 G" ^! }' m+ }0 b! p" T5 i8 k1 x
. X {; g" G3 C! O% j
# q8 L* ^5 b+ M$ B% L# B; q3.如何让类中的某些方法无法在类的外部被访问?8 ]) e% u/ u& r$ g
' |) r. Q1 d8 Z% VA.把类声明为private
+ W- V J$ x# L7 I0 r. }B.把方法声明为private
4 m* \( @0 A9 z$ `3 w- o, r* Y: tC.无法实现
. X: Y+ G# u! S' p5 m% o. V: P6 i) f& YD.编写合适的重载方法(overloading method)4 ?6 i! U( c5 J, J/ D0 z) P
3 i& q; Z# q9 b" ^, i. M, c% w; d0 z8 H& X% P3 A
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?8 n$ ^% ]; y* _5 x1 ^0 U
( }% u% o' `: }; V. a, f- U" jA.MVC模式# ~0 h9 D5 Y* `. R
B.抽象工厂模式(Abstract factory)
3 B5 q8 J: {9 y& J. GC.单件模式(Singleton)3 A$ [0 W! V9 o! T
D.代理模式(Proxy)" Y# c# s- }% ]. E0 A- {! Y
E.状态模式(State)
* y; S& J: G/ M" _
# `* [7 R9 v/ P2 P; @$ r/ r* O+ Q+ v) w# S
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?- ]1 F9 D C$ s7 E* W \; |
3 F( N* [$ d9 X! dA.1个6 V/ I9 e" \; b) u
B.2个
; U9 W; d0 Y* z5 EC.取决于系统资源5 i" e6 O& f/ W! u2 [
D.3个. z; r( g: o" P* U9 b. ]; s. N6 r
E.想要几个有几个
/ I2 \7 r! e: g& e) U5 R! U
# J$ }( X& H$ S* c- g# p
8 H, g5 K, q0 k" `7 r4 o6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
" B# m- u- D! A( p' z7 `B.接口
6 k3 c; E$ v5 w+ @6 b; {, F8 UC.抽象方法
2 @2 W# R O( ?D.Private方法" k2 e' I, k0 M; f: i: e* b* l
E.函数重载(function overloading)+ U. i2 U% K* a8 g% C N
$ Y; u) _8 i' |7 ^* P/ f
8 v' l, Z4 \+ E( D" [* E, q. D2 U2 J6 o7.假设定义了一个testclass类,它的构造函数的函数名是什么?0 ~/ ?! j6 x- a! m2 f7 W3 {# C
& Y8 R8 R, ]( X$ L9 Q9 B0 k' r2 {
A.__construct) q. g' `" j& k8 M9 V1 W! ~
B.initialize: H2 M! B. l3 X$ V! N
C.testclass
5 g$ k( e$ V' ]* e$ oD.__testclass; X0 R! ^4 C9 Z" U) @& u9 Y7 R
E.只有PHP5才支持构造函数
$ N2 j6 |6 M. a3 s; h9 L( Y7 A6 n( {
* h( I' H% X* y: Q$ P# _5 Q! n8 l
8.一个类如何覆盖默认的序列化机制?* ?5 T' s- j! O5 d, H6 }' }
. ^( E0 w" }7 E9 Q3 R6 v! ]A.使用__shutdown和__startup方法
! y+ d/ P2 |" I3 h9 l7 vB.调用register_shutdown_function()函数
' r. K) ?# q+ d* tC.使用__sleep()和__wakeup()方法$ B0 v1 A K/ i% O* V+ P4 h, |
D.无法覆盖默认序列化机制
6 t; E& X7 f r8 `* E, O2 E# D- @6 sE.使用ob_start()将类放入输出缓冲中" C3 N+ |% S+ g! K; ^. A
% G) e& y% P" e7 P
" ` q& Y" C) u% h: O4 j' v9.以下哪些面向对象的概念无法在PHP4中实现?
3 D3 I; f* o% z! ~. ]' D
5 k" e& ~% H0 A: @/ i$ H@抽象类
9 u7 G5 W8 t- @4 O* m% F@Final类: ?* E: d$ H6 `! r( V9 G
@Public、private、protected(PPP)方法& T" c: q3 z' L9 L+ I. j: Y
@接口
0 n% P; a7 U2 a$ P8 \# z8 f W e' B7 [: I, D; {/ E
A.抽象类7 f* S% y4 w$ \3 z3 Y
B.PPP方法9 j; j; Y/ h3 F/ C: t% e) | x" [
C.PPP方法和接口
2 s; Q* {% I6 I- `2 hD.以上所有都不可用6 k1 W, S( `' \4 C) M6 v
E.以上所有都可用
6 ?6 T! y7 |) |: B7 [4 n1 Y+ M% [% ?2 v6 Q
" M) }9 }' ~; e: F0 f [* [) B
10.如何在类的内部调用mymethod方法?
+ a4 A3 b) ?; V- w. y n! _6 x3 T1 w; N% |) B4 W
A.$self=>mymethod();- c, l) ^! D @# N( O! v1 U
B.$this->mymethod();
1 d) J) N0 M( W( iC.$current->mymethod();* O% N6 e7 [) E# C$ Z
D.$this::mymethod()3 `6 [, s9 c0 O( v' O% {
E.以上都不对
- r+ |. {3 o7 U& L |3 t
# |5 `* R0 K0 L5 ?3 R
' ]- J; [3 i! G* J. U `. x: P11.以下脚本输出什么?-
- <?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: Z+ u; [& |, i' V" u
B.Null9 P& i0 q5 X& V' W# \
C.Empty
8 u5 V6 j, h) ZD.什么都没有
" k' U( a$ _2 N( k- j& eE.一个错误# x5 J0 S+ ?) h9 t" X
5 c; j1 L: P. N. ]
3 n5 | T9 ^6 E. q+ v12.以下脚本输出什么?-
- <?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 Y5 q8 A0 o7 T) FB.5* P; ~- W; T; R
C.2. m9 I. R4 U3 y% _4 t$ p0 @
D.Null; |" r2 f9 V L1 H6 y' N* e( P& R
E.什么都没有6 T& C/ w7 Z9 @& T
2 c2 }. H9 l7 [" K
! z E, z0 j9 W- C& b; o
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.50 L& w, Z3 |6 S4 F6 x0 U$ P" }, W) D
B.10: u V( R5 j. `- b7 c" Z S
C.什么都没有% j: g: u. M. _/ E+ H
D.构造函数将报错1 g8 y! S5 F) x [# z4 K! M; \8 W
E.510
/ b3 e& j% H7 L0 W$ N7 }5 k4 z
3 d5 z) N# _- b; @3 \
9 n$ r: ?. [/ 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函数必须返回一个值
F6 H3 g; f" D+ [B.reduce_fraction函数必须接受一个整型值3 S5 R o- y) B) B1 M. ^: _4 U
C.gcd函数有问题
" v6 v% q- c7 R2 L0 I/ }5 tD.必须通过引用的方式传递$eight_tenths对象% A$ @: b2 R! t, e
E.对象的实例不能传递给方法以外的其他结构。5 L2 L' x" j( V' V6 V+ h
. ^) q. M5 D$ c0 P+ h% c
, z i9 L& h( k% V4 Y15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法" I4 `. T! X* i1 m) Y+ \
B.生成myclass的实例并调用mymethod方法+ X" z' o4 T/ [/ C; Q
C.产生一个语法错误
: d/ _6 p" m! dD.默认myclass类最后被创建出的实例并调用mymethod()- w& a8 c+ ~; b/ U" d H, x
E.调用名为myclass::mymethod()的函数2 b) S6 v2 h. j' a
- W# }; o9 K" V8 u! R
- m8 N- c: j* Z16.PHP中有静态类变量吗?
& `( F8 s( P1 C6 ?1 O. t, O
/ n9 u5 }9 e- i+ }4 E6 i& w WA.有
0 G1 ~- I/ |- E# ]B.没有+ f! A3 n( S, a8 F2 P* }
, [8 o" B5 I& s: q6 M* l# O- n ^
" l$ E- l& U, I+ t& M' x' u2 P17.以下脚本输出什么?-
- <?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
$ B) ?# f* g( s P/ |B.2
" a# G0 s1 s' J5 NC.一个错误,因为没有定义a::$myvar9 f; b- v" E1 p/ P% i N
D.一个警告,因为没有定义a::$myvar
8 W0 T; t& X. K* LE.什么都没有
' c1 }" a& l( o6 X& d0 a$ U; N. }. p8 D
9 h1 e# E; m- R
18.如何即时加载一个类?
, K& Y4 W( L# A' N+ Z3 l
& }: {7 z* Q$ y0 WA.使用__autoload魔术函数: t7 a h. n: @ E f& X8 c
B.把它们定义为forward类( b5 ~" }6 o: `6 Y7 q7 K/ P; O+ q
C.实现一个特殊的错误处理手段
% B. u3 } O8 {9 |- M- T1 |% Y& W6 YD.不可能
( \/ O* x# @* V0 j4 s7 P* q8 @: F: GE.用有条件限制的include来包含它们
# O6 S% A, X. ]$ n$ F% N* n0 u6 @6 e1 [, Y
N9 B9 z! |# k I7 X. Z
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
' h" x6 e2 ^1 n
8 p3 u, S; H0 S3 B, K4 ] 答案:__________; V6 T7 O) `6 F7 x) w% n# [
' X6 V- K/ U" U- N: F5 N' A2 s
- R8 J" B' w, h( Y' M! o20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
9 S* D+ z5 J. q- [# h) Y2 _! i2 MB.一个错误3 d M3 ~4 Y0 T/ a$ e# y
C.一个警告! n1 Y4 C; M; H3 F- T* W* C* U
D.什么都没有0 \! i5 P; x8 _' L) k# `8 S9 K
0 b7 K" U2 h& \- |5 }, H: Y8 {. W7 e9 w& g
& d0 P. {) |. v9 [; e答案速查
5 F6 m+ G) s. M+ \6 G" E4 |1.类
) D* j# w, b# R0 r( q2.BCD
+ y \' I; a9 N2 x" A3.C. ^" G: M" A' v8 l2 G( b. a m" n
4.C
/ [* {3 V8 j) [. E' B9 ~: W; b5.A
( e3 ]) y( c* q3 D% s$ E5 X! S6.C: d8 ^$ w, D+ F" T
7.C
: p. k: |1 L2 S8.C \1 o' N; m# Z
9.D7 r2 q8 P$ v h+ Z
10.B* Q* M+ J2 h: o$ ]
11.D
8 {8 Q/ s; @: c# M6 I12.B
9 A' \( H6 e8 |! |13.A" P- v, T* S4 ?
14.D
9 t! }1 Y' E# n. W15.A
2 T3 J: V( b$ t! i3 U16.B
' B' l. L0 H5 T! p. b; ^; }17.A
& V$ x, x4 k$ S6 \% W18.D
' l# d$ ?3 y4 A/ A19.设计模式
$ Y. B @% g! @) s+ g/ Q20.D: s% N/ A6 e' K$ u8 O. \
% n6 m& E8 n( D+ `) V, C. r! r; T- G, B3 @2 A& A7 q
3 z8 t o: }1 l U: S" V
答案详解
- u V+ y6 |% Q; K" Y ?, K/ v1 t3 _ n. i
1.类是对象的蓝图(对象是类的实例)。9 X9 ]& z; X' t, ^. f' H7 E
" M' Q3 [ R0 E2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
& H! g1 r5 p" j6 X
. D6 l z; ?" z3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。/ p6 M% x9 p7 v& H& [
& O( J5 S- m1 i% }1 w+ z% j2 r
4.单件模式可以限制一个类被实例化的次数。# v0 R" k# }) j* |- i2 {
/ H' W' y) v- A- e0 G% n6 r5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。7 j0 o0 e7 y9 t0 s8 C# r; z
8 N- l7 Q V3 E/ D9 J
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。4 ^) R0 ~/ o' R
" B _8 v" I2 h3 G
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。6 a" [6 p1 ]1 o# u6 @ \
8 L6 S; ` o$ ^; v
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。) {* t, O: R: v4 Y* i, u
- Y/ V; _0 y, t9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
+ Y: s7 c1 m2 c: p1 e7 ]# J5 `( e7 Z5 H k
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( {- J3 \4 B. m1 s
2 B7 g, Q) \ b% ^7 v
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
- }; L1 K- }4 I1 C2 L
5 s4 d$ n" r$ i6 b e @8 ?12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。/ ?- s# W5 b1 c; `3 [7 T/ @* [1 s
3 e0 G! f/ S5 h5 S+ @4 y s
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。0 \# K# A! r6 S, h! t; }
3 _& j3 f% D6 Z14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。( T: I* ?9 i) l( c- ~/ O5 j2 ~
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
" W* ] }2 w7 O! f. F+ v$ z( D function reduce_fraction(&$fraction)3 Y, v: k/ w9 O3 D ~* r2 u
答案是D。" V. C- m4 D5 g& G4 c: P8 K7 e. |/ f" m
- a; S+ W. E7 n3 r
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。/ K! b$ @/ P+ i; G# t
, z+ c5 T( Y* ^5 w" r
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。- r0 b0 n% I% K& _% s4 d }
# l" } s, F8 p
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。8 }& y, x3 g& }
+ B/ `" a, ]; ]4 [$ g18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
" P" b% c6 G# D! K( ]" O
, h9 ] C' V9 _) D19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。$ x2 g2 x% Q) p. X. m7 A% ~
# ?: r$ ]3 A9 s20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|