  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
! r i7 j) f- y( @! k8 s. HPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。4 L- H" V* b# X5 ?! W2 B
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
9 \7 E9 i6 G! Z3 x9 h
8 g }6 B8 q: E( Z问题9 Z5 k% B. j9 m/ Q9 O$ C) J, w6 i
) I) y: V, O% ]; r3 D% P8 ^) d) n1.对象的蓝图是什么?
3 ~9 u1 h4 c) S Z' e! c- o( ]) `+ s a/ V9 } @
答案:____________0 I4 Q9 H# ^/ E0 m9 I8 ?
% k& a4 Z) ]% L; x& t
0 T4 t! C) Q& \/ ~6 u: I2.以下代码执行后,数组$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
$ K* Z# A3 i5 T9 y1 E( RB.b a3 O9 W2 t: p/ U
C.a
& N6 L- I! D7 W6 Y6 cD.d% g8 w9 b' u0 x8 f
E.e0 w4 V4 j3 M. u7 l! x
C4 ~+ h3 b8 C W/ A" v0 N0 W C9 @( ^8 q4 _0 U/ R0 a2 m
3.如何让类中的某些方法无法在类的外部被访问?
8 b. a& {" p5 h& o+ R% p: a: x$ Z5 d* q3 b: w" P2 [3 u$ ?) ~7 o
A.把类声明为private' s0 D% x: ], U( @
B.把方法声明为private% [. [7 j9 }8 ^
C.无法实现3 h* B# `6 {/ e
D.编写合适的重载方法(overloading method)
' p% ]- r, @/ e5 C. N, o; y3 U& g5 A9 z+ C' x p) U# D
3 S/ I6 ^1 F! ?7 l* @: T& i& o4.哪种OOP设计模式能让类在整个脚本里只实例化一次?. I2 Q1 i2 m) j7 {
: s5 u+ w- H7 B
A.MVC模式; q! N8 S) V' p
B.抽象工厂模式(Abstract factory)
) I+ t: N% a0 r4 D |C.单件模式(Singleton)+ Q5 x) o- l4 m' ]8 u
D.代理模式(Proxy)& L+ h# y* j2 I/ Q7 c9 ~
E.状态模式(State)
! J1 K @$ o+ z- N2 T3 y
) }+ m0 h5 ~, H: e& Z2 M. a, y: E6 k1 w8 o! o
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?9 p0 H, l/ y% F, p J
9 Z, q, G. I; W# L
A.1个
0 r: Y. F) B# e+ t2 LB.2个) W. J) {) s: u" c) t
C.取决于系统资源, ~" ^3 k. O" O6 R! M
D.3个
5 g% F6 r8 }! W6 C6 t9 C! `; Q) TE.想要几个有几个6 P% [* l( o% n$ U5 l/ I Y7 ?+ n
7 K+ A6 s4 g, C1 n1 V" m' S4 y0 e [5 w: p: G! Y7 R# n
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承2 N" E" i% P- `( f- ?/ q- ^
B.接口* ^$ k. F% W- Z- F9 a, V
C.抽象方法6 E* \- e) A: x
D.Private方法
: F7 h; i' X( X( ~$ u1 H! r2 m( QE.函数重载(function overloading)
2 i5 z, @3 [/ l# m/ ~/ b5 X8 ~/ ~' F& {: P
( |7 |3 Z; i, Z0 T
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
) r9 x& h% A) t/ n" z% q: c* E0 o
* F% F5 L i! f; e) N9 IA.__construct7 L1 e# S s- c5 [1 } D1 \
B.initialize
V4 t0 h. e' V5 w" E4 c* Z1 t E. cC.testclass
- U# o) L' H, `D.__testclass
5 L) a8 w: ^/ U. BE.只有PHP5才支持构造函数
2 C1 S& j( b/ T, p
* F' @6 i$ @& m" H' p4 O" H6 `4 e9 @% f* h- P
8.一个类如何覆盖默认的序列化机制?
% ]7 H# Z/ t# ^3 T; h
6 B x" W$ W* h2 z2 KA.使用__shutdown和__startup方法
2 v, t, x" Z G% U2 i$ P" F" |B.调用register_shutdown_function()函数
5 N1 b# u. e4 s" hC.使用__sleep()和__wakeup()方法
2 O) M4 B( l0 c* R7 wD.无法覆盖默认序列化机制4 P) b/ K9 i; d8 c
E.使用ob_start()将类放入输出缓冲中
9 O1 t- b- l U
$ H* `7 ] n5 e0 ^- J' ~1 U/ G' t
3 W i ]1 }# Z9.以下哪些面向对象的概念无法在PHP4中实现?8 o) S% o; |" \9 N7 a
- n" d, V; z; Z5 l1 p@抽象类' s5 j- C, r9 l3 g* L" h1 w% @% R/ c
@Final类- i' D1 l& v2 F% b# T8 ]& P/ h
@Public、private、protected(PPP)方法 H6 I/ j- w, b1 A* e5 |3 D/ t: @
@接口
9 V/ M; |- Y* ^$ n6 Z8 I
0 d6 C4 I( ^% k) ]A.抽象类
) b5 o9 K! J9 z5 {* e+ e! CB.PPP方法
. K8 G) K1 x. N( GC.PPP方法和接口
, g; ^% C: `- W" [" n wD.以上所有都不可用
4 K$ a7 c$ ~% g$ f) JE.以上所有都可用$ U$ ^4 h0 w/ v u2 ~: h
2 K, W, d- x$ ?! k/ O* \
: w9 S% F2 |4 w, r. O% G
10.如何在类的内部调用mymethod方法? t( _4 A; h6 M* f
7 e9 V' w+ B7 A# e. fA.$self=>mymethod();' {9 X: U" n9 P3 v0 A& p' H1 Y6 S
B.$this->mymethod();
% X( q0 p8 N$ n; ]# |C.$current->mymethod();& x& |9 J* A' ]
D.$this::mymethod()
) m+ V, @6 l+ [; q9 z+ d# vE.以上都不对
|) ?$ Y- [( e, K% y y3 j" r* l! O& w# g
% x5 }( N( |# X! i8 ]' b: O11.以下脚本输出什么?-
- <?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+ O! m7 P h4 ~6 R- r* P+ @) k! o
B.Null9 i$ Y$ } l7 l8 i, i' I ~ X
C.Empty5 ]0 ?- A6 {8 o# K. G9 B' o' [
D.什么都没有$ Y7 K( O. W9 Z% T6 q
E.一个错误
" [) i' {5 j: C) S9 m4 b! v* j& G
, C4 v% \9 [5 T( I; C! {
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
- j! _. c. D" Y9 l8 P& QB.5
: J- [& R2 D: U( G S! x; DC.2
' W9 Y9 w4 R' M, C/ D, P* YD.Null/ T/ v' W6 ?$ E' o
E.什么都没有
' [5 o9 o9 Z/ g9 y) ?4 i9 n$ Z& b0 v. F: g0 ^0 o n
2 T' M" [. A% k8 X3 J13.以下脚本输出什么?-
- <?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
% H+ O2 [" X( W. B3 CB.10
3 O$ D% Y' W N/ DC.什么都没有
7 l8 J! y+ M2 s% @- F4 U' RD.构造函数将报错
" I: ?5 t! V( j$ T3 QE.510) d7 ?; A2 }) y+ q9 n
( O# U0 u# \( ?
- L" R3 Y8 i+ 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函数必须返回一个值
/ U F( q: C0 s* [. uB.reduce_fraction函数必须接受一个整型值; T3 q7 @" T0 r4 u4 q4 _4 j, [
C.gcd函数有问题 M3 z2 d- j# `* z2 Q9 S$ ?7 n
D.必须通过引用的方式传递$eight_tenths对象3 A; \6 ~+ c* d9 {
E.对象的实例不能传递给方法以外的其他结构。
" c( B1 F% w/ W& N4 B( Q! {1 m/ X, z' ^3 p$ w0 d b3 V
: f; z% `% S' a+ I9 T( Y+ y
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法4 H& C) I4 ^" C1 [8 a l) k4 P
B.生成myclass的实例并调用mymethod方法# I N! |5 ?* N# y' ]; r7 ]) \
C.产生一个语法错误
@( _7 L7 e" k; q7 Z$ C, y& cD.默认myclass类最后被创建出的实例并调用mymethod()" ~+ D5 N$ K/ C& N
E.调用名为myclass::mymethod()的函数
+ t+ X$ m8 w, @* j5 l/ \' T: @% J; |3 z' k2 ]1 r
$ S% A/ Z1 ~) B# T8 m! t3 C16.PHP中有静态类变量吗?
& }" K- O; `/ H, {3 r* _2 H9 k* U( d; s
A.有0 c- d% q$ k, J3 J2 u
B.没有0 y% `- _/ p, ]1 ]4 p) s
; Q4 e2 M+ z+ \$ J/ N l
4 d( ^' w- |" U& m# y: h17.以下脚本输出什么?-
- <?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
$ S8 ^% g1 Q5 e8 K2 uB.2* Q0 A8 P, U, }* e4 c( |1 S. O
C.一个错误,因为没有定义a::$myvar
& x, p0 [3 N# {6 i" eD.一个警告,因为没有定义a::$myvar
y6 n1 d m) h- J) h) A. ^7 A9 lE.什么都没有/ C, \( l- W! m9 L1 F6 N
1 j8 }9 y7 F; z0 z1 s
8 t5 ]0 h) Q/ L& I& n18.如何即时加载一个类?! R3 i7 n% M, {( U9 R) d5 w' t, ]
) n+ r* y f$ A1 P1 A
A.使用__autoload魔术函数- X) K }5 C. @$ T6 H9 k9 _
B.把它们定义为forward类
0 |) Y4 t; T i! a7 g! OC.实现一个特殊的错误处理手段
) q$ `; v7 l, C! W4 c& E2 a) iD.不可能
) T- k/ i6 Q$ v5 P3 ^% zE.用有条件限制的include来包含它们
* c: q% V1 _( O9 c/ O
% y+ e4 c4 j4 W, {; b/ t8 Z1 x1 E9 R9 K) m% _1 `
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 g6 F" n; a6 `
7 r) k1 B3 z4 _) s7 m$ X& n 答案:__________; p% a" g) P* K
1 l2 c* W7 d6 d, i
, x: n: C/ L) m$ I f20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
7 F; c% Q/ ]' R3 Y4 f5 zB.一个错误, r) r; P- q$ O
C.一个警告. o5 J2 U, l8 X) l
D.什么都没有
# a! d" W0 H6 s, l9 \' i# w
0 F6 D9 p: w4 g' j" d# M3 T( `6 X: J5 L [% ]
; d0 N! H; T8 N, w5 D+ S
答案速查6 Q2 R$ C0 A( @0 M* s7 K1 m; Y
1.类
. F2 z4 o8 P% [# T2.BCD: z* i! u1 g' I
3.C" ]& j/ A7 M. h
4.C
! b [& x; H& w' i) @ Y- K5.A
% _0 ]+ c( K" @/ B/ V" V" i6.C
`$ ?) h' h4 \% F3 b7.C C6 N- v G2 `1 S
8.C1 N* D# A5 o! D* H) M0 M; k3 t
9.D. c) i$ U9 {9 b8 q# K! x7 o
10.B6 h0 Z; s. u2 k/ `1 L" N& F
11.D- ], a- [2 P9 z2 b1 u: q, u. u2 i
12.B: y1 y! l1 m+ Z) \3 z' `& D
13.A
9 R2 s5 T% V" b$ F% a5 z* Q1 i14.D
5 ?9 z! F# R. Z+ r2 n6 n5 V8 S* T15.A
& }# B% x5 K2 c' {1 e16.B
& j$ ~$ P* h; C2 u17.A+ q7 U4 J, Y% o: A3 ]
18.D
' {( n+ T' s! y$ C: \7 O* E, t19.设计模式4 u* G0 v2 Y7 y( t) ~# X
20.D
# H$ M! N; m. ?$ }6 ?
/ N0 {& U8 a; h% H# ?) U. q
0 w; ]( C) z2 K% Z- o9 m0 Y
+ W; Z1 ]' \0 e答案详解
3 F8 M$ a. Z4 y
, R, w! U' A- v, d, q" T$ j1.类是对象的蓝图(对象是类的实例)。% j8 h8 H2 j }$ J \& K
+ [+ j9 j0 K$ Z
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
! @' F* c* p$ p" ?' @; z+ g: E7 b) M5 }" p. J
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
* v$ t- c7 w2 k# P+ Q H! A7 W' d) E9 Q+ r- r
4.单件模式可以限制一个类被实例化的次数。
4 u6 ~; h# a+ }( G8 K
9 D3 o3 W$ ^' m% Z" G) E+ h5 [5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。1 f' _. k: h8 E: K; r
+ J9 J4 n& |* n% Z: K$ P6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& d( g2 `) i) [' c
! ?3 N( V$ a3 F& N* u7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。; Y+ t' V# |1 L# n# ?% T
6 ?* x4 |$ M/ D8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。! B5 I' L- C9 o" T8 }0 j* P
# y4 ]' ^ p6 s* F
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。2 D0 T3 x( I5 P. Y
: Q* D8 Q# F- b' h' g# d10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
( U9 n# G! l$ {! ~9 n+ _' O; f- Y
! D8 R" a4 Z; j1 `+ A0 E11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。/ o! C W, e* i. x9 P/ ^& H
1 e1 n( ? @1 |) L: E0 a12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
$ Y9 W9 P- R6 q2 E
! k( P8 _2 [# v5 }' G. g13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。8 |5 v z9 x$ q, j& r
+ P. P1 s+ J1 w t& _& j. B
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
6 x) E2 O- \5 z. R8 U1 G0 f8 m回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:& ^2 z( N- b9 s, j
function reduce_fraction(&$fraction)$ s$ S2 v: z/ ^: t) _' U q
答案是D。
3 ?! V% ^" I& o7 a8 ?, j. S# u# f+ y5 v& L$ _& Y4 ?7 ]
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
* E# q. k8 F9 O( {- K9 K6 O1 T& b6 O1 }7 B
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。+ c" a6 ]% y3 ?# d! c$ y/ P: n5 \
1 \% R' v' e" }0 h+ s
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。7 h5 N1 g% n9 H) U. d6 P; ]
, b; J9 A" ?3 _3 c3 a" X1 c: |9 x9 Z! g18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
8 y+ @/ p" B' g4 g' u5 {. R W- D$ o3 g& s
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。3 I! B L, ]& G2 N) _ ?
, C8 n" Y! K5 ^% X5 z% C20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|