  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
1 w" i8 P8 q9 q' y( \+ KPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。" D4 y* ~- |+ | J
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。0 }7 k3 s/ g, T/ j y4 R5 m0 O
) \8 ]3 H! B5 n, \1 O! ]. \
问题2 O; W1 g# B! j6 w: o( w7 u1 Q
& m% M6 Y7 b% @: `* g+ D: I1.对象的蓝图是什么?2 f1 P- x, c+ O- y
4 G8 ]) A/ g8 h" Q) f* d2 |) O答案:____________7 j" F) P6 A( S( W
7 A0 K$ S: q7 {* q0 I n
$ ^! D# s! }# {2 E) O+ z2.以下代码执行后,数组$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
4 a, r+ O4 ], l% \" VB.b! u) h( K3 B/ O) S% u+ i& b
C.a
0 k6 g$ K2 u/ m6 f& ]0 F }3 mD.d
& t9 \( W6 Q! U- c7 c; N1 V( jE.e
& e& C# d' O- L! f& b( j3 m5 }( b" x+ c4 _! s" g5 \ Q
5 ^- x8 r9 @3 ~& `5 D
3.如何让类中的某些方法无法在类的外部被访问?+ [1 X$ Q w2 A
3 [0 F9 _/ n+ _# p0 bA.把类声明为private
( P5 H2 k# N4 x. S; x* cB.把方法声明为private
! w U; n1 \& W! rC.无法实现8 o+ ~4 G( z7 e& a2 D
D.编写合适的重载方法(overloading method)% D/ _; q9 B3 g. I; y! x! M& U2 a1 V
$ l2 e& }! s3 a0 d# g$ G
- N- c: n$ c5 A. O9 Y$ n
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
! h* e% x& D8 A% Q0 M n6 N* O' i8 c1 h7 }9 ]4 e; S
A.MVC模式" S& K1 W6 R( f! R' H& j
B.抽象工厂模式(Abstract factory)
* M- h# x: C9 q- y! s# k4 HC.单件模式(Singleton): w1 @; u0 F6 t; S
D.代理模式(Proxy)) |! b* r' J% y9 z
E.状态模式(State)
9 j) q0 q- ]" h) E4 `2 D. h) i
0 N3 C6 h$ ?" ?3 O! ?
& w' b9 N! o6 t$ z( s" |' n5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?9 J* N9 T j% z: a7 r" K
5 ?7 r9 K9 J0 `8 n6 PA.1个
1 A/ u1 d j1 \# b; H0 Y1 z/ ?B.2个
8 `$ [6 e8 a) hC.取决于系统资源( g3 I7 G4 n1 A5 i$ J8 @) D
D.3个
" z$ O) |7 _2 N* W' s% G) vE.想要几个有几个2 i |1 A% \( n3 C1 d
3 D( B/ L6 {" C- C
o# q# m/ {3 o- R6 _0 I
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承& Z1 w( g, R7 C; x- y* N3 ^
B.接口4 B" c! t& N. v+ d
C.抽象方法
. Y; @% }& D' b) E! ]+ j- ?9 PD.Private方法- V! h @& o; N: O' o
E.函数重载(function overloading)
" S% Q) C0 R6 _3 k
2 q3 B$ L& w! [- R1 e7 O% a9 i% {3 U0 W+ s: L
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
! a8 m8 P6 e1 N+ x5 L7 v$ `4 [* G9 M7 m v
A.__construct4 d2 X; w- Q6 K
B.initialize
* ?9 L+ S+ R3 R# r5 }, TC.testclass
; m4 q+ G# Z% V4 OD.__testclass2 n9 w9 o5 W& q
E.只有PHP5才支持构造函数& ^# v/ p% I6 ]3 L! L
: T& z5 H/ }/ A e
+ m1 G+ {9 I# Z/ ~5 L4 ]
8.一个类如何覆盖默认的序列化机制?
/ {% q. I8 U5 e( B1 t* v6 L( m% L7 ^
A.使用__shutdown和__startup方法
+ X( s+ `/ |7 y2 cB.调用register_shutdown_function()函数
* K; T& a' }; x/ B Y* rC.使用__sleep()和__wakeup()方法& u2 k( G) U" z0 ]0 d* M
D.无法覆盖默认序列化机制
7 y! u4 h3 V" dE.使用ob_start()将类放入输出缓冲中
% G7 K" n( z5 C7 w! u& p. k2 Y8 N6 U4 m
/ X% \2 w# {; k' u& p1 S
9.以下哪些面向对象的概念无法在PHP4中实现?6 m" O2 c3 ]1 G& |$ y
; d/ w& M. R9 Z% [3 W5 c@抽象类
8 ^* O- t' k* o4 x@Final类1 ]8 r: }0 }! I g% F! n
@Public、private、protected(PPP)方法
4 w# d$ z+ @ @4 T: }# Q@接口
, _8 P0 ^ f0 Q. L( M* F X. K- _2 u6 {$ U' K
A.抽象类
7 d4 C" e+ F `& A4 n5 P6 L+ QB.PPP方法
& ]. V! R% U# }+ {' l7 `5 KC.PPP方法和接口' R N* ~8 Q2 ^- D; k
D.以上所有都不可用8 I# f [# T6 k$ ^/ Y
E.以上所有都可用1 Y( E; p% \) z7 b" R) B; n
7 B- L) J [9 P, T6 X
- g# m3 q, T/ l10.如何在类的内部调用mymethod方法?
2 c( R) Y, y- E; a
7 v3 Q4 a2 A0 O! q* T: E, V" TA.$self=>mymethod();8 p8 n4 W0 p# w4 }
B.$this->mymethod();' b6 y* m# h! b# T. u
C.$current->mymethod();
6 i- M1 g ?3 I+ r [; K1 d; DD.$this::mymethod()4 t; H5 u1 n" U3 i
E.以上都不对( x5 N4 }! \8 i- R. x
8 p5 @/ w9 \4 N. p
7 ?& ?2 Y6 `8 N: l" ]$ L: Z( `6 @0 q1 ~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( m2 F, H$ N7 G
B.Null7 o4 q! A# z" x# i/ ]
C.Empty
9 e/ P8 A/ L8 U! J' bD.什么都没有! M' R, `* Z' h
E.一个错误
* |& a! N" @7 x9 K$ T
0 K: Q: P- X% N @
* O5 I% W4 M+ X" G! B$ U12.以下脚本输出什么?-
- <?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.108 z: k& b) f5 R% f! @9 d
B.5% o' Q7 w3 }$ u3 v
C.2, V. i. s) V' z+ ? k
D.Null! Q5 I6 K1 A' U) p
E.什么都没有
( E4 L6 ?. r; Q: n) _) E
) T& M* c- F+ p3 S$ D) e* c4 D0 s! ?5 R7 e
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
( R$ B2 ~* a' q# dB.10
- i& a4 E! m3 O! C8 N$ GC.什么都没有; V( v: Y2 A _/ x! o7 j$ [
D.构造函数将报错9 _' \$ C' W3 Y# z7 ?
E.510
& M* _( C2 F6 v7 @6 N( A. V% e5 [
' v& L$ M# {0 K/ z' Q* z$ f" a
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函数必须返回一个值
2 _+ E8 O& n2 `3 G ]6 hB.reduce_fraction函数必须接受一个整型值; S8 ^( f0 U- q' [0 w( C7 J' g; M
C.gcd函数有问题
! Z' ~3 ^+ R3 YD.必须通过引用的方式传递$eight_tenths对象
z: U8 E7 |, y8 g! U( DE.对象的实例不能传递给方法以外的其他结构。" v! B# Q Q+ N# s+ f" D
7 X$ t% N$ Q& F _
2 p4 z( |' [" W* k! F15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
: G# V+ t% a: ]1 e; Y# FB.生成myclass的实例并调用mymethod方法
4 j' A/ U: X+ V% P3 y( TC.产生一个语法错误1 T- [& j( T% W# T/ m
D.默认myclass类最后被创建出的实例并调用mymethod()
- C/ q4 W1 O- u% M1 iE.调用名为myclass::mymethod()的函数
# }6 H; C8 g8 D# u6 S+ _; u$ h9 h, ~' R8 c% B
0 t' o7 X6 A( I
16.PHP中有静态类变量吗?) U% f! ~& Z6 q0 H; ?) J j. d
( C3 g7 ?( F# S6 e9 p3 z) d
A.有
5 o; C1 i$ Y1 ?B.没有
: t6 w: \+ ~0 U
" n# l! o2 t' T0 {" @& A7 w3 R/ c, z, u3 [
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
8 |. h% |! ^4 @3 aB.2
( \ ~4 W% C5 A, K: z7 K. R7 F( H# SC.一个错误,因为没有定义a::$myvar
: h9 f7 X2 O! k! f2 W( uD.一个警告,因为没有定义a::$myvar% o& y) W) E+ `7 d$ U4 L7 a
E.什么都没有( N. L H2 U' V' F) C! b
, c5 k6 t' _5 \
9 c! P, F% ?" o) I9 `, e8 W1 O1 {18.如何即时加载一个类?
, |, x. ^5 [/ t% e7 C; [0 _& j6 G& x( b' \
A.使用__autoload魔术函数
0 k. o' \4 Q% n. N* K* b$ wB.把它们定义为forward类8 _' H, {3 ?7 ]
C.实现一个特殊的错误处理手段7 B8 b/ i2 A0 i' u, L: |) V9 w
D.不可能
7 R! M2 R- J* R1 y6 CE.用有条件限制的include来包含它们( k Y0 d4 A- |1 }8 t# z
# \- M6 v% h" w" |' p) u. }
. x, L/ j8 i" f- n
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案? ?8 t0 A* Q |( G, s) `' y
& Z/ n1 I' p l- S( a3 M 答案:__________ x$ o4 X" k& i; W- u7 [+ B
. {% h- j6 k4 }
% [$ y$ R P( l+ @# d
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called8 K/ l3 g9 l3 f; H1 W7 x
B.一个错误
) M$ O! R* ?3 X3 f7 e' dC.一个警告
* e! q# ?4 q5 |7 {, rD.什么都没有: m6 q& X. N' u2 v/ q/ U8 [
3 t6 _+ o) d x- A/ q, c
- N( K, n7 }+ \
6 O" h0 ?& ~! @, K
答案速查5 s- Q0 f% V4 [% E' D
1.类7 E( h/ m6 y. P* I, y
2.BCD
; ]8 l9 ~" ]: I8 o3.C$ n8 z: J2 V/ h; }
4.C( m6 U/ k# Q5 i" f9 d6 r8 b9 ]" x
5.A
5 o8 J% Q$ g) ~6.C- Y/ _ q$ G" E+ V( s; H
7.C
# e n0 g$ t2 u& P9 ]* D- a8 G+ r8.C
! P# d4 W# t+ l9.D
% W: g) |- C) G: s9 `10.B
) Y! z8 {3 I. |7 F) H5 w& g11.D
2 @# D; E5 {& X O3 C12.B
1 y+ T6 a1 t3 f: F8 D13.A# \* S6 D1 K& o; ?/ p. l. c
14.D- U0 c8 j N- V$ U
15.A
# G3 I# k9 }7 V1 `$ W& t: d* h16.B
0 \/ h+ a+ l1 F17.A) R: O- w* y- `4 l8 T; {% I
18.D$ P; B% E5 ?2 Z% z7 ~
19.设计模式3 [: y2 {( @6 T" c1 p
20.D/ p! w6 X. M; u
$ D" w& ]# }% C9 T7 f, L* l
, Q8 t; D& l, i' _& c# C
1 u% z4 z" U8 [6 u; a答案详解, v: Z$ Z$ W+ m
/ B9 g0 S e0 W3 k
1.类是对象的蓝图(对象是类的实例)。: I$ n# e# s( u& k: x1 U" a: w' N
' L' i( I% `4 l: M
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。. \1 ~; R/ P5 Z# D; ^! @8 N
0 i* J' e5 e/ U7 L( d$ b" D, q
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。4 t8 m2 P% y" y
$ g' ?# ^$ x# b( G* z4.单件模式可以限制一个类被实例化的次数。
" F. f0 ?0 f7 r& u
! ~0 D" T. `0 b) u& R- J5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。) }) y9 A5 W; y! B8 R2 _ U6 `
|; \. U: Q/ y c. F
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
$ _- X& W9 y& D, I2 g) w4 ~ K& e4 W" R5 A% F4 s& x5 |7 l
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
* ^. D8 f4 t# ]- u0 i$ ]3 D+ G( M, `( n$ B& {' X: w) _
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
8 m7 S8 j' R) r* m3 C3 x9 A
% J* G% i. T0 p9 |' W/ `- \2 h) V9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
4 ^( Z3 w3 L. o! g. Z1 ]
" n2 ]9 [% `* J( I- O+ K) {10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
4 I D$ {- y4 E7 s4 n# W8 W7 w6 i
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
. [$ G$ V; b; [7 J1 a, g/ y6 P* F6 p3 x; O' J: ^3 Z% l- Z
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。9 N* _: u0 _) J* t
; K# r, y9 u9 U13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。' [% H/ D) F7 b2 y3 k; @2 z
' C3 U( o- m4 \& w1 r' w
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。" @- i) o( h& T* {* }9 m
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
/ S( Q0 R" J( K function reduce_fraction(&$fraction)
" z [) T+ ^# r6 j" Z8 A% p E答案是D。( b u4 e# ]) o" I( \3 g+ c3 _
. x- p1 Y- d b# q' u
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 U- W0 L3 k! B1 C/ n* s
" T6 ]. [2 r7 _- r/ p3 c% c' e16.没有。PHP4只允许声明静态函数变量,没有静态类变量。+ \9 P5 W) |$ n. e' c8 M
3 X6 n8 d5 I3 x* k |
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。/ B" m7 j3 M& N# E X
. y( X% g" J5 E( V/ W# X+ R7 `18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
& B" t. G+ ]$ f2 a9 m" @# L
( O' o1 V& c. k4 u( h! p/ j% F19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。5 c2 _) ^, N3 B0 i
" U! b4 T s6 K$ O
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|