  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14249
- 金币
- 2415
- 威望
- 1647
- 贡献
- 1363
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。6 n8 u& G+ D4 O! a
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
$ w. y* u% N7 H. A A- U' N4 l1 h本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。0 W( |) |( x7 B: h/ C9 W4 ^0 F
" r% G# _" b+ E% z0 o4 w7 X. ?4 w问题) }& M* E) X9 K- d
r7 Y3 t9 ~8 c+ f1.对象的蓝图是什么?
9 _* W: i2 Z8 m1 o7 i, X* \; A! S/ ^4 j5 X
答案:____________' o5 e: p. K5 v, n! ?* v
) P4 i3 O$ p, U6 v9 N0 X# c3 H1 O/ K0 N2 K
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.c& A0 H/ j& N5 L& J! T! J
B.b+ A, a- {3 x. ]- L' x/ ]0 v8 |
C.a
3 d) Q: _! Y- J) t0 zD.d1 z9 n9 I5 J! Q5 l0 E* j
E.e( I- j$ Q: {6 X! J) ^: S
% Q% j m% I9 f: c9 _3 \3 U% x: q' D- t9 }
3.如何让类中的某些方法无法在类的外部被访问?9 G* e# e! P, J/ J, V
) F6 Z" y) A4 ~7 f* y
A.把类声明为private
" r* H; w! P' s& MB.把方法声明为private
: a& D$ f8 ]6 z( N) P1 A: b: O* JC.无法实现
; U9 u. |+ W, a: gD.编写合适的重载方法(overloading method)
* w1 B7 X! J8 k* u) N3 _+ \% E0 S* |. c9 ?2 M1 T
, h1 j4 U2 ?, Q4 f2 a9 Y5 c4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
0 K" ]4 _0 y7 V7 r' X+ U
" h! z' X" w; \6 R( f" i# N" [& |6 _. l4 LA.MVC模式
, ?) i+ n: ~' K" N9 YB.抽象工厂模式(Abstract factory)
* Z* V1 U! Q/ r. O& sC.单件模式(Singleton)
" q& P! b0 F8 W* b2 O5 ]' h8 B4 aD.代理模式(Proxy)
9 W$ S5 b& t9 x4 k& WE.状态模式(State)
% c3 @* v2 q {5 `# |+ }* u5 u, h9 M' x9 C7 {
# S5 [/ }* q; h5 i" I# |0 c
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
n) O" J0 D; s1 W% K3 s* z% v! E8 d* n9 Q" }5 b* H; g7 U- o {
A.1个
; e8 Q# P5 v4 P8 F9 @B.2个
/ T3 j# X! T2 D: [C.取决于系统资源5 b/ H- X& r$ v$ U
D.3个
$ @) r6 a# }% D$ FE.想要几个有几个$ F* C3 z$ D) L& t- ?
" {& U1 I3 h6 g0 m: ~9 a9 A( _
2 G: K/ O5 W) d3 m6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承; I7 {' e9 H- G- V
B.接口
, y$ [" L2 g. ~, q5 X, y3 x; DC.抽象方法
" f$ s3 k C- {7 }D.Private方法
: F+ _9 h$ {7 D( B$ JE.函数重载(function overloading)
$ N! L: ? p7 K3 y, q8 j
# _5 h) \* p0 y8 I
. ]( U0 F2 u" l" ]3 |3 ] z7.假设定义了一个testclass类,它的构造函数的函数名是什么?
% v, G9 _9 z$ t2 m8 W7 w0 B. J. ]0 D
A.__construct" W* y0 `* G b% Q- B* B8 R
B.initialize) i+ V, m( L: T/ r r( j' v
C.testclass
x6 u% _6 v! |+ z+ xD.__testclass
% O. v+ O$ k3 N# D. I% WE.只有PHP5才支持构造函数% G: r2 r! E" I( H% [& Q
3 c& G2 Z s1 X9 o$ T: s
# H V: k# U) y7 J8.一个类如何覆盖默认的序列化机制?, _7 A2 I; n) ^
# g; X, \. `0 i' B8 z7 M
A.使用__shutdown和__startup方法, _, C& J( V$ \ C/ E
B.调用register_shutdown_function()函数( |% y) R$ x* h
C.使用__sleep()和__wakeup()方法
/ E# A5 Y% K' x. m0 h) BD.无法覆盖默认序列化机制
9 E3 Q) f7 w2 k5 W* G8 E0 D# K" sE.使用ob_start()将类放入输出缓冲中
. d* L- Z5 P3 y+ a7 a$ o- i+ j/ c* l% v4 @2 K1 m% k/ C
8 d( o" p' `2 M4 n" ~% I( j9 q: L
9.以下哪些面向对象的概念无法在PHP4中实现?
m3 Z* ^# x" A9 U
6 |0 Y- x7 ^* O: Q! t@抽象类
& ]- z: E6 A; M! } J@Final类( b% |, n6 w) d- i% V* K. O. `
@Public、private、protected(PPP)方法
* c+ `8 w$ O* x. f, d@接口% W+ E m- W' K# [2 S
5 H" {( X! ?( K2 A K, a8 m I
A.抽象类
9 s, k' D7 K4 D" F9 p' `B.PPP方法. D1 P1 W) [: ?) b" U1 h% h4 U. {+ M2 m
C.PPP方法和接口( c+ a; M9 g5 L1 m' A4 e1 H$ M$ t
D.以上所有都不可用) ^7 |6 s9 Y t, L
E.以上所有都可用
6 u* X# F" G; e2 {3 ^- K) ~3 R+ O( w S5 B: e: y
% A5 v: J F+ l; G4 V$ _5 |6 x
10.如何在类的内部调用mymethod方法?- o( S6 X% M9 V( z7 N( ]6 F
. b6 I. ]8 n T! @, W$ zA.$self=>mymethod();
, I: h. ] ~; YB.$this->mymethod();
# Y2 N) F; h4 Q% q+ TC.$current->mymethod();
5 [( E9 ^+ y y) r/ c6 iD.$this::mymethod()! _6 q; u, `9 j
E.以上都不对
1 u. j2 r3 }2 R; y
$ X4 y* c2 e9 y _
5 C4 t% ?3 Z) b( o+ A, z' Y' K11.以下脚本输出什么?-
- <?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
8 a0 e/ r2 V+ @9 P( a8 LB.Null
; m( b" e) Q. \5 Q' oC.Empty: A2 x1 Z' c7 a% V, p }' O
D.什么都没有8 o& @8 ]# H( r. y( e) i
E.一个错误
: X5 c* c- K# _; b6 S4 m2 \) a0 n4 H% H, F
, K# O8 Y% O( H6 ~' |1 u12.以下脚本输出什么?-
- <?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
X1 x* `( z5 GB.5! ]7 B* S0 t" ]( H H
C.2
7 ^7 U: P" @9 b' T/ K' j% e) j0 tD.Null( I0 P. U1 d6 _# _
E.什么都没有
! b0 B2 f7 d; q# q+ D1 t; z; z5 u+ b. w6 Y4 o0 X
" i# O y0 l6 k% d; z4 X& D13.以下脚本输出什么?-
- <?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
+ `. v) ^% y' f0 l5 ~1 `B.10
' P5 n1 C6 ?2 p0 m AC.什么都没有
: I, z) r( \$ {8 |& F/ X0 A4 S# lD.构造函数将报错
4 M3 O4 g# Z$ q0 {E.5105 J3 d# u8 W2 V
- _! U7 s" n7 J A7 p4 L. f
M- a6 |( P4 H. n, t* `- g14.考虑如下一段代码,执行时,$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函数必须返回一个值; Q) R! V/ ]: T5 @9 g, f
B.reduce_fraction函数必须接受一个整型值4 v0 p, X# w2 _; h+ A* Z
C.gcd函数有问题; L: O3 u' ~0 e+ y
D.必须通过引用的方式传递$eight_tenths对象; g/ U. U- D# h6 Q1 Q
E.对象的实例不能传递给方法以外的其他结构。9 I8 o0 S ]' _( q: [8 S" G
$ d$ x8 }2 T3 m& A, { w/ A. E6 J6 F9 h7 W
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
! ?# a" \1 s$ ]" L! h3 L; {B.生成myclass的实例并调用mymethod方法
/ J2 {; k2 ^6 j7 cC.产生一个语法错误; u7 U7 l6 x# A% ?# h& n( `6 C
D.默认myclass类最后被创建出的实例并调用mymethod()
2 k W; a2 O+ k. G) a. hE.调用名为myclass::mymethod()的函数6 l; k: d: {8 g! c- T
U% R2 P @( k: s% K C) c: \" V+ h4 h7 ]1 n5 m9 c- C; T9 i0 D
16.PHP中有静态类变量吗?
" b+ y6 y7 Q R% |5 _7 P% q5 K c. n5 D, B2 B+ b
A.有/ V f, {2 Q' q+ P' g5 S6 I
B.没有, W7 a) P3 j3 r9 k
) S i8 E f3 U3 l
% e# r$ r6 U, c8 a. E17.以下脚本输出什么?-
- <?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.15 D' s/ q! B8 R- ?- p& y, Z
B.2
* t! M# H& }9 W' d8 rC.一个错误,因为没有定义a::$myvar9 E7 r# l# S# a/ q
D.一个警告,因为没有定义a::$myvar
/ i/ c/ U' ^! O; IE.什么都没有
9 X8 ]( A. e1 a/ L2 H! j, k4 t- G: G6 X1 o5 M7 V
9 Q9 g0 g$ B! t18.如何即时加载一个类?4 k9 `1 i9 A: }+ F4 R
( T4 A- F8 h+ W/ p) E2 P9 ^7 q) a
A.使用__autoload魔术函数2 i8 O$ m* M4 o* F$ z
B.把它们定义为forward类
+ J5 K6 C" w1 k8 O2 f: ?) R5 ^& ?4 kC.实现一个特殊的错误处理手段
8 {9 J8 O* }' w+ yD.不可能5 j0 d: a% @1 d: A; I
E.用有条件限制的include来包含它们) l; M3 x6 U& ?' e
* r3 | \- G/ Y8 F, y. ?. Y
' a- z6 D R; ^& d9 |0 V! {+ Z k19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
r |( v; q/ h+ M
1 Y" w/ `7 I- M$ H9 k 答案:__________+ N# R; d- I' K8 k1 g
( x1 f* p% m8 N6 c$ G. M1 J8 g9 h5 N0 N. j4 t, A% r0 M
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
* j* F, x- p, E$ x3 HB.一个错误
7 P! [, I0 _7 zC.一个警告
9 P5 w" H3 Q, B6 H2 E9 ZD.什么都没有9 M4 i' T6 b8 S; \7 b4 H, l+ n
( F" R* f$ M3 \- M2 Z) r2 B( e; d3 l; Q6 p U
H8 _# B9 `9 ]) m" r; h答案速查 q5 J4 M6 {/ z: H
1.类
& j6 L) r, K1 {* F2 G4 d2 P) C' l2.BCD
( z7 b9 o5 Q0 }3.C
1 X$ b3 n; ~! Q0 w C4.C
$ M/ F* |) Z( a9 Y4 t5.A
- a+ @$ R& ^2 D% A6.C3 L, w V5 {5 c
7.C [: z, L5 r; N
8.C3 I* d Q$ C; u; E9 E# p5 H% D5 G1 A
9.D
: }3 \1 v! b5 {$ V' Q% A10.B
# \. h) l5 T; ^/ d0 n* K' z, `11.D( Z$ E% f: ]4 x% S4 S
12.B$ Z9 r4 a% s0 _2 }/ F6 M- S/ q
13.A
' ~, a; f! ` n7 g0 p3 c14.D- q: h# l- |; o, ?5 U- \
15.A; B7 K* v% H& P8 b5 s2 ~
16.B2 [/ M1 w1 w3 i. y+ i! \
17.A' ^) N5 I; k$ M4 m
18.D( c* f5 L8 c$ o6 q) _! R
19.设计模式
; m- Q/ t; J1 q S* l20.D
7 {) Y6 y3 Q* ]5 d/ ]2 Z& b' S0 S* P9 F% `" d0 u
- E' y7 m$ b1 f" [, ?5 ^/ d
- U P; J, [. |3 c/ x+ l
答案详解
! `8 d! e6 K* z# W' t8 b& u g0 p. Z: T
1.类是对象的蓝图(对象是类的实例)。/ J0 s! n+ C; p- Q1 X
+ u# p( H @& k# E( J! Q2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。5 X4 f( W( E1 Z- ]2 I! ~
2 B) i" Q a2 j% B- x L% Q, H i3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。) m1 l% l5 o _7 z9 @
7 Z& {" l; X, P, a4.单件模式可以限制一个类被实例化的次数。
2 D4 G0 Z2 [ Y6 n$ X# q) o6 V8 E' O6 o0 O" S0 b
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
& a( M/ b1 b! V/ b& V
+ q& e- g& r/ Q( p3 |+ @6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。" ~* Y7 F& b. J8 j
: }5 u+ [* h. A# n, C% x7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
: g; h. g' B0 }' U5 u4 l9 X0 L2 D3 a! Y/ V$ I. W
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。, N/ H) R8 |7 n& ~" p
3 Q* S* _/ l3 `: y2 U; s, B9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
& g1 B0 J4 J& `$ F% J) v. Q
; z. k& Q. W) W) H# r! n- y U10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。7 A& V9 M7 p7 K' g: F
0 _+ n6 P( K! C8 `( s5 w( Q
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
( p7 Q8 l; B3 T# {; |3 }
/ j f+ W7 Y# a" {; ?6 J12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
( c( t/ t4 M2 ]$ |( k) a
' ]" D. [8 K: l& o5 v13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。$ U( `2 y5 F! i+ u" s- O$ p* j
$ C; o# k. n: i5 O9 o: t+ u8 {
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。3 u1 g9 D2 E( _$ C! N& g% Q
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
; ]& J' E3 X3 Z- E K, b function reduce_fraction(&$fraction)' w/ W& ]( o2 D/ i
答案是D。
& K8 N5 `. ? L, P. ]% G" D3 _* C I' V- k" ?8 S" x% H
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。/ T8 X1 c! n2 m4 Q! U
( F& D4 P4 |2 r16.没有。PHP4只允许声明静态函数变量,没有静态类变量。/ t Q: B" y f1 s9 ]- \7 Q4 s$ ?8 @* Q! i
O$ G# N, _: Q. s% u17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。2 `& X) `5 \2 V2 s( j5 z- p6 K' [
( H0 L, y0 f* s" U1 t0 o) _( M18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。9 _" p5 a3 S$ v5 j% w. a) q
1 e( i8 R( T8 w19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。3 p4 y% F3 B3 |
5 \! S) \0 @( R) Z20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|