|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
1 R- Q) \- P8 s* L# Q) N4 W6 l1 cPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
5 q8 f$ T8 D) [: p本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
2 J5 @- j; s, {' ]* \
& t; \7 X) S# M9 V; a问题3 R( w' Y0 h J0 L* Z1 [" }
! I7 W b) t' x% t7 S
1.对象的蓝图是什么?5 v7 P: B: N' m
' F- c q; K6 l$ i
答案:____________ K" ~$ d9 v- H; R
! ^9 E6 s( M& I" C
; L! ~" @/ R* N2.以下代码执行后,数组$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
+ e! O/ c# h, ~' t9 NB.b
2 ~! P7 `0 g/ F1 f/ VC.a6 j( z, {# J, g! A
D.d% b/ @) k3 z# G' v
E.e
& ?$ @7 D X; e j5 E+ L& m9 p2 e2 G1 w7 F8 ]( r
4 t% S" c0 l; b: k0 f `
3.如何让类中的某些方法无法在类的外部被访问?
$ Z# u' \8 F; q* y! n. Z
; L$ B6 N# K" fA.把类声明为private
3 G$ w0 I5 [) M# l kB.把方法声明为private
7 ]% l) A) H* d6 [# C/ DC.无法实现! ?) d; Y% y2 ]6 f
D.编写合适的重载方法(overloading method): [$ E \5 ?& l! r! G+ `
3 \1 K5 R& V9 A5 h- b: F
; `" x( b1 B# F& J6 g @4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
' U1 m9 D+ K. r& `* w" O+ e# \" A- ~) B, Z2 ^
A.MVC模式
5 }5 W( |0 u9 h yB.抽象工厂模式(Abstract factory)
0 j8 _- f2 K! [- h3 Q* j& Y' T5 kC.单件模式(Singleton)
6 g# N& j) Z9 u2 M; mD.代理模式(Proxy)
' B5 X! ~$ }* ?- r: LE.状态模式(State)
! j6 V" K5 W5 z4 N2 r" I, p9 y, }: L W$ l
+ p; ]& h: v* ~
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?/ k6 ~; {, h# z0 j! d ~
+ W0 D, a6 P, {5 y/ D6 p$ |7 x0 ~A.1个( D( V' ~/ R# B3 K/ y& Q
B.2个
& O* u8 k% L# fC.取决于系统资源5 V0 s6 Q" B, Q. j4 D* z5 M" L
D.3个4 { Y- [ I7 v$ \
E.想要几个有几个
/ l0 f8 p0 T( @) d0 v" e( W( V' t/ L+ W0 _
2 A1 y+ ^- y3 f4 g6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承8 v: M- w: P% _* h
B.接口
: B( {8 P9 k2 D! e, M% RC.抽象方法
2 |6 ~+ e) _3 B2 j7 a( _' d+ ND.Private方法8 f: Y2 ]! {! u0 ?: n. U, ^
E.函数重载(function overloading)
1 c) d U7 g+ d6 [8 C
5 j3 D8 J7 h7 Y* W! T
3 s$ e3 H) d4 H) K! o7.假设定义了一个testclass类,它的构造函数的函数名是什么?6 y% A9 q5 T6 }
7 V! [. q: W! l9 R$ UA.__construct
2 R' F9 u4 q2 k& n- DB.initialize. w( A$ G1 ^, g0 ]' c' O) ?2 `
C.testclass
& ?3 v! Y2 X& _, d Y+ {9 b7 X1 Z! iD.__testclass
) L. q j& X' ^* c4 k. KE.只有PHP5才支持构造函数: \) f3 [% ` Q
6 a* k; R @: Z3 v' q" j4 t
9 l4 y5 a1 w& m3 e: \8.一个类如何覆盖默认的序列化机制?# K4 w( h/ S2 [4 |8 T/ t$ B4 ^$ n
: m& i4 J, k4 a
A.使用__shutdown和__startup方法) v6 I; h; S& `2 F2 y: @. W
B.调用register_shutdown_function()函数
$ T3 q3 e5 p) G/ \+ A S* B U& kC.使用__sleep()和__wakeup()方法
% D! [$ s6 |1 `2 T8 oD.无法覆盖默认序列化机制
1 h1 J2 D. a8 D# Y- HE.使用ob_start()将类放入输出缓冲中
* R& t% U4 C# Q
" x. s" U C+ h" G9 N/ Q
3 w2 e' I# Z2 A. ~9.以下哪些面向对象的概念无法在PHP4中实现?4 {. z l+ |. r; R. T, C* m
, y$ l) V9 E) u@抽象类6 w! w1 o3 z d
@Final类2 P) N( L9 {* t3 ]+ \2 G6 i: \
@Public、private、protected(PPP)方法* W! _0 k: I) T
@接口
) w- m% C5 X" H8 ^4 r; D! k" X! r: Y5 g x: S
A.抽象类
" y+ M5 d2 J* I! n6 W" JB.PPP方法5 h {- K' G: `. a& I
C.PPP方法和接口
. {' Q- M; j# l5 s4 c$ eD.以上所有都不可用7 Z) F N7 t- S
E.以上所有都可用
3 g9 t: {7 W" g! i+ ~2 f) x! T) b* t# d9 I$ i7 ]
" b) Z) C8 P& p1 M" R10.如何在类的内部调用mymethod方法?# B" \; y7 Y" Y f
" [0 H& a2 T1 ~ g XA.$self=>mymethod();" [" I6 F& v( p2 x
B.$this->mymethod();1 u6 M0 Z7 p; F5 q% @+ |
C.$current->mymethod();
3 i, x3 I' S9 G) V5 i& I3 u7 hD.$this::mymethod()
; @4 o& q/ M+ V- f: L1 y# sE.以上都不对+ i* \5 R- h" r% O* ?9 S
) Z/ p. }/ h& `# r! W
1 U. M" m5 I9 k B: a' 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
- |. n8 s6 b4 f/ l) G. ZB.Null
0 Q6 P" z/ M6 x8 O5 z7 SC.Empty
# J; }5 S) b7 X4 ID.什么都没有
; W6 g. h1 ?# [! i. C! i# O" nE.一个错误, m! E7 C! K* J$ w) Y3 [- D
1 i% b$ X! V+ | v! `! R$ ]& p
6 W6 w+ [: p+ w F. o
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.107 ]& y5 w6 I9 U1 Z
B.5 q" n( e8 F* v- v3 ]$ K8 b; v& N
C.2
0 Z* ]! C" b" T# \: D* eD.Null4 b3 ~) ?$ z+ F3 j) r
E.什么都没有
, ~8 B% s/ m X
+ E6 w# _+ V6 I* p
, m1 h( {! v) ]. Q6 }3 W13.以下脚本输出什么?-
- <?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
% O6 K9 b1 U0 y# eB.10
: t% W" K8 w" _( n3 p) JC.什么都没有6 T9 k4 s/ {& f; {, J& H: ]
D.构造函数将报错
7 l' m7 U) B- Q( C. r9 v0 m3 _E.510
4 W/ t$ s( m) _2 O6 }9 o& b S* L# o5 j8 U7 G( R
9 B2 w# A( R$ T" L14.考虑如下一段代码,执行时,$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函数必须返回一个值* r( |* P" f3 P, n
B.reduce_fraction函数必须接受一个整型值
6 ?- Q. B9 L9 }9 k" o! g4 H [C.gcd函数有问题& N& t" M. `+ a7 V0 o) V, {
D.必须通过引用的方式传递$eight_tenths对象) s% B# K' b& Y& S( o2 N4 L
E.对象的实例不能传递给方法以外的其他结构。
& i/ g2 k" x S# o% m& s8 X: N( u
3 F9 `9 S$ U2 z$ z5 f" N& |- S15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
2 _% \1 S, {. a/ b& L+ {B.生成myclass的实例并调用mymethod方法1 D7 g0 D; y1 ]$ m5 g1 _! m5 K
C.产生一个语法错误0 C+ B* [ E6 ?% M
D.默认myclass类最后被创建出的实例并调用mymethod()
2 q* Q2 g) b; P H# E# e' {E.调用名为myclass::mymethod()的函数2 X. r! \9 @& p7 Y# t9 S
$ F" c" F/ \2 `5 W
2 _' Y0 I: R8 l" }8 \% r7 P16.PHP中有静态类变量吗?+ u3 S- C' v6 o- s7 G5 D
$ {, r7 K/ v$ p3 pA.有 q( Y# t( v1 M4 N0 \
B.没有1 G4 Y( X7 U, K9 i+ j3 y
6 g3 b$ X1 a; F6 O) S1 V/ J' g
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
" P! N9 i% w& b0 `; |. @B.2
1 L q0 ?- F& x) q! E1 CC.一个错误,因为没有定义a::$myvar
. L6 p2 W4 _0 b9 O& U" dD.一个警告,因为没有定义a::$myvar
- V$ u- F6 x9 B2 RE.什么都没有
5 \. q; }9 ?. E& S, f0 v
* Z+ m# R# [( Y* V! p/ t1 c7 V& G% q+ X' G" e0 r; ?
18.如何即时加载一个类?8 t6 s& m; ~7 E- e: e2 p. I; z/ N
: E8 n4 O* `& r$ B0 i1 J( N
A.使用__autoload魔术函数
( P8 P' N# U$ J$ f; P$ OB.把它们定义为forward类* F, Q' z- i. p9 w' Y7 I. d
C.实现一个特殊的错误处理手段
: o' [0 c7 e }- w# U3 DD.不可能+ M1 e: A. D$ D3 U
E.用有条件限制的include来包含它们) M" P |) _( G! i- N4 E, m
- M7 }7 W3 o2 s/ {( X: Z" ~6 B u( L J+ F0 b* U. ^4 P! h# q) J& r; I" F
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
6 ^, ?7 T6 S4 H9 Q* U' N: H
3 L' z, i# V2 f/ m( b 答案:__________/ s: q* C9 \# g0 d2 i
/ D6 P+ ~/ L) W
8 k0 D/ ^( z7 S( S. m2 J% I20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
* Q* g1 e+ X* B; N N/ X/ K" ?+ IB.一个错误 g( x3 _' y' c) x% t
C.一个警告
/ y9 K1 D9 q6 @. \D.什么都没有
2 |- I( ]0 s" M% M
, r1 \5 l( Z }( Z5 Z) k0 U1 `) R9 q* n6 m6 r
9 b+ L9 m6 X: t0 ~! h' v答案速查
, `5 Y$ ]7 T0 D) j1.类2 `4 |7 z! U/ ~6 d. F! H
2.BCD' { k5 C: \( M9 i4 D
3.C" H4 d9 v" g4 V- W
4.C
. t4 ^# _8 U7 o3 U$ [6 q- e3 S5.A; U9 k" R. h+ \ t! i/ V
6.C
5 m" X0 |8 c6 x3 k6 v7.C
$ b: t+ {; X+ j2 s2 j8.C
, U( b( A0 K" p! e: d& J/ J9.D3 J0 z3 d7 K e5 z- x
10.B
9 U6 Z6 q: I* w11.D
( P9 k) N1 e8 @8 @12.B% l% B7 E6 K I; x' \1 A1 `0 M
13.A" {. S% i( V! S: K* E- z0 z& N
14.D
! R R+ H2 t& n1 y7 C6 D* N% G15.A% {3 @( v7 {% b" t. C$ C* Z( M: k
16.B
7 }# ^) F) g" G, j; E: y6 J( F17.A- ^( R: B [, r6 w
18.D
! ~0 f7 R- f- U6 i& r19.设计模式6 A% Z" D8 |1 r
20.D
# o# b8 J* I' l: C3 {: S
9 Y" Y( E- ~; ?4 ^! U6 q: S8 x4 I' a2 m- p
0 z4 F0 y0 }: X4 }5 N0 x! b% r5 ^2 Y答案详解5 X' {; d6 d9 a% `9 w
6 s4 V& _' V- A5 a: x1.类是对象的蓝图(对象是类的实例)。
/ f" a: ?% [: j) P: d" d% N4 A0 {( _7 Y. M
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
4 {3 R; ]- T! ~4 i9 M5 ]8 v" Z; |6 b X( r% i n" ~1 k) {
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
- ]2 m7 T9 h/ c9 O [$ S$ b' e7 b6 ^' k; A. u
4.单件模式可以限制一个类被实例化的次数。+ @0 B" j1 D+ R8 W' g6 |# I6 r
& r7 p2 A9 w- G9 z& M" F6 E5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。: B% t! [8 R6 |" l7 S! J1 Q8 W
% f: l5 b8 L- u; p3 J2 U% \' f$ M6 G: P6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。8 I* T( ~1 @9 j0 [$ @* U; q, S# i
S4 f2 W$ F' E; G6 E
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
* j$ m) m- U0 u4 o* s( n1 y2 W$ ~6 m! Z1 f
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。/ H- f8 w* s9 o( W0 \5 n! x# @
) N! b; ^/ I3 R" j# S) H" n9.PHP4中没有题目选项里所列的任何一个概念。答案是D。' h) N; `5 |9 [0 Z" t
! ]* j& q4 A! n2 i
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
/ M* P& b9 s* H5 x7 l& W/ [. J4 G1 P
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
5 F; G$ V) R+ U: H) P8 y. ]& G3 i- n4 n. r
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
* @3 i1 b, _& | Z( B# [
: d9 i/ }7 c' k$ q2 L13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。* ~ j! l F& S; h5 E
+ _- x* y! k) A# D3 l" d
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。1 m9 p$ G0 }, d
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
, W: H; Y$ `; p3 a1 }( d Z" q function reduce_fraction(&$fraction)
5 a9 ~; A; P7 B' H$ | c0 {答案是D。
/ B! B5 r5 Q, J! c1 X8 J5 M
9 a! f+ X9 K$ X W15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。0 W, o) p$ ~1 [% w+ Y
& v& T& p0 e; D$ V8 P& Z( H, s( o16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
/ {, B' r& ]' Q1 i* Z3 ]6 p
3 W U4 |1 |/ C, j' q" m17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
' L, F0 k4 u, e$ M' I+ `* {; e0 B3 ^& }" D. y
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
5 d: c* m7 T+ d% R/ {+ x8 q0 {9 C- k' |& {
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。. N. r2 E: W, |9 m' i7 J5 G
2 X& f1 k# N& a0 _20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|