  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。+ i2 t2 X* o# {5 g }4 z
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
$ q1 G) J1 i$ ?. ~9 q9 S, T5 s* K" w5 H$ h本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。' N& Z- X, e0 B( R
- }! v$ C" p- X. z4 p
问题
& E, [* C& d$ ~
" T1 |( c3 g4 N! C1 H0 e) n1.对象的蓝图是什么?
6 n" G0 J" j: n$ V( ?& f, }: _3 a
, c4 p% G d& [5 s/ K0 a( a+ L答案:____________1 G$ ^$ S# h$ }' i. h, v R0 ?
& L) T, i0 L5 G& q1 k
, t7 ~" k% F+ }2 O- b$ P+ S2.以下代码执行后,数组$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 ]- T4 i k, s5 M) z% f
B.b
1 D, o+ q/ x+ _" ?) tC.a% L. @' V- ? \( O+ w" c7 j
D.d! X- l7 i0 {# [* @6 n1 K
E.e
8 b2 J- K" O4 [ w+ ^" e1 w% s9 i
; N; m( a% A, H: Z1 ?
( [( ^+ ^; S; s8 @9 G4 _3.如何让类中的某些方法无法在类的外部被访问?: _; A0 M. M) M; y( ^
0 M. j2 _4 y0 Y& ~# \% Y0 X( iA.把类声明为private/ D1 B" {! Y% g+ }# I9 M
B.把方法声明为private. Z% K7 a( t/ ^ u- g9 }
C.无法实现% g$ X I ]! |( i t
D.编写合适的重载方法(overloading method)9 v; o- |, p/ A% Y# i3 ?; J3 G
+ K, H1 q6 v' X" G) e$ X9 K( v; P! N/ w! b( F; H# R2 ]
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
" V8 E& e: C% G- m8 U+ r9 u7 S' d- G$ P2 q
A.MVC模式) S/ `( m8 S1 C% n: U
B.抽象工厂模式(Abstract factory)
, ~- D3 k& j |$ @. fC.单件模式(Singleton)
3 V9 K$ ~0 j3 l# H j' @& L' [* xD.代理模式(Proxy)6 N: \3 |0 F* C/ i% K5 N
E.状态模式(State)
+ X6 U& @# T& D5 w' f; B: L: d8 [( w3 }- u4 i! L6 @
, L! }( ?5 E \9 i
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
2 F- l# o7 T1 Q( \
/ o; P. p0 Q+ q$ Z! k5 y: N" ?9 ?A.1个
1 b3 N1 W s, ~B.2个
/ ~7 f- D) ]8 C; ]8 z( H- AC.取决于系统资源3 H$ G; |+ s( l% ?) E f% e2 _/ K
D.3个: }7 c$ {0 Z! j
E.想要几个有几个
& P4 R4 |4 Z. I# s) j
. @" m& t( P/ Z$ \* n
3 h# ~/ Q6 m0 W$ C/ ?7 e1 t6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
; w, X, C! \; VB.接口) Q% m% D0 J0 J; ~, g& c- I V
C.抽象方法
2 a" b- `4 ~7 z J( MD.Private方法
; s# x u; O7 s+ o4 uE.函数重载(function overloading)
, Y/ C4 q' a+ X" V$ N2 v2 O9 c7 v! w7 D0 M0 J
+ I f0 \( c+ C3 u+ S3 G' c A
7.假设定义了一个testclass类,它的构造函数的函数名是什么?2 Y6 r! u2 h1 a3 d1 Y
# h( q1 r" D) n6 G( p% v+ m1 f
A.__construct
- z6 k; s7 U9 |! gB.initialize# e1 |: I6 v. e
C.testclass
* f, i l6 ? E7 \) C3 v& UD.__testclass
9 y0 e) D6 e/ P' UE.只有PHP5才支持构造函数
K- Z& m3 z2 ]4 w1 k1 [4 {6 v# E4 z1 W* ~2 L/ I* S- ]6 @
; Y+ E0 j0 A' a* u/ `! A/ u7 G8.一个类如何覆盖默认的序列化机制?
5 Q" D( H. |+ Y7 U# x
$ n9 ?+ h, T+ cA.使用__shutdown和__startup方法- {: ~% m/ [4 J/ O8 M2 D0 F0 d9 I
B.调用register_shutdown_function()函数
3 L6 T) U! a8 e# BC.使用__sleep()和__wakeup()方法, n$ p# X. c. x* k& R( E% @" i7 z
D.无法覆盖默认序列化机制+ F {" n; b0 O# r5 h! |( _
E.使用ob_start()将类放入输出缓冲中
, T: A* [8 x2 v7 T* N. |; j# R( h3 K
- s. e# s: O) a! }: ]4 Q9 w3 |9.以下哪些面向对象的概念无法在PHP4中实现?
0 Y3 ?. g& g' S0 a3 M% }
5 ~) Y9 _6 O y0 ^@抽象类
/ ?8 U8 w* @# \9 b" p@Final类# m7 p/ S" ^1 @
@Public、private、protected(PPP)方法. i3 Q+ C$ Y/ b& @+ _ a
@接口
6 w8 m6 E/ \; o) K; S
8 w0 V: A7 @# ]A.抽象类# | [" H# O/ L& f
B.PPP方法. l/ r u* u$ [& _4 v
C.PPP方法和接口
3 N% b0 z8 |# r6 e8 L: c- A* h; ID.以上所有都不可用
% D& u# Z, c* C9 g7 NE.以上所有都可用( w: f2 h5 X8 L# x" y6 n: k
( e! R, U; i5 F3 Q% h: S9 _* N
$ |6 k! L% J# }, D6 X1 L- D2 p) q
10.如何在类的内部调用mymethod方法?+ @. @+ v3 h ?9 G$ r$ ]* X
* f# _7 ]$ Q; ]1 V pA.$self=>mymethod();
2 W. A* W) X7 m. \B.$this->mymethod();0 B/ Y* n) Y$ b* _) |( t+ o
C.$current->mymethod();7 R" d7 q( F$ q- A! o1 C
D.$this::mymethod()1 Y P" _" h; p7 M+ h
E.以上都不对
: ^% v, ]& W/ d6 Y6 u! q6 N6 i6 {% d
. c( N* k; M! x/ R: E
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: z4 S2 T- u; U: [$ Z3 M$ J5 _
B.Null$ Y8 g; f( b* f+ b! ~- h
C.Empty
2 r/ [% `* ]0 j: ED.什么都没有
5 D9 v5 Z# E" l) x* KE.一个错误
2 z( h5 m1 }5 h/ I! e( A7 t3 b) ~
e. M8 p9 k/ C* {: _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.101 Y6 L7 o4 G" j$ U
B.5% }& y+ k( v7 X
C.2
' K& Z+ N Y. Y. \5 C/ z6 cD.Null) u. k8 s& R3 B, U3 X4 q
E.什么都没有
( f. G1 n5 b' m2 X% J1 h% A; N
: i/ y7 s4 O" K4 S% J% N g6 B: j( t# H5 m: a" s
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% c) h2 ~( N, X
B.10: y4 S: [2 a! {4 f; M. e' S, y
C.什么都没有1 ^) ]4 f! Z+ q% Q# i2 i
D.构造函数将报错* d5 m3 e+ a8 b# f
E.510
S9 w2 i7 a/ a1 T9 k. D
/ U8 L( b- S; w. M
- H) K$ W \' @$ }! S0 s5 c9 s14.考虑如下一段代码,执行时,$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 W) B6 r" o( o
B.reduce_fraction函数必须接受一个整型值, T; c: a' d+ h3 D2 g
C.gcd函数有问题. t9 a9 F8 M/ P3 ~6 F& r
D.必须通过引用的方式传递$eight_tenths对象
$ T0 y* T* n" `" L6 x# H% RE.对象的实例不能传递给方法以外的其他结构。
+ h; a$ Y% j* f( s" O ?4 ?" _2 L9 d. F! c/ E) n# W
$ ~0 F i Q- j g5 r( Q6 g8 [
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
: \) j5 B* c9 i+ I; M) h$ WB.生成myclass的实例并调用mymethod方法- E. N0 X+ T' A/ |+ A! z
C.产生一个语法错误+ I# U; g# f/ e2 L5 ~1 O
D.默认myclass类最后被创建出的实例并调用mymethod()$ F% N/ G! ~4 i- [- f+ l
E.调用名为myclass::mymethod()的函数
. v# n; d' L1 ?) b1 Y
% n0 e+ f% W$ }1 l& y
( C/ h X" f% u2 j16.PHP中有静态类变量吗?% b( D' P) R* N5 K% R
. e5 o* t: H2 LA.有
: O$ @, {% D mB.没有: T$ j5 m+ i/ a6 D
- P6 j: g; Z/ D2 U
- ?4 l8 n, O1 N$ g! u: F( U
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( f# M# w+ ]8 R3 w" v3 B$ w
B.2# G& `2 t7 H( e8 W
C.一个错误,因为没有定义a::$myvar/ F& T' `; j1 f7 {) w" f
D.一个警告,因为没有定义a::$myvar
" h1 b1 R( |, x/ @E.什么都没有) i! @2 m' n4 F7 b2 D9 w
& r1 J+ B8 k2 O6 A
6 n- [. a9 B) ~5 v/ w18.如何即时加载一个类?
1 H. A, X& l1 g+ v! [; R# ]
; x0 c, z3 o* B7 T% q) WA.使用__autoload魔术函数
3 ]" U6 [( g, N& q8 KB.把它们定义为forward类
% ~( k: H, S8 ]9 @! w* c9 P0 dC.实现一个特殊的错误处理手段
5 }/ W1 p- n0 K; H5 y0 Y& N, _* kD.不可能( j2 j5 B) |7 g2 n) D) \; d
E.用有条件限制的include来包含它们5 e9 x- | g) ]# Y4 a
% `, S1 z0 P( m- m3 C1 h% ^& W3 x5 Z) {
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
1 s- ]; }! \/ L, A7 B3 A( A& @8 ^' H3 T8 x$ a W! {* {4 X
答案:__________5 f2 H% K5 D8 x* Q
: ~6 x/ o! p! w3 w5 d, f: ~& j1 X d. t. `2 h
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
3 w/ O4 n( e2 C8 V4 h9 C6 a$ s8 LB.一个错误
2 e+ t+ c( t5 G6 Z0 kC.一个警告
/ _3 ^. D( \" }4 p; V' YD.什么都没有
# r7 R# U) z+ Q% _5 q% U9 t; V" o
% g. W8 h/ t I( u6 A& O$ u- u; y5 N9 a2 l
9 D$ G/ o- j% o% b) W
答案速查0 B( X# u* ?- f; c6 m6 M5 u
1.类
* }( @1 @- _, P/ v+ [2.BCD+ H& l$ I1 M/ `0 |3 a
3.C5 @! A" A7 e! ^3 C
4.C7 B j( C: B, W$ K5 w0 V! l
5.A) o4 h( }0 |2 V
6.C
$ Y& X- V( O& K* c- w. Q2 j- w7.C
- N' w' s6 v! r& @( x0 u8.C2 Q; e7 q. U% @4 O8 y$ J( R* L" k0 n1 J
9.D
7 Q+ h9 ? l% v; I m5 e/ G) K# ^10.B) q/ {; D4 U8 j1 ]8 |! Z
11.D
* k4 n% l+ n( U# O* n12.B; x! Y& W1 d; M3 A( X
13.A
! @& G' _; u& t0 T; j" y* J/ B6 m14.D% t: M v- H. J1 E9 V
15.A
. N/ Q/ Z7 {7 f: N( k+ e' ]16.B6 \3 m2 z+ l, r4 b' V
17.A+ ~/ h6 ]- ^# D: m, M0 [( G
18.D* [1 P, o2 z' @8 z0 W& [
19.设计模式
2 ?/ A# p9 W# y( D2 S* E6 b20.D+ @ C' g& {9 B2 x
; m# b) U* P5 {0 }! G V( f& j
0 F0 c: S4 V/ W7 m: [; X$ I- X# F4 |
3 J; Z1 o' o& L/ C0 }- M答案详解+ ?& V; z2 m! Q" `
% U# R/ t2 I8 J9 x7 T7 A( T2 q7 f
1.类是对象的蓝图(对象是类的实例)。
) \4 P4 ]0 C4 N! A3 P+ y
; _6 ^, `' ~1 a) } R: a" G' O; J$ ^2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。% I2 ?2 e- P: z8 K' O2 l! }! {. v
& v N1 p* T: ^3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
& \5 T. X9 _+ f; z7 q* i
3 c7 c6 D9 z% C, _* M4.单件模式可以限制一个类被实例化的次数。1 h/ |7 K6 Y2 O. j
: O+ f0 ]& C D
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。2 M6 I! F3 P/ P2 o
: Z9 I4 k: |- [; e4 m
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
V, ~1 x/ J( H! \( x9 p( Q- ?, _5 [5 S4 b3 M
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
" Y- E0 G/ q5 ^
6 z2 i8 w3 G: X* A9 g8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。9 y/ |0 e6 m3 v4 V! @& C
# Z: i$ y! }) d0 s( J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。( X5 E% Z8 D' Z! I
# }. I! U- s" \10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。! D J& R, x* O# J. P7 y# b7 |" t7 h
$ |# S' U) b r; n; a; Y: l4 s& {
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。1 e( N3 u* I: l
0 z$ }4 \; o3 ~( V2 h$ |* [" K12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。7 W7 i8 Z7 \, d2 P6 U
. D H% O9 v( `5 H! [8 Y
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。" F- x7 O2 R x1 H4 c
0 k( q- Z, V1 y9 m! l# N I
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。3 D+ U% V. Y! ?7 r
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
5 }' {3 i# r3 M7 O" B$ c function reduce_fraction(&$fraction)
& H& q1 I2 |( D5 Q2 ]/ X8 a' `答案是D。5 L0 c- i7 m1 ~$ ~& L! z& k
# a3 |2 X, @( x, ~6 H4 f15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。. B2 E/ v8 t$ ~4 k1 P
, U% |" E' R$ x+ N# H6 j0 L8 @16.没有。PHP4只允许声明静态函数变量,没有静态类变量。. ~2 H5 X( @, |( Q( j
$ M6 s, W1 L1 e. i4 W* n2 R, ~
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
( d2 Y/ B" t) G- _
) H* }- H3 H3 p/ T% W/ P$ r18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。% o& ^' q" l: z$ {
+ a4 X; E. K, l5 j& E% E
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。 P1 N' \7 n$ ]' i) r; ]4 k7 A' N
; o& A# Z8 O _$ }. a
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|