  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
5 Q+ P3 S9 ?, Y5 w1 ePHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
/ i( h' b. l' S. o本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
+ i* T+ R& ?# X2 N( d8 c' V* n7 I% h9 z8 _8 T! @
问题 F; ] F) ~! S7 |3 E; o9 W# E4 `
+ G7 v6 J3 y) [8 l- S8 t% c x. E
1.对象的蓝图是什么?/ A1 k/ r* ~7 J: v( }/ @
' ]) F( F W7 l7 D; b2 s1 k
答案:____________" D- i6 O o" K: d& z! a& m
+ g1 B6 N) ^4 T
0 t. E$ [4 V) P/ d" l* L
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.c8 J- z) e: H! m; ]7 l: ]
B.b
. y4 N$ a$ E4 o& sC.a: U1 N" `4 g" X& N- [2 G
D.d2 D5 x: P+ t& f4 C t; m
E.e5 F& q. n. m# L- H- c4 N
6 ]7 H+ `5 P! f) b- N
- u! T' }: q: a H& u' ~3.如何让类中的某些方法无法在类的外部被访问?
, J3 R8 \; k. r
5 d2 I( ~* F! z# RA.把类声明为private9 x) z2 t8 h3 X- j
B.把方法声明为private3 { i2 ?- l6 L% I
C.无法实现% I8 d( k1 T0 j2 p9 ~3 T1 E y6 @: h
D.编写合适的重载方法(overloading method)) ]- X, U q% u6 v# b) e
l' o& j0 w! }% j
0 I' Z0 f, k7 T" S, b1 \4 ]4.哪种OOP设计模式能让类在整个脚本里只实例化一次?6 T/ i( C' O& Q) L: H- B) D9 l
4 k) U1 A% I0 C; H
A.MVC模式
0 u$ K/ z1 h1 I" u- IB.抽象工厂模式(Abstract factory)4 c, z4 \! b7 w# N
C.单件模式(Singleton)
+ ~) Y/ u8 H7 dD.代理模式(Proxy)
# h: m8 p V' c% hE.状态模式(State)
0 J2 z" u( E' l2 q$ O6 z8 S) S) \4 k* F- J( w
7 O" }9 c x; P/ B$ S. S' L" K
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?- E8 Q& D. e' y; e% |$ D0 Z
5 c [5 w& m, r9 V" q1 LA.1个+ z5 x" `/ Z8 q" P% E5 i' {4 J
B.2个
) u* Y% `1 w" T* D/ VC.取决于系统资源
+ K4 h* X/ K. K1 h/ ~' }D.3个7 O+ r% m, L' H. T
E.想要几个有几个
! ]: l* Z. _8 U- Y U5 N
a' w: N6 ? @+ @. F
5 h, S$ }6 V, I0 z0 G7 O6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
& `2 I- f5 n" h' E7 r) }$ |6 DB.接口& b j6 m8 O7 ]: d
C.抽象方法
, m' b' l1 l5 { P1 d! k( c( GD.Private方法* A, L- b( O7 s1 k
E.函数重载(function overloading)* b7 S% f- M' ~9 q g. x. w) b
$ u0 f7 w. }* l' C2 i, r- P
& u* @; L& H2 q( A7.假设定义了一个testclass类,它的构造函数的函数名是什么?
: V6 g# e0 V; i% _; f% j* Q1 X4 K/ g' ~+ x. c6 u
A.__construct# v. ?- q' W8 U" E
B.initialize5 @/ P; |" K. O( W/ ^
C.testclass; O6 M% l+ g9 T* \% A, F4 r
D.__testclass/ I; d9 A* E/ |' j7 N# T
E.只有PHP5才支持构造函数0 f! |! S& L) f7 i) b7 O0 [
/ s! Z: D9 T# w' c( H; }9 z( I3 \* l3 M9 E
8.一个类如何覆盖默认的序列化机制?; M$ ~) h& }* u
0 Q% G8 t6 E- ~; G1 T
A.使用__shutdown和__startup方法
( |3 l; q' S/ M$ _9 ~' g# kB.调用register_shutdown_function()函数) A' q0 q5 j7 |- m1 I) r# B
C.使用__sleep()和__wakeup()方法* @ _+ o6 Y) w1 ?- S9 r
D.无法覆盖默认序列化机制
/ ~0 t4 y" ~& G& Q: \( OE.使用ob_start()将类放入输出缓冲中
7 ]+ Y$ P; B4 I2 R3 S
8 G" [$ e2 a8 g) L5 X& Q
# E6 D/ P9 k* w6 c# s. g% P9.以下哪些面向对象的概念无法在PHP4中实现?* p8 _# o0 }/ I: p+ g- k& @$ s/ s
' O' U8 W6 D8 x P2 i# o" n1 j' D@抽象类& z2 ]# C( i$ T6 z
@Final类" J& b% j- E+ ]
@Public、private、protected(PPP)方法
/ k0 J- G# G- Q@接口+ m! C% A5 n {' L
0 W8 x* j+ V/ q9 e) k
A.抽象类
. v |! R' _# K" F8 [B.PPP方法' p) z5 j" N8 J0 y+ T0 i: f
C.PPP方法和接口
0 y* X6 a9 t8 zD.以上所有都不可用
, c7 R% h4 m3 n/ S! s: e, bE.以上所有都可用6 q6 T7 N) I3 U
; O( I& P" Y1 s& `- h# [) {$ I0 d; X9 ~9 d' s8 R
10.如何在类的内部调用mymethod方法?
( M1 p: b d- Y( N3 }
% F" l% Q& h+ HA.$self=>mymethod(); P( F# e7 U0 E: e+ I7 n) L: y9 [
B.$this->mymethod();( r$ b+ |4 H [& B
C.$current->mymethod();1 `$ \2 @7 f4 ^$ V# w! R G
D.$this::mymethod()
( @9 j6 K# ^. n7 n6 H% ]E.以上都不对
% A- @6 m# G2 L& w {) Z
$ Y8 b" E& p3 {: x- _! b$ A& h' A" M0 Z0 B1 U: f
11.以下脚本输出什么?-
- <?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* r7 s+ }6 }8 Q0 T' k
B.Null5 P3 {- P3 I- B- h, ~
C.Empty. c) ]4 c+ x3 `$ k6 r
D.什么都没有" t, m0 l @" ?4 A
E.一个错误
0 ^2 V* L0 K, O2 `4 H* K" l
; T6 ~ u9 U) ^& U6 x/ E
S4 v' O+ s3 a( e9 F4 w' P12.以下脚本输出什么?-
- <?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- O! P. R8 B9 [5 w2 k0 q2 K S" P
B.5
9 O! u' g9 x$ N: uC.2
- D) B+ T/ d6 z8 KD.Null& M- x3 c. `0 e U- [; O
E.什么都没有
7 @0 a( w, [. \9 I* J
. q8 A' U: z: r4 p% r8 q+ S2 h9 D8 b
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.5
5 s4 Z9 v3 o1 VB.108 U7 W# P$ P3 f9 \: l- J( M) A
C.什么都没有$ y0 U8 d& i3 K5 V* g. T
D.构造函数将报错- J# A( U& M4 @' O
E.510
, O& ^- g% x! i& @" \% E$ S) C" @$ I, V' m3 A# A& Y: V
% `1 m4 b' U8 p5 @8 \$ [
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函数必须返回一个值
0 Q' c$ Q% |" X6 [B.reduce_fraction函数必须接受一个整型值
9 \" G/ k9 ]/ V% eC.gcd函数有问题
2 w3 G8 o4 g% ?, }3 a3 Z) gD.必须通过引用的方式传递$eight_tenths对象
! U3 N- T, Y$ V1 f \E.对象的实例不能传递给方法以外的其他结构。
6 J+ o) b( ?/ O3 X( _/ P& s/ n3 ~; t5 `9 i! B
! Z5 g5 a) s8 [1 Z15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法- f3 \5 w' ]$ {0 s
B.生成myclass的实例并调用mymethod方法% B% {/ _( x+ B: a+ f# \
C.产生一个语法错误- P0 \* X/ r: q* \# U5 Y
D.默认myclass类最后被创建出的实例并调用mymethod(): v( M: s0 C# Y" m# ]" m l! }
E.调用名为myclass::mymethod()的函数 d9 J) e( K( b. K
# A, g6 o' j/ k6 x8 L: {2 G
$ q: Q, j/ [9 h3 k z: Z; W
16.PHP中有静态类变量吗?
# L2 m8 B. n+ r2 u; Q, a* E! @7 a6 e# n
A.有
) A2 e& E/ K+ PB.没有5 a0 s. O* L, `6 v' }
4 T& `0 ^8 E. ?; W( a A: l( H4 i! u2 z) ^ s6 s6 i$ X
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
1 ~/ \- V4 b3 N: OB.2$ d# q7 @% X9 x6 M5 j
C.一个错误,因为没有定义a::$myvar
! }3 s$ u: L+ e3 J6 X- UD.一个警告,因为没有定义a::$myvar
( J; B$ M' v, h: G8 vE.什么都没有' @9 p4 d: T, x* U
7 @9 |0 _1 e6 A z9 b3 Q' ]( d8 p; I* F3 f6 d
18.如何即时加载一个类?, A9 C9 ^+ e, ^) O. _
# N& l5 @2 E3 e0 t+ L* WA.使用__autoload魔术函数) L. }. M, _) u
B.把它们定义为forward类
3 p8 S' i+ J3 z3 @, ?; FC.实现一个特殊的错误处理手段" x1 E5 E2 h) o! X
D.不可能
4 D# f% ^* i o. E1 O7 \$ n- CE.用有条件限制的include来包含它们
" w( S) P, m3 o7 I: t; q( x: @( B$ F' h7 u
# f2 T5 ]* ^6 F7 w' x
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
( e: i# R; u; t6 A
* }+ C( _8 m4 h9 X 答案:__________5 m' p, c. l8 F+ b) M0 t
) G) X' ^. r9 n+ _$ `: ]9 f; }1 ~6 q9 K' f( V" U6 n
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
2 r" i0 c- O6 d: ]B.一个错误 I0 s* s0 @$ p. l: u' z; Q$ G
C.一个警告1 Q$ M( p5 T# c# e7 ~
D.什么都没有; B) L, \; A1 q- ?8 A: |1 \
0 ~$ s7 N- x' f
$ ]4 M4 g) l1 I9 @) g( A/ V
9 G) l K) }1 H) O答案速查
4 N0 b; d" R* X; n1.类4 J0 z6 ]! N5 W0 W& S! i8 o$ h
2.BCD
" E/ p, i3 f7 ~1 ?+ {5 k ]# W% Y) I3.C
; q6 V- E9 n! C! B* K4.C2 Y- z0 v1 I0 e/ l2 M3 v1 v
5.A" }8 Z$ ~6 n: Q
6.C- r M5 w8 H4 p+ k- w
7.C: }; N% ?+ i1 Z# _8 Q' ?
8.C# A* n- @5 f# v, D# k& B% y: D
9.D8 d- O0 d' k: x5 N5 Q6 {
10.B
; W8 Q3 o8 N$ L11.D
7 s2 C- @3 Z$ [) G12.B
6 d- t5 t$ n$ C! R! a7 ?13.A
0 e( z. V/ q; v: t0 _14.D
/ e5 [. I+ h% F; y. R15.A9 r; f6 e8 @8 m
16.B
6 C: y1 n2 n$ T! _. [17.A) x- } o) h' ], e: n2 k, V3 \5 {
18.D g6 z" b1 N- d: W
19.设计模式2 s& A0 L7 [6 g0 r) ^7 b6 v
20.D
7 z3 e' A; S4 R5 W* {. I* s4 Z1 I2 l! V
6 j- }; g7 D1 R4 S
/ N8 Z k0 r6 C7 w8 Z2 y+ F' Z, j
答案详解, P4 b% _' V$ f& H2 W' K5 k/ k
2 y9 J1 ?! `7 {" T2 s3 V2 q! x9 d1.类是对象的蓝图(对象是类的实例)。
$ m+ c f- l( b7 c9 j' ~8 d0 y
9 \5 p1 a3 j' X4 W9 q2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。% ~4 j f$ Q0 Z5 U; T
5 m d0 k' v! R y0 X
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。* d& R# `/ S% E) P! [
- w4 R& I8 W% O& U; \
4.单件模式可以限制一个类被实例化的次数。/ e7 J5 b# z9 J& L5 i8 Q6 N! ^
+ D3 l! A: Q; d( ~% F5 B; I
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。" H* b- |" I x& d* b/ S* W
7 ^1 m s: ~ D! c P7 e
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。& w2 ~, j% e3 v2 f
$ j( F' H2 R) @ ]
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
m) t6 B" T" X5 x) X" j1 n w( A% \0 ]% `1 o4 J
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。* e8 \/ y+ K5 C5 R9 [
9 m% L5 v( c* P) v0 D9 i9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
! d. z( Z& K9 e: c- c4 u3 C! L* E" f4 c2 _$ b7 G
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
$ x2 W. v L8 A* [ H3 S- h3 Y7 ^1 M$ }
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。" o) ?, L- K/ Z# x6 K' l, f
. r- e4 B! d* p F* H0 d# F. C' |" y, a
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
" U3 b/ f. E4 V! [; O6 ], z) ?$ v! x, ~
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。2 c* F8 k3 D7 s* \- X+ K
' R/ n7 c! |! a( m; k* ]* r2 A7 ]14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。5 _% l' M/ w1 R1 E% Y
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:* N" z) x; q! L: @
function reduce_fraction(&$fraction)$ {8 Q, H: P8 X1 I. e4 \% N- P& a
答案是D。
u, S) K5 d' t$ ^4 }! @
3 v* q5 A: P% K" B15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。/ k2 Q9 n9 t( ]4 z. h4 f
* ]# G4 \& f+ u
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
+ w% {! c7 x( e
9 d+ o! Z2 z6 h: t9 [- T. _- Y17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。/ \2 B) c" K: Y% k" s2 m% c0 O& c
E& M+ a; k( G, ^2 D& n6 F; h0 I18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。4 [0 z7 I' o0 b, V9 T
5 F K0 `* p8 g4 S* [
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。" R3 ~$ W9 p5 V8 Y- A, ~: L) D# T
, g' z. L5 S4 A9 Y20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|