  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
8 v# U+ X! j$ S) ?& `* nPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。: a3 y( ~9 c/ R* x. m. a! Z; q
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。* p, ^- ^" @. l, S* J
: v4 j3 l4 c3 \: v- t
问题
# H" Z# `% p+ \) U$ F4 K" t& l% X' y: |
1.对象的蓝图是什么?& I+ Z6 i- `4 O ]- t: \
5 v: p0 R% F6 Z7 F: s5 S) l
答案:____________
6 ~8 z' V- e7 W& F. W; @! l8 G: U
; P3 J1 `- ?' f; d; v; h' k
: O; J4 J9 i; b2.以下代码执行后,数组$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
$ i8 ]- n8 S$ M: @B.b
- S% J9 @; d4 t) SC.a
' X6 N" U, U f' dD.d3 Z% u) O) c+ l" @
E.e: k0 B" d g. Q6 s) Q. b
3 \3 }% R, P4 D4 l" {7 l9 y$ L8 |, o/ S
( x3 w) i0 W! u1 ]
3.如何让类中的某些方法无法在类的外部被访问?4 p# m" S; N5 R- S1 n( z3 Y6 w+ A
0 E; C n+ [; ~6 |9 jA.把类声明为private& `. E, i* l- \7 a7 j) X
B.把方法声明为private# ]) k2 M+ g* q
C.无法实现 g1 C: z- J7 l% @( O
D.编写合适的重载方法(overloading method)! J: b9 W( |/ ]3 x2 I
. e P4 H* x$ L" X) z1 A& \
. |# `' j7 S/ [! [" E8 A
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?8 N5 J' o( C# Y5 `" L% U: C& H
5 P/ L S% Q' i2 }( Y7 aA.MVC模式6 K% T3 K; q5 p6 n, }; x& y
B.抽象工厂模式(Abstract factory)
! D9 _8 u1 G8 `) J9 bC.单件模式(Singleton)* }8 r$ ~; F8 A2 ^4 n4 ~7 H
D.代理模式(Proxy)
) k: G) w, V. Y" M5 E2 UE.状态模式(State)" \ e# j/ o. q5 u: ]
/ }0 o# n9 U/ \! p& E
& X4 H% r- _5 [% E, z. [1 u: B5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
s: V+ x7 A4 d& M+ x I7 S- \. Z# g2 V% c' f
A.1个5 L% |5 G. H% }
B.2个7 l4 n! \ \8 {+ _
C.取决于系统资源! g9 m% x. E3 {, s# x1 V4 @
D.3个
9 e+ `, M; E. n* e- L) bE.想要几个有几个6 p# L2 d1 k1 l) ^
# a- J6 G* m) c& D5 t3 {3 U6 |! c/ L" k6 Q
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
- k! Q$ Q4 w3 sB.接口- z* a* }1 \) ]
C.抽象方法
! V! V5 |9 l, n7 O, l8 W, VD.Private方法
3 {2 K& a5 K4 GE.函数重载(function overloading)
& u( C$ b3 t, S7 F" t( t) P2 r& J. e. m( O
( \/ _4 U# Q! k u, ]5 Y7.假设定义了一个testclass类,它的构造函数的函数名是什么?
5 ^4 k/ D! [, Y8 `8 N% w! J6 l. Q! S/ U
A.__construct
' y; T& y& _, t$ y- p2 W2 s) IB.initialize, O8 O4 c7 A$ S6 o' `: L: k% l
C.testclass( v* h& S4 w7 i
D.__testclass8 S" V2 i8 H" Q
E.只有PHP5才支持构造函数
1 e: V8 A1 V; [# U5 H z, P5 P% S/ M+ {+ _! S. |, O
! m9 ]* {" f" c5 ]: I7 N2 g
8.一个类如何覆盖默认的序列化机制?
. v9 X: |- A: a
# O9 Y" \ l1 N1 p) L! F$ H4 CA.使用__shutdown和__startup方法
- L) Z0 U S* X" J, F+ sB.调用register_shutdown_function()函数
/ L! h- I6 R O& f$ e! Y+ VC.使用__sleep()和__wakeup()方法$ n4 c1 Y/ J9 }% Y* {/ w F1 Q( r
D.无法覆盖默认序列化机制
( Q- D; O/ }) f0 {: vE.使用ob_start()将类放入输出缓冲中8 q$ H$ Y- c) M# h) q
1 a# v$ t9 }1 X( b$ q8 \0 M8 d$ h( [: f
9.以下哪些面向对象的概念无法在PHP4中实现?
6 L7 N p& ?9 z1 z) v% F7 Q* B5 z/ x5 m4 B# Y7 `1 B. C
@抽象类
: J" C8 \! F6 M) f) f7 j@Final类$ Q6 x: O, {4 m; ^7 B1 _1 W
@Public、private、protected(PPP)方法8 ~. F! j: n( W4 M1 m
@接口/ X- i; ~8 Y4 b) E+ I, J% g
# j& M& V- {* e" c) A2 \9 e' o/ nA.抽象类, n0 z( x0 R' H/ N
B.PPP方法
) K1 O3 T7 E6 A1 ^# Q0 [$ xC.PPP方法和接口% o& p5 o# s: a) S0 C6 _
D.以上所有都不可用
t4 W9 p. D b9 a( Q' t. C1 s6 jE.以上所有都可用
$ U' y0 h8 e0 h& k5 G% z% C4 I( r6 J, ?$ m& \8 Y) h [: \
5 T4 ~2 q l; E. y1 i6 C10.如何在类的内部调用mymethod方法?
! y$ |# S$ E8 Q0 }' g9 m4 C0 I: `
A.$self=>mymethod();0 J+ y: T. F9 S9 b& q6 |3 S
B.$this->mymethod();0 S* I' f. x/ F v6 H* l) |8 O8 S& ~3 L% C
C.$current->mymethod();
) {8 r/ J$ E0 F uD.$this::mymethod()
: G7 R) C! R8 i) S# ^9 GE.以上都不对5 H' k& o, Y3 @8 ]) X
/ T* D! R- `1 ~/ e) q; B
: o7 c: z- r+ E: p11.以下脚本输出什么?-
- <?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
& N9 q: ~/ Y0 v8 mB.Null
& w* g- K* W1 c- P! z. ^) vC.Empty6 ?, ~- w, C1 [. ?
D.什么都没有
$ J: ? }, g" F* TE.一个错误
7 N) b! P' s6 g2 f! Z
( J+ B% C; x4 F, N* Q# m/ N
' o- e- q% o- r O8 R. t12.以下脚本输出什么?-
- <?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
/ Q9 j* \0 H4 v( e& GB.5
3 s, H$ T7 M" V& T% J# M. A, ~C.22 k! h3 R- B, j' z1 \
D.Null7 e0 b' G0 b+ B1 o4 n; y
E.什么都没有
- Q9 D7 z& a" h& O+ C5 X
( l6 Q& T7 [2 ^- T) v$ [- c( Q3 [! I' Q7 e% o& `7 y, q
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.56 }1 |# y: Z/ w% b
B.104 \& x- U$ p' z( W; N) b, q
C.什么都没有
1 ?: i; D; q: x$ m7 x) K: H- xD.构造函数将报错2 i' k/ A! F2 |# W/ T
E.510* _$ j* D4 `: \3 w, R/ h/ ^# U% ~
: R7 P0 h! q6 O# Z& A
5 d- ^4 I. w3 J0 t6 ?( z7 o14.考虑如下一段代码,执行时,$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函数必须返回一个值
) n: D$ u. H" _% U. ^3 JB.reduce_fraction函数必须接受一个整型值1 G+ e+ k. m2 C
C.gcd函数有问题 ^7 m0 q2 J2 B5 b; n! H
D.必须通过引用的方式传递$eight_tenths对象: p+ p$ ~3 y5 c) i
E.对象的实例不能传递给方法以外的其他结构。
- ?1 \& E% E- g6 P0 p6 e2 c, `5 @& Q; Z$ {* x9 K9 v1 R$ `
3 r! S* a2 i: J$ h; G! F) [' b" Z15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
- D, ~2 H6 n7 L( V$ nB.生成myclass的实例并调用mymethod方法# n( ~ } s0 L$ V: a0 V; L" u% _
C.产生一个语法错误5 v( b E5 D; k7 D
D.默认myclass类最后被创建出的实例并调用mymethod()
6 q" ?1 u% W- u6 T J& fE.调用名为myclass::mymethod()的函数
$ m- Z0 R2 ?* ]* @4 l
% ]3 g/ ~( O2 [5 c1 e! Y3 u- }
* Z; X+ o3 x+ f6 f R8 Y16.PHP中有静态类变量吗?2 I( S% Q& f8 V0 ?, x( Q
: x8 i5 S Z# n3 z
A.有
% R0 V; `) K& a! b1 @B.没有 h5 ~% Y" d% n2 p1 P9 R- y, O
! E4 P7 l9 p! H! Q8 v
, Y& M# X4 I2 M L0 K$ J! I17.以下脚本输出什么?-
- <?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
/ i6 f0 c# P; w- xB.2
2 E2 }+ J$ T/ {5 @5 O8 i% g) ?C.一个错误,因为没有定义a::$myvar1 d A' N) t2 t; ~5 [ z
D.一个警告,因为没有定义a::$myvar
B4 v4 Q& F& ]* s7 tE.什么都没有
/ m# J4 @3 W. P
0 t) O: Q7 \) E. w3 A4 \ P" F/ n1 `, k; Z0 P
18.如何即时加载一个类?
7 @0 B2 M3 T ^: f! V; {" ]% j& A, W" \/ o8 q$ z# }" D
A.使用__autoload魔术函数- j0 T& h* i4 M# `0 y3 J/ \* k
B.把它们定义为forward类) Y" N8 g O- S
C.实现一个特殊的错误处理手段
! q9 q# W! q. }6 r9 I5 ?9 FD.不可能
, x6 d* L2 G* _8 ^E.用有条件限制的include来包含它们$ r( Z% C3 V! f5 m P5 Z: H6 z
* m6 S& g9 C0 w9 @
4 G5 N4 ~* e) t4 C19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?7 y: m* H' I& L7 F6 h. C. U
$ u) N7 U; F1 P8 l5 k! n 答案:__________+ u7 A- M4 l; L' B1 w0 X
8 N$ O4 _, ~# l; \# [' h
* z* _; R& D; k" r; P
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
3 E! C# O; p; S M* w. fB.一个错误
+ O- ]8 k+ N) t6 S1 r2 O* KC.一个警告
' {' W5 d; S' z, A! v L- ]D.什么都没有
0 p9 K0 l. c3 H n4 b
# [# c% Z, ?$ ^4 ?2 L6 @9 Q- w7 V+ Z4 k* b3 \
6 Q; ~0 M1 F- B* {7 x
答案速查
. u2 T% C+ K+ {+ }1 @1.类" [( E2 A5 M7 w) ?
2.BCD
/ w! h o2 ]- c$ k* e3.C
' O) s9 Y* E% W- }: p9 P4.C
; h7 O/ J4 m% H- \: C/ q' C$ w, c5.A
" [1 M+ M7 N/ b, x% z6.C! r/ O7 _2 M' Y8 c: J$ l$ Q* s
7.C
* d4 p* R; D, r, w4 M Y6 _8.C5 @0 d& S7 Q9 L9 @4 r
9.D4 ?* B# i0 w* g1 G
10.B; z1 e: i* s% y) x
11.D
: y% }( Q, _" D. P8 E0 {6 n12.B
5 {. Q# w# C6 Q: d8 i& O, f13.A+ x# p; J. f: U5 p. G
14.D* S& B0 n" h/ {5 P+ o, b
15.A
8 Q" W9 C) o+ q16.B
" p2 P/ q7 T: ~/ `5 E( p9 M17.A
' g$ {& B9 y/ a; v9 ?3 }18.D/ j- I/ o- S- G Z
19.设计模式6 K! Q0 y/ [9 U0 U. n" A$ d( N
20.D
, b/ `- t: I# X+ B
% B) T8 c3 b! e# ]6 A
, s: h9 N, C @4 i$ g3 Y, j
, D$ n0 r9 b: L2 u. ]答案详解. r3 p1 E3 [/ b( U/ [* F ]
4 Z+ u+ I) r: S: s& Z9 ^$ }
1.类是对象的蓝图(对象是类的实例)。
+ F% {1 }$ |% A" k! O2 L' Y* s: a* m, \; F& @: z3 {
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
+ I9 N1 W& M6 R5 t/ n4 @" T6 R
0 v6 K' M- A4 E5 D* D6 q$ z4 W3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。, m( w' d6 A3 Q8 e0 ^- I t' {/ P
+ }" U6 j* f& o" X) P4.单件模式可以限制一个类被实例化的次数。
9 y' |6 c0 ^4 ~4 t. e( {
4 S. J& [2 \+ P4 l& m% \6 |+ f5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
+ Y2 Z) p2 o3 o" Z, U0 H
/ V+ Z. X) O9 a0 c0 L. U! j, e6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。1 v' t6 w* ~8 V9 ]( z7 \+ o
' s! i) g* s7 O( b5 x3 x1 r
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
* N# u6 c" H/ w7 R! _# m" @
1 ]2 ^$ e4 l9 F2 x! D9 p+ ]- v# n$ h8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
, N% Z, o+ X0 ?6 R' j. n' }! t( i' t/ |
* D# t& B* ~: l" Q9 S9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
' Y$ l: R! K i1 x6 M' ]. k5 M6 j' u4 b& N
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。$ k! j( ~) k% I0 l
3 k1 V( `9 v7 c; n+ e
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。4 D: A0 g. ?0 W& [" x- R& b1 s
6 X4 s. E8 K/ i$ p6 P; M
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
% c4 J7 B, t& ~% [7 a1 A
& ^2 h$ \/ v; c7 f& \13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。4 m( W! G( w; {3 a2 r7 X
j6 ^! L+ k& n, O% Z
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
7 p# u/ W) u' a# ?* i; g回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:3 F- E1 r# _ d+ W
function reduce_fraction(&$fraction)1 V) z- c! A9 U* g) E2 P
答案是D。1 }8 A' f. X* {+ ~
2 J& j( e/ t) u( G- E' V+ N- b15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。8 Y5 s( }) n% i
3 r# s2 t. u' D9 h3 _& b& b7 n16.没有。PHP4只允许声明静态函数变量,没有静态类变量。: N M' n$ _& I/ q" R' g5 Y
- q% C) a$ i4 `/ [1 A17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
9 i0 @* B" _1 G1 G0 t0 {$ D) R
" s! ~, ^, G1 v u! Q. ?18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。) C7 z4 C+ ?/ W, Y3 A Y
& X7 f) l0 j. G19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
9 t! ]% x7 I* j# o" G- P( H' [
% R" }) L9 c/ W. m# g* d# O20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|