|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
, \- y! `5 r+ H1 y$ ~2 WPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
1 A/ X0 l6 M+ y4 m' f Y0 C本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。" _# V1 v2 i/ x/ F
$ u/ K- i& j8 [5 G
问题
: U3 f, w4 Y' o+ t- H) i# D
+ O& {# E. j }3 ?; F1.对象的蓝图是什么?% \2 H" s) r y! N- V4 }/ u
8 b# @) x& }3 F% b, u) k6 ?答案:____________% R- t, m Z. g6 g- @
3 Q6 h( h. m) ^( @* v$ }
3 T# X) z! C3 W
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.c2 k# Z3 Q5 A7 T; @( ?: N- ^5 z# }1 c
B.b+ w2 `4 q- g% h- K5 D- L; \* I* W
C.a
* m$ d) M# S* U# `' }, _D.d9 V6 C5 k) O: @. I9 |$ K
E.e3 s, R) V l- q
# @* B! }5 \7 K. Q' w; g
; Z- U# e7 U4 L! s, t2 c3 H# Q3.如何让类中的某些方法无法在类的外部被访问?
6 ^- \8 ?% w3 v6 f. l" L2 h$ _0 B" p3 e* Z% W" D, M; A) y
A.把类声明为private
, R0 ?/ J: d5 r B% i' V0 e) sB.把方法声明为private
2 I5 z# r k3 _. \C.无法实现 s! F) R: k" V. S
D.编写合适的重载方法(overloading method)
7 m0 m2 t$ d2 K- e* G8 M
% v' D1 s4 O/ b9 k2 x
8 w- p9 ~* T' K4.哪种OOP设计模式能让类在整个脚本里只实例化一次?; K( T) J% G/ P1 ^& k4 P
9 `/ o5 d+ p! r4 \A.MVC模式# N8 P! p! ~2 S D6 K% r
B.抽象工厂模式(Abstract factory)
! K1 \5 D* L/ C9 OC.单件模式(Singleton)2 D: P5 z. s* f& I1 ^# k
D.代理模式(Proxy)( m/ b! \, s3 U: e( {& {- W
E.状态模式(State)
3 U/ A) G) L) X( o: l6 T: H; z( U3 l: s/ f0 H- f
) j3 g. d2 {/ { u* F
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类? z6 l) ^, B2 D9 A
1 Y. p" D1 y8 ]
A.1个8 {& f* L4 Y p: U1 v% j
B.2个9 G$ D4 k& Z9 q6 W9 ^% ]
C.取决于系统资源
7 q4 E) ~4 K% G$ c2 mD.3个
7 _4 Q3 t l% }( Z7 N! s. JE.想要几个有几个
% B* I/ ?4 P. @* z9 T0 s8 m/ B2 Q( V! l, x/ C$ ^
# j$ C5 J- N8 ^# F4 t6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
& o1 c" G* \# e& ~: x; E4 M) a3 BB.接口* L. r. B+ s( t! _
C.抽象方法2 U, l: P% U- R
D.Private方法" C \( ?8 J. O& U* J1 C
E.函数重载(function overloading): e( u& p4 a) w0 t% ?
" e( D/ r# U" l2 d" F/ _/ s. C, p. p0 r# O5 ]9 _
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
) j/ f4 s8 ?) v5 v {9 v* z5 |$ P$ ?. W& z
A.__construct
7 s& ?! I" }, eB.initialize
/ [2 V7 D8 l9 b) e4 A; UC.testclass
# C0 d# P4 g. zD.__testclass: y8 z5 Y# G7 R) d+ y) h
E.只有PHP5才支持构造函数
& m3 E$ X8 g G. k3 a9 M
% @8 n2 R/ p) D4 ^2 k$ ~
; k+ a0 Q% {) V8.一个类如何覆盖默认的序列化机制?
1 R8 q X X- x
- M& k- Z+ ~% y+ `! ^8 d6 F& HA.使用__shutdown和__startup方法0 R7 g7 w- d7 y8 _$ z0 g
B.调用register_shutdown_function()函数) Z$ ]) n' L3 T7 s5 l) \
C.使用__sleep()和__wakeup()方法! u5 u8 j5 Q! o6 I! j/ g
D.无法覆盖默认序列化机制
' h: k, y$ j* _* w! j" OE.使用ob_start()将类放入输出缓冲中
* [; F; h& y+ z9 R
' j% o2 S) _9 r; F, G! y' H# q7 h0 a1 f% `8 C0 J$ K) {) ~
9.以下哪些面向对象的概念无法在PHP4中实现?+ K$ {; }% L3 o& ~8 r- A/ V7 {
! [, e. h5 W- v@抽象类
- K+ k" z6 w6 @ W@Final类, V/ B6 Z) y) X6 g1 Q4 ]4 [* C
@Public、private、protected(PPP)方法
# J! I8 t: q5 {/ G& d@接口8 j8 R' t! R& b. B% U5 R" I6 @
; |6 ?0 ?1 B+ m- [' |5 E% o% q
A.抽象类
3 F' E2 }2 e1 t% kB.PPP方法9 p$ l7 C1 r: ?6 j. x
C.PPP方法和接口
% i" L; {# Y fD.以上所有都不可用2 k% Z& L# |1 w- E3 b* w
E.以上所有都可用
! T: |1 M/ V0 l: B9 l2 X
0 M: D1 ~2 T0 f" W- z& h2 J! p' F5 h u; g7 c+ D' l
10.如何在类的内部调用mymethod方法?
$ B! p% X* W' \& B/ f. R* O5 ~- T, C/ S" a% A0 A8 H
A.$self=>mymethod();0 ?' C( [0 t9 {! S4 H- `# C: k* i
B.$this->mymethod();% X% H4 X: x9 p3 \2 L/ v- k
C.$current->mymethod();- M& S& u, s' u
D.$this::mymethod()
4 s. m2 n- M3 e1 y0 o) H+ O. `E.以上都不对1 u2 k4 u7 G0 X, r% x4 u
# j( Z8 o5 r4 n1 R- d. j! H
9 n {6 G+ {( E, J8 t11.以下脚本输出什么?-
- <?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
' C/ r+ j0 S: T5 iB.Null
0 [( R+ h1 m2 M2 S! V; }C.Empty4 o; H6 Z- K3 H$ Q* {
D.什么都没有" `+ P$ {4 J( C1 t* S
E.一个错误
; p- x* b9 o* f: o6 U, g% `! O; c) W' N
; |/ Z& y+ g7 M" o5 i0 r12.以下脚本输出什么?-
- <?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/ n/ q, l1 ?9 J
B.5/ Y3 \+ U8 @6 K0 W, c
C.2
( n( ~% [8 T2 G" K( a* L5 mD.Null2 @+ l }0 X4 h2 a+ g
E.什么都没有
3 R: H: v, n1 p# @" y N5 X
2 o$ T) x) g7 S( ^' ]+ r8 D4 Q L3 m* }9 N7 [5 o( a$ t, `" Y% R+ ?
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" C0 i4 Q, c0 P" a9 H: V0 n- G, w
B.10
6 }4 t" z9 {8 s- ^- w7 F- ^* E! C. Q( lC.什么都没有
5 G; W3 d" c! b2 B* }& TD.构造函数将报错
4 Y, g" x% H; @6 G5 F' d: n0 }E.510
% o1 D* ?0 [$ H' e/ \, o1 e4 N# V+ G( C4 U8 p/ Q8 B# J
6 g$ o* |+ k5 U: W' N! ]- U1 w3 w
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函数必须返回一个值5 ^$ @4 o D5 ~
B.reduce_fraction函数必须接受一个整型值
" s8 f( c- i M% [1 zC.gcd函数有问题
, D* a; m8 z% iD.必须通过引用的方式传递$eight_tenths对象% ~- g: h+ u' |0 R6 W1 ]
E.对象的实例不能传递给方法以外的其他结构。
* t5 Q/ d+ _- ~* N, Z* ?
: l9 K2 N. O, n4 w
& C% P3 @( z% B& g0 r5 z15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法+ w+ _( {' \9 o5 l$ y- E( k
B.生成myclass的实例并调用mymethod方法7 [, F1 d. T& ]+ A3 T8 _
C.产生一个语法错误/ l6 d3 A2 j; @/ \
D.默认myclass类最后被创建出的实例并调用mymethod(), Q7 I: Q* P) k! q& d
E.调用名为myclass::mymethod()的函数* d- k, |/ Z" a
# M% c% s/ j" ]6 Y& S, b# B9 r. p& n- `
16.PHP中有静态类变量吗?
" I* [$ v3 P. z0 o/ R7 Y! M. W2 I
0 N+ u% t2 M* ~$ [2 rA.有
! M$ b8 J. I hB.没有 B s6 ~, |) x
8 {" q$ b9 f5 A7 Q
6 K" k0 t2 Y- S5 V% h. n- c
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
1 S( e2 s% a& d2 _6 VB.2" h& \* c8 w4 ~! p
C.一个错误,因为没有定义a::$myvar
/ R3 v/ F' Z/ ~+ jD.一个警告,因为没有定义a::$myvar) o- J6 C' u! w' R! q- w3 U' @) P: j9 c# R
E.什么都没有2 k' I$ Q, y k$ W: O, S# d
9 M) ]/ \) B- l1 i @/ S
' D" v, d2 j) p4 C. D/ W) H18.如何即时加载一个类?% Q, H1 p- B. i8 r
! N) z( c6 u: y4 p KA.使用__autoload魔术函数
$ a* Z' G* b( E" r2 mB.把它们定义为forward类& a7 u# T h; f7 X" H3 B, L
C.实现一个特殊的错误处理手段
+ _9 ~. T5 u) X- u" pD.不可能
# T9 L2 g3 e4 c6 n0 \ F& Z8 vE.用有条件限制的include来包含它们) A+ h8 ^9 u* w0 n" y3 a+ Y& z8 \
9 [) }' X# z( o8 G1 t# k
* I# L/ \1 V$ b2 d; f+ ]$ n5 ~0 ^
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
$ Q' j, j( D0 N( _- G
( F, J1 _+ x; w4 S1 \! ~ 答案:__________
' M# b5 Y" k* m! k! m E+ I5 E
- i" ^" B: V6 U+ d; x; j7 k2 o; l& M( b0 C }. P5 | K8 {# j
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
) W( | b7 e0 i, x- D# T8 [B.一个错误
9 X% w6 I! _! ?. a/ S2 lC.一个警告
( X6 L) {: J* C+ ~" i, ~D.什么都没有, h; R6 J) I0 y4 n/ W O
2 n4 f! [2 y3 m( O
% u/ U$ t8 H! I6 f! m
7 S% H7 {9 g* J3 ?! s2 {; L答案速查
7 O) s! J z) Q" F/ ?1.类8 |' R8 D+ I# l4 [1 g
2.BCD& A% F; r/ I% @. X
3.C" w5 C. Q3 r; I
4.C, C S$ E/ G8 Y4 W
5.A* s% ~) h+ Q' R
6.C
9 K& h$ }7 O+ B, j W7.C. x* d# ]' ]0 @( I5 [
8.C
( F0 Q. |1 e$ u. X/ d) d9 N9.D$ u+ B# s6 `* T( |; f
10.B
' m$ q% o7 i' ]/ b) L( r0 g11.D
. | i* o9 l! C2 y& \7 e12.B
" O0 s3 G j4 N4 x) t13.A, }" K9 n% s: e- c( B4 Z+ r
14.D- W' B2 d ~! x- x+ G
15.A) V( U4 D$ @7 H+ }
16.B- G: W" v3 c: d' I
17.A% S/ T6 r/ _* |: d+ A* o
18.D
P1 M) n2 y9 z19.设计模式
% j5 G' B& ^! M6 L/ W- X4 |% m20.D
) I3 q t) k* v
& h% R+ F+ F% i$ K; m$ x. @ g# X& X( N+ O. Z/ L5 N/ a
9 r9 m$ {, W$ I" G6 f" P& h
答案详解
/ p: g# p* w8 `9 B3 L$ h \- X) t& n5 b- w
1.类是对象的蓝图(对象是类的实例)。
4 L% t( v" E( j* D" Y1 S% X0 i& U9 R2 m A' w
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。$ ~6 @4 Z/ o, H
6 h) Q9 |' V8 ]( E0 V) B r3 W/ N- p
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
% h( ~+ k& e5 }& R c. O
* S) Z+ R; `* a$ x1 C* a4.单件模式可以限制一个类被实例化的次数。; D- f9 L6 r2 \+ o Z* o
4 X* o$ u0 S ^3 K) |5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。, f8 t2 d1 z4 Q# `
& f5 Z) `7 w7 \% t# v5 K
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
1 L9 r3 K J1 B4 c1 {6 e/ M2 W* W; P5 L5 H
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
& b9 X4 Q5 E" ?. M) p% p9 v9 Z. q. i; F/ j
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。4 K( f! Q0 G- }: L0 b" Y
% p, J) B* G2 u4 R; u9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
5 s- f# X8 P5 D/ B1 O4 {4 x2 w8 @8 e% D* m5 J$ O R C& }
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
2 c8 }) m) ~8 v& Y' ^ B2 _+ P: j( X% S* u7 U8 U, _
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。; w$ d2 \6 Z, q$ n3 n, m
3 d/ C7 G1 e8 a7 k
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
' K7 H. P' E8 E# P9 L
6 j2 e8 R2 T D1 Q w, a i13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。7 B' p! n5 ?( _8 t, j# j9 j
( o* n5 U- E& t$ e5 T14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
/ g4 [& |( n1 b0 b* f回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
6 h" E& p" m/ @0 @( }0 n' u' H function reduce_fraction(&$fraction)
x/ o9 M* \7 l4 }: F答案是D。0 K2 M& Z4 |9 M+ R8 Z( ]
0 L$ r/ J2 G, M- c15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
( f8 C* h* [& n" O* |4 X) z
3 b, T- i- ?& H7 _# n; |5 k16.没有。PHP4只允许声明静态函数变量,没有静态类变量。6 T6 w2 F0 X: T v$ P
! F5 c0 b7 S7 e0 [' o! O9 X17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。/ U5 c0 P5 T1 T5 q I
D9 Z8 W2 A' Z1 p6 X
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
3 \" y+ R! k8 c" [. d _% Y
: Y/ b* q R0 p- r: m9 L& Q19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
, I3 u+ ]% S+ J1 }5 F% }& J1 Y8 z1 w2 V; e- m* y9 }4 z) F2 F
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|