|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14389
- 金币
- 2480
- 威望
- 1647
- 贡献
- 1428
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
/ a% h# r( E7 r7 j3 VPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
6 x _# b; h# H: K本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
+ O7 _# q8 H4 t: j: [8 k. o; j: d# U! m c5 d% B1 d4 j
问题
; g8 W! t6 [4 m
( Q# i' V1 O, A* l8 X1.对象的蓝图是什么?" q: c- B7 O+ V' O( _' A
; f# U# y& A j
答案:____________
% W$ j$ c5 R4 T& J3 O5 Q; r# Z! g
" k/ w( ?8 ]3 G, q1 h; e+ y9 _ z+ z" f
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. V0 N) L; Q0 l
B.b
2 x7 F4 M r5 X6 M8 G% _: Z9 [C.a
1 z* c0 }; ~1 h. r& cD.d
0 E; ?( o! a" o8 yE.e
0 L: d" i9 }5 ?6 e- H" T/ W0 |2 S6 C6 l! Z. [4 h9 ?0 Z" J0 U
5 S7 \/ z! v2 ~( ]) u% z
3.如何让类中的某些方法无法在类的外部被访问?2 r% ~: Z$ {' `3 |' l
1 f% ]6 [0 f( ]A.把类声明为private; {3 F" ~7 Z r) v6 @
B.把方法声明为private
( M4 B. L. K2 VC.无法实现
( l& ~: h. P4 i5 MD.编写合适的重载方法(overloading method)& X' u0 ]) G4 a6 X C* I
( q1 E- \! x8 s9 P1 Y# S4 o0 M
/ }9 s; r, V+ [; u/ c$ W
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
% S! k7 j7 D. H* K- N- W) ~" Z y; n- J6 H$ C/ A+ K
A.MVC模式
1 S5 H+ q" p" _% u2 K6 y% WB.抽象工厂模式(Abstract factory)
( n9 h8 H+ V U! k# @C.单件模式(Singleton)
3 q2 h' [4 p% l0 T: J* o$ [D.代理模式(Proxy)
* D5 b% m' e2 s- UE.状态模式(State)) z) M, g2 P; o$ L, S2 [
3 G) h+ a- q9 Y5 ^$ {5 Z
6 y- f, t8 F: q0 s j5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?( G8 i% e! ]8 z- [8 p
3 y; k+ F0 v# W' r
A.1个
7 A; t9 c% i: R; ]B.2个
; C2 D5 ?: b$ iC.取决于系统资源 h2 Y5 K- F, d' i
D.3个8 H3 |( m0 a* J v% c% _
E.想要几个有几个
/ h4 N: a9 j' u5 L% T! {6 Y
/ Q! H5 W- B; y" w7 c8 ~9 S* h$ L0 l* v
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
' i+ @( t1 A! u p2 J' WB.接口
$ l O- B9 c ^ u+ Q6 v% kC.抽象方法( r. J! Z6 R' E& o, C
D.Private方法
; Z% l' k, j1 X' l0 [E.函数重载(function overloading)' y! }8 D0 l7 B: t
/ _" V9 m# J6 h5 M: Y- }
2 {8 L, w. P$ R& I+ B7.假设定义了一个testclass类,它的构造函数的函数名是什么?
! A% b6 X* [, |( w! f3 K4 c' \" U% ]3 m' c9 n. H$ N
A.__construct; k+ d) X1 Z/ r5 \- K) C
B.initialize8 J3 p D: e) l; L1 Q' l/ ]$ _
C.testclass
+ p. w( x+ K" a' k- G! PD.__testclass
9 F8 q' [) B5 e) P5 qE.只有PHP5才支持构造函数
$ ^, }$ Y2 ~4 }& l4 j8 ?5 [6 ^ P: L6 ?3 x/ Q$ D
7 ~; Q! b% [8 v
8.一个类如何覆盖默认的序列化机制?2 s4 e' H2 j- y
) L; ~, x" d3 I4 Z& qA.使用__shutdown和__startup方法
e1 R( J# K' D: D2 m' S- bB.调用register_shutdown_function()函数
9 a9 @% k+ T5 T+ gC.使用__sleep()和__wakeup()方法 b! c: Y2 a: |, q6 `- i
D.无法覆盖默认序列化机制& g! P: i) R+ P8 X" e
E.使用ob_start()将类放入输出缓冲中1 e( I" H) N$ K, _# W! S4 u
$ @5 ^ K/ D2 g) d( `) E
3 O* y: J# L& ` [ e: F( y9.以下哪些面向对象的概念无法在PHP4中实现?1 B9 g) _! a' e- Q% P/ H" N
% ^' x. e- o* y$ b" S( V3 C
@抽象类6 c+ e2 ~% n. |' n/ w4 A& _
@Final类
4 }# @$ k9 @: V* v2 E# s/ E@Public、private、protected(PPP)方法
9 C& K( Q3 m* ~* }@接口% Z9 b- n' y, I! Y! j2 ?; |
/ W# n: m- `. vA.抽象类
- \6 S- Y" z, I* o, P1 M# B: vB.PPP方法
' \) o' I7 U6 y+ S2 O& G# P" ~) u! jC.PPP方法和接口
b* Z( P- w# E" S' s3 L+ MD.以上所有都不可用+ v0 Q/ O6 @4 I$ _ [
E.以上所有都可用* x* P. b+ t+ [( p& g# Z
4 s+ k; L/ G) m6 U* L/ y. p% ]3 k7 F r; Q
10.如何在类的内部调用mymethod方法?
M- |! c# Y* p4 p; f) U
! w( W! C4 _; o* g- ~( ^! P0 FA.$self=>mymethod();
; ]& m- o1 Y+ _% h! ?# e9 G2 yB.$this->mymethod();" f- v5 D6 q q+ c, {
C.$current->mymethod();4 z! m, C" N0 m- E. C1 m5 M
D.$this::mymethod()
; D. c" p' @( h/ B$ {2 K" ~5 w+ PE.以上都不对
. `0 {* ~) o+ [3 ]) Z: w
_7 i; r4 g6 g1 C/ C+ D& k% z: ]6 I
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.104 g5 M) [% m2 X( D1 I* J8 i
B.Null
$ v/ W/ A: s% ]! _/ ~) p2 eC.Empty
7 ~3 O( v9 y2 s' ~( {% e- Q* A% uD.什么都没有
* y2 y# |5 s0 f+ K" Q$ W5 qE.一个错误4 e6 B$ x1 l* B4 a& J
& n) a: {; G h$ R/ G U
! W( _4 _ Q: N, y; R7 X' q- X' W12.以下脚本输出什么?-
- <?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
5 l6 }& P+ n6 E! y" Q4 p: KB.53 r; m# w7 W9 @# {6 U
C.2
. J0 E0 ~; B2 |' r* ^D.Null
; C' x. A5 H. h: Q* y U+ BE.什么都没有
, U! M' c: z% F7 [% F: F& f; i' B( u0 H3 W3 m: n
/ A! s1 \. i' u* z/ 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: M4 \- h& p$ v0 v6 P3 a
B.10, t- w8 Y3 \, t: L$ X7 D
C.什么都没有: a& E7 u* [0 E, G
D.构造函数将报错' n5 q% w6 a# ?6 s7 t B! ]% {
E.510( v" p* k3 B# Z6 p! d x% ~6 ~
; |! q% [+ T9 Q
. \9 O0 n( Y; ^' w2 l14.考虑如下一段代码,执行时,$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函数必须返回一个值
: [2 m s0 \3 R% Y$ R! `' hB.reduce_fraction函数必须接受一个整型值
* X$ |/ `4 }% q$ _1 o7 jC.gcd函数有问题+ d, ], [4 h2 Z2 T2 W4 s' B
D.必须通过引用的方式传递$eight_tenths对象
9 I e) P4 B5 C( W* dE.对象的实例不能传递给方法以外的其他结构。- U: o, }: w' }! y4 @
8 C! ~9 M W- d4 P8 D
% l( C+ D9 j4 M* G7 A. n. h/ s9 i2 c15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
, z |% n4 ?1 n2 E. MB.生成myclass的实例并调用mymethod方法
- b( M5 y2 x1 g# b' KC.产生一个语法错误2 w: t3 d$ u* r+ D1 ]9 @
D.默认myclass类最后被创建出的实例并调用mymethod()
" E) F8 x( |! ?* ~E.调用名为myclass::mymethod()的函数, T/ m. R, L3 c6 \
/ Y% i, p/ B4 d! q& E7 ~# J# _/ z& E. T4 n
16.PHP中有静态类变量吗?. Q# i% K @0 X% J) e0 I
_$ [' b. Z0 Z& v( t4 RA.有! q A* n) ?6 ]; Z9 g. {
B.没有 k; ^' Q+ j2 G. w
0 W3 `3 L' ~3 ^+ m, P) e8 Y! H9 s
- R4 L4 `: E4 v/ [! F17.以下脚本输出什么?-
- <?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
# ~) Q0 y% Q, @* ?, X, ^8 D4 @1 QB.2
% a6 @( }. I) U& A" d2 m* E" wC.一个错误,因为没有定义a::$myvar6 o7 ~7 p/ G* D/ U$ `
D.一个警告,因为没有定义a::$myvar
( h% x& q7 B! ^, M4 o3 ]E.什么都没有
2 w' `7 o/ p1 L( z7 F; U! m* W+ L9 c5 g7 C$ R4 T
0 l9 @- x8 P1 e
18.如何即时加载一个类?
# z2 K7 R6 @( c$ v4 Z
* ?2 }6 J: Z- N* |, bA.使用__autoload魔术函数
4 I w) ^ t9 g/ @B.把它们定义为forward类
: [ H+ E/ m! I9 \. hC.实现一个特殊的错误处理手段. Y8 u5 p: d! T% S t1 B
D.不可能3 R* F. O! ^ y
E.用有条件限制的include来包含它们
4 `! M4 Y0 T; a% s0 a2 L
! {4 Z+ Y4 C( k U3 n8 K& o& X1 Z) I. J, D+ y+ _' E! e8 F: o5 ^
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
4 c* g1 R% \ F5 ?3 Z9 O k# Q7 C
7 ?2 Q- J( k8 Z3 N( h) ? 答案:__________
& h4 ~. r9 C6 z( f
: P/ K- H G0 Y( C3 p
* L# E! A0 S- G6 Y1 a( h20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called# y v/ z% q4 V% J* T
B.一个错误7 `! H& s* Q& ^
C.一个警告
* t9 b8 l, Q! ~D.什么都没有: n, Q @9 E# h
9 o6 J- n8 J( u% Z, |% A8 L( {; o. C$ Q* v4 M/ L/ c9 A
( s! D+ C; _/ Z) \1 R
答案速查8 D' m# @! y) K
1.类
. V2 p# } H* b& l* k8 v5 d% w2.BCD7 y, Z) z2 ]- A2 o! D! p& K. n
3.C
* j. p! X* }+ Y# t4.C
0 w/ w1 e% N, a. ~# `& n3 t5.A
- `; n0 Y t, h, M, X' V) q6.C
' G' I( @1 {- R7.C
8 _ O( U _4 y' V$ P. s) [" @& l8.C
1 `% L% w R3 c7 n5 \9.D9 y$ I! c# U7 S' y# d6 Q% e
10.B, A* z8 j/ q: ]! f2 R1 D
11.D$ _4 ]3 B5 U0 ]* S
12.B
7 j" w! M7 Q, t( B; F3 D$ k13.A5 l" }6 ?5 f0 e% w6 n
14.D$ T' m$ ?) b6 v) @$ u
15.A/ }. g4 k9 r- ?6 |
16.B/ X: v% j6 E: ^' U0 j9 ?
17.A
' L) e6 i B7 O; e$ T5 R) E, c; `" E18.D2 a* J M X* D2 Q' C4 T3 q# L& X, B U
19.设计模式3 L! J, `: T, \7 ~; A
20.D1 Y! n8 p Y; W& z% ]5 c' R( ?$ `& Y
2 r: f5 n9 h7 s3 H" }3 c
5 A" Y: y( w. R
. \( G/ j. i. h6 @1 \. \答案详解
# @5 |9 Q$ ~5 l. h6 E8 z) t* A3 m* q! m L( F; c& L3 K, ^
1.类是对象的蓝图(对象是类的实例)。0 s) L p: ^# m5 v+ Y
( {8 R- V& ]7 N5 b2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
. k; j& q) i" R4 I$ W" A
# v& H+ e) R* h# L5 e) Q3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。2 `9 q1 Z9 C x) ~/ J
9 j( V# u* B% F# x3 M, J. @
4.单件模式可以限制一个类被实例化的次数。
( P. v h* e7 [8 `6 N5 I. O+ b. P' N" n. A2 ~
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
9 q$ G) ?5 \( o/ a- N8 U
: @1 _. O* S2 z7 H6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。% y+ s% Y/ s' z
+ C. @7 v _+ Q- l, ~, J7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。4 N% c! d9 I+ V/ f% t
) T L( Q- ~" p; j9 l- `% u" U# T. @
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
+ F( J. K6 I# z/ l: x% v' T. ~
: _1 r4 O( R# _9.PHP4中没有题目选项里所列的任何一个概念。答案是D。) k+ U; Z+ ^9 X' }; S# t3 \
[7 X, v4 R4 m! g: k/ ~
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
3 Y2 _5 C4 I- m5 M) L9 Y; V0 A
5 _# n: e9 R6 D3 _5 z' X11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
, V! b- ?, z4 \$ c5 N9 j8 [% ?; k8 ?; _( H
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
7 Y( ^8 w, L* x9 e! u& l# M7 y/ O4 I1 v: E5 E* _0 T+ b
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
! w; t; j3 _, a8 c: i; `- s5 B6 N/ r. k- i" d f1 z7 I n( w
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。* Z2 K0 Y" G9 Y* k O
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:& I" P! R0 Q# [% _! e8 i5 z
function reduce_fraction(&$fraction)
6 Q+ j+ G4 Z% e! L答案是D。
+ F2 t/ \* s% v, r+ W% W% t) Q+ B* l
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。7 c0 c& J; Y: k R3 Y" G
6 v! v% [+ D; Q9 N
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。( ^" I; T5 n, r5 s' u+ k' ~
9 p: A; ^) a% ?8 \- X6 s" C0 B- F0 j- H17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
/ R: Z7 l. m# t4 |
; P" C& C% A7 m6 k! F18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。' @6 d1 \4 X% }, v+ X) P
. k4 E5 i6 v4 V7 `2 r, O" X3 f
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。" h* R( K9 o# _3 d1 h- _
6 M9 G3 Z" X; T! K5 L9 ?" U
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|