  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14171
- 金币
- 2376
- 威望
- 1647
- 贡献
- 1324
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
- G- Q e- Z3 E g/ |* G" iPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。& ~, ^# u5 S. d* c" a
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
% C# A! A h+ N9 X3 W1 u2 ?
$ Q) _# k) C5 X9 ]9 |5 u问题
% A/ k6 ?2 U) A2 M: \
' H2 _! W5 H% ~% @7 v1.对象的蓝图是什么?
7 Q! P- Q: u% C7 f/ f0 Y' x
# o( N: O9 }/ `4 Y2 V* {答案:____________( E7 ^; g2 p d& Y" k
+ I& x4 {" n3 b, ]
0 p$ Z2 J; n t( _( M2.以下代码执行后,数组$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.c4 ?5 B; A# i+ E# ~
B.b) I+ r: i. H1 V+ ?% L- g" A; ]
C.a2 K: {0 z% H5 q- l' `' |$ ~, N
D.d
& x( \ v0 R% |) \$ WE.e' ~, D% f6 d# r. }. W
+ n2 U- |/ D& |9 p o
/ i: S& _4 C8 O3.如何让类中的某些方法无法在类的外部被访问?, X8 A. j8 J; b5 F
+ n. Q3 D" A3 X8 t: W0 B4 s4 KA.把类声明为private
" J5 f4 v' Q0 @6 a$ K4 {B.把方法声明为private+ w' |& @" a# a" c7 U6 s" D" N
C.无法实现
% ~9 P: r6 p v* ED.编写合适的重载方法(overloading method)5 J8 ?9 U) K# [# L2 W
4 a, A4 A, L* _, `1 A
# _! ?! X/ l# Y' Z4.哪种OOP设计模式能让类在整个脚本里只实例化一次?8 a4 D" D, P' H4 m/ }, o
" j$ r7 r: m/ b' w! @. d0 U* V- ]
A.MVC模式
1 X) e- _* O7 U: N: ^4 K2 s7 UB.抽象工厂模式(Abstract factory)% W, s7 P( ? w! m, F' B% [
C.单件模式(Singleton)
) {4 a; a, { E9 h2 e" \( g: ID.代理模式(Proxy)
0 B2 Y9 O3 I l0 e; G5 F8 lE.状态模式(State)
' v& o% K3 N; n! T$ d; p/ m" v
" R; R2 @+ c8 O& @6 l
6 `: c B; O& H5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
/ K. [2 L& W6 L7 `! b- p+ X9 A8 p
: L1 X+ K+ ?7 u$ I% `/ \, I8 e5 dA.1个( {4 n( w8 N. X8 S1 R
B.2个, a( X6 S e, ]' E
C.取决于系统资源
+ m- {5 E2 u" `# H) d3 ?( I$ p9 O3 uD.3个; ~0 R8 C9 w1 k0 B0 f
E.想要几个有几个
! ^! N# ~% m# e; p$ D
0 a7 s( U% a1 X% `$ ]! I) l* H
) G' a& ^: {: P# E! [6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
3 f( P9 Y: b" r0 D, N, r6 Q/ s! QB.接口2 B+ I$ j U( d0 y
C.抽象方法: Y; I$ a# r' p( Q
D.Private方法8 I+ }1 l8 c7 f0 a4 |+ a
E.函数重载(function overloading)
: r! o( y5 e4 O. J
3 R! ?: o+ J# F0 m m W( H k5 a9 L( H: N1 [5 V" O
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
- y7 h2 I* j6 b4 S8 E! f
( ~8 l& Q, D& \9 HA.__construct
7 V; ?! Y/ O6 E/ M. b7 ?B.initialize
h9 d% j( ?% `8 OC.testclass
$ [9 [6 b, b9 A* N2 e( @D.__testclass4 T, f( n+ P/ n4 |4 _1 D7 f
E.只有PHP5才支持构造函数6 s0 a/ o3 V, O* _
/ h6 R9 h5 u* T6 i' ~9 j: X/ Z7 _6 V' ?9 f
8.一个类如何覆盖默认的序列化机制?
" C% ~6 Z1 A! I3 z* U, r) V# o% ]7 r
- ~3 ^$ N4 `# f, SA.使用__shutdown和__startup方法
. l/ U: o" P* j; _1 _# Z$ I y AB.调用register_shutdown_function()函数
# S( W! @ A3 w7 f/ A1 YC.使用__sleep()和__wakeup()方法
, O+ M# B& d1 T- ~D.无法覆盖默认序列化机制; R9 s. F/ }' ^( R7 ]3 ^
E.使用ob_start()将类放入输出缓冲中
' f" U5 x/ s$ j; K' q% @; Z) D) U$ x# t0 m" g- N, R% p2 \
' O) J2 z. _) P$ A/ U/ A. P5 }9.以下哪些面向对象的概念无法在PHP4中实现?
; q" Y _! m' {" L" h5 h$ E' L- } j& @ C8 r$ k6 W @; I
@抽象类
7 R3 k2 I- O4 A1 A@Final类 `$ C- J# |1 }
@Public、private、protected(PPP)方法, Q: g- t8 } U9 b/ F
@接口; M& \/ o7 X d4 c- A
1 F- x( {5 S2 J" ?A.抽象类& c' o) n, Q. Q) X9 z
B.PPP方法: B2 ~1 i1 y) {* E8 J H& ^
C.PPP方法和接口9 Z8 ?( V- ^5 C
D.以上所有都不可用
3 Y2 U. ~5 |: B+ aE.以上所有都可用
& b, D# C J& s1 t2 K A7 W0 x
4 i2 c a; P" [% @" f0 Z. {9 Z+ _# O
10.如何在类的内部调用mymethod方法?
: ^6 D' q+ J# b/ m! H
& T |& K; E4 J1 j$ r& aA.$self=>mymethod();
8 @* l; r5 h3 N4 a3 T7 ^0 WB.$this->mymethod();' y( B% W/ y2 c
C.$current->mymethod();0 Q |3 v: P1 ?6 Z' R& K- o
D.$this::mymethod()1 t" ]& n) H! h$ p: b6 Q/ O
E.以上都不对
+ ]' t _8 x7 j( A& Q! I, N* u% R+ x- \7 l4 U% r* Y+ S
& J3 B. w# A$ F6 P* _+ H3 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$ y/ t# a( Y
B.Null- T1 {. }( D9 t6 L, {7 f' Q9 Y @
C.Empty+ E, S8 T: N9 ~- q8 s0 ]; E
D.什么都没有
3 P! r6 N9 `% QE.一个错误& e5 N* @: v7 F! K/ O# `2 {
8 ?. t& C9 x( [& L" _, c4 k0 A
5 E& r7 P" C. |' H; ^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
4 ~8 h" |/ L4 O, a' jB.5* F8 I: _. a% Q/ D u
C.2
% S% l* O3 a! [& yD.Null- c3 A3 i' j/ Z
E.什么都没有, T5 E' r; C, H7 d, k
# w" [1 p/ q0 W3 | l- e
* s7 y2 Q+ o3 r9 V7 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
+ k9 p+ y0 e) C5 f- cB.106 X4 \3 F% K) y$ J9 F
C.什么都没有
4 i. ^/ j3 \5 f0 ?6 F- c$ QD.构造函数将报错
' ^# x# v8 T" o. L$ o+ }/ dE.5108 c: l8 [& B) T2 j2 P
9 C. Q2 D) h$ q3 o- B
- |' `: i) X) [* L- B5 G
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函数必须返回一个值8 s+ C- v3 Q9 f! d9 R8 D, w& B' c4 g% r3 j
B.reduce_fraction函数必须接受一个整型值
, ?0 j( O- z/ VC.gcd函数有问题
% r6 c _* r' [" q6 E1 DD.必须通过引用的方式传递$eight_tenths对象
: `( B" C8 F* Z9 E$ u$ IE.对象的实例不能传递给方法以外的其他结构。
- A" z( y5 f( {% D' F7 R5 T
8 X+ O) }6 R# p7 m' v9 {/ v, s9 I2 D+ d+ s
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
: A# M! I0 g( F1 s# e1 aB.生成myclass的实例并调用mymethod方法
$ Y8 e$ ]5 G' @& P- h4 A/ {8 fC.产生一个语法错误- \, e: d9 a- L7 P/ O
D.默认myclass类最后被创建出的实例并调用mymethod()
( h+ Z' p( G) R& f, KE.调用名为myclass::mymethod()的函数
1 _/ `. x$ w7 p6 h! h* U& M( s
* V3 R$ h( ]6 P5 b! p2 d4 E
16.PHP中有静态类变量吗?
& x+ X. ~8 M# h1 C; L8 ~% f% l0 T- V& @2 s4 j6 I7 }# G) r
A.有; ~$ s: V6 P* V# X7 Q9 V% ?# g' Z
B.没有
- D6 U/ J t' _* T
9 j8 j, G9 }5 N$ q9 C
0 G* g/ g0 w' k4 i$ o17.以下脚本输出什么?-
- <?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+ v3 c) _* M1 [9 d* e; o+ ]4 N
B.2: S. L/ i! _+ E3 g# @6 _: T
C.一个错误,因为没有定义a::$myvar0 v) M" u7 t4 m" r; J9 g
D.一个警告,因为没有定义a::$myvar- [# m, q' f% ]4 Z
E.什么都没有
. ^7 X6 Y' c- [; C/ J" o" k) @5 ]- G& E$ h. a: p) W, H( A
& I+ B+ K9 M, }% a1 y1 d+ _0 t
18.如何即时加载一个类?# _& n# e) c. @
7 F. p% u# M4 b
A.使用__autoload魔术函数% d: U0 D" l% p, L: i3 K7 K& f
B.把它们定义为forward类
) w; o7 s; `7 @1 L' C* v+ @C.实现一个特殊的错误处理手段
2 q! P3 j! k0 TD.不可能
8 ]- Z% P8 S' B. mE.用有条件限制的include来包含它们
% O( m q# W3 }3 ~% ^, K' ?, R# U- h! E2 k* R; I
2 }* N; A# R; P% ]! ~19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
& E4 v( m k8 w' X6 I6 }
; v7 y) [ Y6 H4 z$ G; a 答案:__________
- D; {; l7 n9 V- X4 y7 n7 Q5 ?- Y- T# V( Z' i
" A) k. |9 F' `% l0 O
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called; U- S* J" Y Q+ j
B.一个错误+ ?9 D0 L; x i
C.一个警告8 P0 z& _6 R! H$ ^8 e
D.什么都没有
( m7 y% s% {" c* q- T6 O) ?* V( K2 z! D+ W2 ]9 s. |4 F
) Q3 N4 f8 @1 D; h$ B
' t% n! e0 w! ]7 ~答案速查
! z: V" D* Y; f+ k1 o. k8 r1 p1.类) p+ v: S8 s5 q3 T
2.BCD- j+ B" ~$ B: V3 w2 b* Q) e
3.C- e; Z4 p* v8 | B1 c
4.C
% D1 q4 M0 L! T5 W) l5.A
8 m, s5 l. I- l; o0 Q, b/ K6.C2 i& d4 X# p. b1 K9 a
7.C" f T6 D9 R- e7 A
8.C
* a2 |5 j3 W9 T6 p% m% A/ O% ^9.D2 C1 V5 b7 H4 f# u$ r$ Q
10.B
# a2 s& I. n: |# |4 J& `11.D% ]6 b. u n4 C
12.B
; m3 x& `% ?7 P, r, B" a# J13.A
* z' u8 x( d% y; d6 ~/ K$ v14.D
3 K& c! @2 s# d' E+ B6 V/ m) h$ j15.A
) X: d( C8 U) h$ X& [- w6 ^16.B
/ h: |& U: s( E- P8 m( Y4 F' `17.A3 q* I- b' w6 _ I
18.D
* B$ o8 s: D8 s" Y: |" g+ d19.设计模式
6 y6 _$ e% S" h20.D
) N" ^$ N( y1 U v
/ I" |: u. T1 l' c, t0 s/ \# P8 }, c; s
" a% z7 e& \% Y, C' u
答案详解7 d0 @ a, P8 k$ Q+ y0 A8 |
/ Z3 Z) \8 U" L( a9 J1.类是对象的蓝图(对象是类的实例)。
: k0 q* v | u+ _/ W: a n7 c1 u* Q6 H1 b+ h9 H3 E% S I
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
( e2 g3 e2 V. V1 H
( t( @1 p6 w. c' B9 P3 O. w$ U3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
2 Q- d# Q- A! n6 `' h, w2 y) a! w' s' y& ^0 X
4.单件模式可以限制一个类被实例化的次数。
4 r; p& K$ y( f7 U
! @. P5 D: N1 `4 B) Q+ @$ z0 Z5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。0 Y: P8 u+ U/ l W" h" Q9 o j6 \( N
- ]1 \0 z4 A- s) n+ t
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$ C F+ D' f1 @4 C5 G( W0 S z
8 F' e v R* o1 @* m7 ^( D
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。' u: ^) m- E0 a/ [4 Z, K2 Z( e* `
2 P$ S7 [! D' V8 B, G0 g8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
e+ n. f0 L8 i6 R" x$ @3 ?1 Y5 w3 c: R* Z( q; R# w; P1 W R/ M
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。$ M/ b/ X! {% e {: ^% ~ k3 G' o
. t+ }: a* p" O2 s* I$ ?2 U1 b" t10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
( V9 l# D `% W* d8 E- G" a( N5 F/ D) X8 U! @. |8 `- k, p
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。% T D3 d4 e6 a) k1 Z4 m; X3 \
; Z8 w r1 j" L; P c
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。" [$ R" d( ?4 |# u& Z! b( E& `
3 [7 i6 C t" m) I8 V p# n
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
; O% D: x0 W, r$ i( f; P1 ]' e' E" B+ g9 D2 P# t. q
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。6 e3 |- D# }, j& `" W
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
' |; n3 {( V9 f2 T( _+ g9 J function reduce_fraction(&$fraction)
d. B$ n/ e$ v8 N- H答案是D。
4 D7 r: D( Z# a9 u0 L! g! N, [2 L; U" ~5 d- Z+ |2 u3 e
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。6 k" M/ R2 t5 E* Y8 U! e
- V, d! b( H: H1 ^% u16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
& D0 ^! A* ]. e" M' e2 o1 ?2 D* @6 `2 f. {; P) y
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。3 r: ] I! [$ v/ @; v4 g
: [- P2 q5 O- [. M; |6 d8 W
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
+ a1 ] s; K/ l1 _- Q
2 Q# B: e, f. p6 ^) d# G19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。: [' D4 n3 v- f% p1 M$ ~
3 O8 y' i! {; n3 _9 k' z, a0 t$ I6 M
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|