|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
& W- b* N4 n. z& ZPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
+ j) [- Y, ?( C/ K- P本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。$ S; V* V$ I. ^+ m
" B7 z" N( }: Z5 t: Z2 C* {6 O问题
w% v# j: z9 N0 o% |6 Q c. p3 [- D2 }! I5 ?( c
1.对象的蓝图是什么?
- }% N( H$ M" J) u1 t( Y# `$ \) {7 w- h8 J
答案:____________% G7 F. p* ]6 z4 M; Y
- ]4 `) ^ k& ~% v, h$ e
) B0 V' x; u8 S' h
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
' `; E2 k5 r/ Z$ {B.b
! t) P. w, a% ?5 g- V! \C.a
* z% v: D/ K: }' `D.d
9 P1 i4 W& g% F4 x- v8 xE.e3 d" f$ ? K4 c" u6 ]2 ~
: J* P5 H P0 P' N; H; P0 |3 L9 C
$ M) K8 ?6 M( t J
3.如何让类中的某些方法无法在类的外部被访问?
, e! W: f. w8 i2 k7 s9 l* |% {, V; Z# B
A.把类声明为private
% Y8 v! C6 }% n& c0 o4 T8 xB.把方法声明为private' K/ m# l$ S/ N# I6 k" W
C.无法实现
+ a+ g: N: a9 k5 H! Z: m/ bD.编写合适的重载方法(overloading method)
6 t3 B5 W; ]. s" |; I; j" B
, \8 c" `8 D, G2 _" ?2 c' U$ B/ ~7 W6 W; P4 k+ J- x/ Y# [
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
' X7 a& {6 g$ K! M7 ^" D& i# T, H9 j4 _
A.MVC模式
! P+ O/ z- I$ y' @2 VB.抽象工厂模式(Abstract factory)
* @$ B. U- c% B. jC.单件模式(Singleton)
* r }' i2 M* m) k! C5 QD.代理模式(Proxy) w$ @7 W& X6 I/ E8 d+ \
E.状态模式(State)0 u. t+ L% O# U& i: C* G/ W) Q* H
% u; ] z* N% W; G; z* L# ?
. [ E6 d- M+ C$ |1 G- b& Q
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
7 p, ]+ V' _, D) g; I# G4 F
) C+ Y" o0 e1 `9 W0 Z1 E6 x9 XA.1个
6 U- O: H( m' fB.2个
7 Q# b T4 A7 q3 I8 G4 n" q- yC.取决于系统资源. d2 P2 r+ b# i: e5 R# X& L4 d
D.3个, ?0 Y2 C# b5 U: \
E.想要几个有几个( ~& f3 \. E9 X5 N
; L7 c* l) l/ c7 r/ @4 z
/ _7 T) `$ t5 W! ~0 C. M$ x$ `6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承; B+ _7 q9 a( X0 Y: \, y) ]
B.接口1 E8 l6 y4 i9 v) Q. t
C.抽象方法" c1 v0 _" k* i8 |# X' r2 ^
D.Private方法# |) O+ g# ]# ^+ V8 p" |
E.函数重载(function overloading)
: q6 ~) z/ n6 S# F Z/ s* ]4 j# Q2 u. o
$ j0 P- b y q, L7 K0 s9 t
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
" V! K% g/ o/ J+ U
5 ^$ u6 J/ i$ J" x. x# |) b! ]A.__construct+ I* O8 `7 V" V$ }4 {. W
B.initialize
! E2 I g- ]0 n$ o$ {C.testclass- l4 Y' V' b/ E$ c% \ z
D.__testclass5 n' P& D+ r- P/ X8 z E0 J: L9 V
E.只有PHP5才支持构造函数
! C4 `. f0 g) \( k+ F+ z U. ^# j% |2 k$ A( y$ ]2 v
2 {( f( J( r/ A4 B! |( `! P/ ~& k
8.一个类如何覆盖默认的序列化机制?+ ?6 {0 {/ ^8 {3 i% T# R0 x9 h$ f8 w
4 G3 z* c' b4 H7 ^$ T/ sA.使用__shutdown和__startup方法
2 c a Y/ S5 dB.调用register_shutdown_function()函数 m; V+ F& W- H7 `' [3 B
C.使用__sleep()和__wakeup()方法
( x8 `6 H- k) W X8 U2 ND.无法覆盖默认序列化机制
9 w+ |+ @7 b( uE.使用ob_start()将类放入输出缓冲中4 C: ^. Z$ w5 O% | h
j- E0 r. u' J! @0 y/ y; k& M+ W, _0 D
9.以下哪些面向对象的概念无法在PHP4中实现?" U0 z1 r5 i( c
; ]- d% j1 t# R" M+ T" `9 X& n/ ]@抽象类
8 m; k8 K5 l5 O* F@Final类+ y8 z$ h, p0 n, O
@Public、private、protected(PPP)方法3 Y9 |' ^+ z: k6 [* {
@接口
6 J2 Q6 e9 A% U# T" w8 c2 a! F
5 T$ S& D# B. C' N6 b1 P) NA.抽象类
$ K( _$ T; ^' uB.PPP方法+ e7 O) H) g5 _! ~2 }; P% W% H
C.PPP方法和接口
6 `* G( H3 p; o% uD.以上所有都不可用! E! ~& N! k5 a7 U$ O& ~
E.以上所有都可用2 a: Q3 E; @+ Q8 N
7 |7 D. E7 m" G) v; |3 E3 ?
" }& b, g, ]0 N10.如何在类的内部调用mymethod方法?
0 g4 ^6 d2 v+ u+ }" r# N9 V
% {5 l" K( |. x# c nA.$self=>mymethod();
3 I# u0 G. a3 @' c# w' K' o4 XB.$this->mymethod();, Z7 m. k! {! k Z% u
C.$current->mymethod();5 D# G7 r5 T! J
D.$this::mymethod()
: d C9 g- v; Z% Q* f J: qE.以上都不对 u3 T* f+ z) [7 ?( r% D! S
* g4 y1 `5 R% z9 x- p
! v! N/ y2 @' h: k) g k
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
( n2 G- n& h: S P" oB.Null
|6 P$ j" v1 C, S; R7 x5 vC.Empty, o/ u5 ~. }: u1 j8 s2 M
D.什么都没有* K- A+ ~; D/ k1 n. _
E.一个错误
1 `' o3 ^* a) [
8 }5 K" N; m" W6 ~! p" k
d; e5 ^- s/ ^. |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# `) `% e$ i& n
B.5
1 F3 W. K% ]2 o2 w' ?9 [& R$ `C.26 t4 X# B1 H# }4 z
D.Null
3 [4 K M7 h9 y3 C# OE.什么都没有) ]6 K# E; Z X
# @4 I6 W P3 V$ X& d- h; V+ z
O; U2 R5 w1 _+ C: U6 b6 |, {
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
% \% @. w1 w3 _" TB.10
- B- \: P+ }; A& f. O0 r' OC.什么都没有
' @: P# U6 w& `D.构造函数将报错
; y5 K- m! E' d0 tE.5101 ~& M9 t" v B/ H9 e5 o. P6 n( n {: S
1 g" S$ l, g& O, u& i# w M( h, g0 p/ E; B$ A
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函数必须返回一个值/ [* P& V3 k& B0 j4 {& f9 A8 A
B.reduce_fraction函数必须接受一个整型值8 F, ^: j' p" q9 A
C.gcd函数有问题& f' F, l! |) p/ h8 t. ~* x
D.必须通过引用的方式传递$eight_tenths对象
: `' q7 t9 q7 p5 p+ K# A- DE.对象的实例不能传递给方法以外的其他结构。
" t! I1 n. `0 c; z d
* b& W/ U( T) S1 [' \2 \
& V2 |4 o$ ]& N* A$ c0 J! t15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法: F# b) P8 E; L& e7 w
B.生成myclass的实例并调用mymethod方法2 C# i" R/ L& R9 L6 P
C.产生一个语法错误5 O0 h1 o6 g) G* Y
D.默认myclass类最后被创建出的实例并调用mymethod(), j0 _9 x1 R, r$ [, [) C! A3 F
E.调用名为myclass::mymethod()的函数
! w+ ^: P; d8 c7 ^ e' d- \. \; D
4 c( u9 V- d5 c1 {- q' h0 [16.PHP中有静态类变量吗?
: S. }( _5 \0 J% O3 O: C/ u. u2 ]; q+ y9 O5 c
A.有
, b$ G( J$ |0 @3 J4 RB.没有' a; v2 p6 m \% X5 k* B! S$ F
1 B3 L5 c( g6 O" _( X j% E/ u- F, k, o- L
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.15 R0 i }. Y; p5 o% U
B.2) m. ~" M+ f& l5 X
C.一个错误,因为没有定义a::$myvar% Y) q. y" O4 W3 p \
D.一个警告,因为没有定义a::$myvar
2 a0 U, _) @8 \$ |2 d# [6 SE.什么都没有/ {) t( o# _( W8 i6 e
' N2 U% p8 ~2 O2 v, G& N: v
2 D* x% ]/ a/ D: G# Q$ B18.如何即时加载一个类?4 `' B' g" X& z% }% K* i) M
$ r! Z+ v7 G( L3 rA.使用__autoload魔术函数
7 T" X6 q1 Q; dB.把它们定义为forward类
$ o O' s9 [, zC.实现一个特殊的错误处理手段
& K: L3 i3 Y |; HD.不可能
$ L4 v8 g7 j8 B- @3 SE.用有条件限制的include来包含它们
; U! q% O' b" J9 o8 Z* }7 a7 Y; r# j1 |
9 R0 S6 U+ I' Z
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
% M# _! g) m' k* J8 k8 Z* z3 o. O9 B- `5 {+ E- i# j
答案:__________9 F7 q6 z o6 l7 d0 i5 X
: p* r5 O' f, B5 m2 D% F7 j; I: a" q! u
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called4 ^. W. [7 C/ f2 g3 p
B.一个错误
! E4 u& O5 v+ }) a/ l2 m5 M- M P( b6 iC.一个警告
G; c1 ^( Z/ L& K4 h- b7 VD.什么都没有
# t2 U, g0 E1 T1 ^1 R# p, C. K2 h W& L$ [, _% p
3 w7 }, i! T* i) z; c
7 P' B1 j5 K9 A) t8 V7 ^4 s7 H
答案速查
5 U2 [3 K# [2 i9 r0 u7 L; W3 |' Z1.类
9 x* J0 a) }! R+ X) ~6 g2.BCD
g2 U* o# ?& c7 e, r. S# V, S- g5 j3.C
' Y: J; g+ H' X* R4.C
( s; A) E6 z- q: J Y5.A
" |. N" ^8 A: P6.C6 e4 \7 B/ z7 I) J* f5 A6 D
7.C
* |4 q2 V4 I9 a; A% g8.C
' w6 M3 E. M b# J: N9.D$ f& I, ]2 J5 j
10.B
6 U, W5 @9 p/ y# M11.D
. B/ y) x0 F# y3 K, a: G12.B
% [% x4 _. g( l8 I3 E( Q13.A/ j' h, ^) ]6 O* b0 J% H
14.D
+ E% i) u& `, ?15.A4 E! u" }! O. L2 \4 U1 t: O
16.B
# @2 k) D9 Z) W; Y) z! r, b17.A
! `/ L# I7 X. q6 c) O( d+ b18.D
4 G+ J6 e7 Y, t6 a19.设计模式* n! }: q. C8 ~( X" A$ l3 w
20.D
( \& c# _& I7 M1 [' Z: M, M/ O! B+ n8 @3 u2 D) b
p+ n2 |9 N Y& V8 y; h% n0 V
+ D; {) W" h4 g+ w, V2 R+ P
答案详解1 y6 M: c! `; o
- a) |9 o+ h* y! n( v
1.类是对象的蓝图(对象是类的实例)。
0 L" b6 A) C0 I% c4 v A
* j1 P% j& H( H, }2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。/ {* d6 ?# S+ P9 m- y. l1 w
4 N& J6 l& v4 q- A9 c: q3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
" @" H2 x: |4 t E2 J2 S8 D9 ? r9 u2 D
4.单件模式可以限制一个类被实例化的次数。( ~# L" _: P2 l
3 ]. V. |4 F7 x t5 a
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。2 @/ m _5 i: k# X; N* L
& O0 B, C2 w0 O6 i' Z
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
7 f( {; T" _9 C0 C( o7 i! w( {" V7 [! J! p6 I; K- e+ D
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
1 g' P2 g+ M1 M' i/ s. X, h/ d( {1 E. f( r/ n1 N, Q( }: |
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
& z. Y$ p- \- ^& e6 u5 t/ n5 I5 ^7 ^& V( d) p
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
* R4 j. h6 a+ Q4 `5 M) ^+ w) _6 Q0 D; t+ u# Z: e4 i
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
- W" }% A H' V6 X$ I" H& ^1 F. W2 `& ~( ?( l& s3 T4 [( I& V
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。 y6 C, f! @3 j% B, f6 ^
7 g+ f* l. f* h3 n12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
2 c, C4 i5 D, [) o2 O) h
& e2 h7 T x% z/ G; F7 C$ b13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。& b4 Y# N) M2 V0 O. d/ {
2 j2 [ o, u" i/ f/ f
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。3 O" x4 ], ?, V
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
$ B1 ~; `# K- E/ W g0 O function reduce_fraction(&$fraction)+ ]- A1 C8 f& W- _% V
答案是D。& Z3 s# B/ w6 t
5 z; H6 p3 S8 R" D. i& k' i
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。% M* l6 g" _) s1 w) q
5 g7 V: p! o; g, o- Q
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。& V0 U Z( ]2 m& K
1 z: [# |" D$ z" A
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
i0 x* e4 a1 p$ F9 m
& B' G8 ~! o+ ?18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
. m7 X0 K2 s* i6 n' ?$ W, x
% B( J, ~# O( n7 Q' y; x19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
0 s+ N/ v1 b& | i3 z, A7 q2 v
3 ^8 i7 ^' ?3 v& \' ^20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|