  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14249
- 金币
- 2415
- 威望
- 1647
- 贡献
- 1363
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。6 i* g+ ^! l4 V3 d' a
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
9 A3 C4 k) p/ S- V4 l! Y本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
& |' z+ D l9 {2 M/ s
5 F+ H9 V: O; S0 p# G! ^8 C3 j问题% ~8 H( i* M( b5 g( l
. z& t: Z2 T, N8 t- f0 W2 P
1.对象的蓝图是什么?7 R3 |! y4 N6 h, {' Z. H
) _7 }' B; M6 Y! X: f" I& U1 [- h答案:____________2 B* G5 P5 D+ T9 \' x$ m9 A0 p% r- a
1 |) u& K) s; r: X
; [. F5 c3 { l6 `% f9 T
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
! C3 l# W( i& }; BB.b/ }, ~( t2 g4 b
C.a
7 y7 y7 y4 A; YD.d
7 d* l2 k5 l" a$ e# j1 eE.e9 x# Z; s+ M; Z K6 F$ q
" ?: R- X2 f- q- [/ o: R2 F" j
- N: F! p, I$ L7 V2 G8 v& K. ]3.如何让类中的某些方法无法在类的外部被访问?
7 a j, C0 m2 t0 y0 |1 {
6 N+ s* B) h% ?& [, c8 m" g- }A.把类声明为private
; \ D) p/ w: F& ]B.把方法声明为private# j K+ \1 X. `. q+ Q6 ?' {" U
C.无法实现
* z) l5 ]7 j+ ^8 sD.编写合适的重载方法(overloading method)
: Z5 r. j) r+ \- \% Z# S
( W4 d* {' p0 K9 }; E* i' [% K" p0 n# A( h! I
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
, ~5 m/ l7 W f& w4 e4 {0 J
; O* d; b3 M9 V; [- D0 MA.MVC模式+ n. e+ Z- L' Y* P
B.抽象工厂模式(Abstract factory)
- n5 w! {+ M7 V$ @" j8 A' R. oC.单件模式(Singleton)
8 D* j' d! ?; q1 xD.代理模式(Proxy)
3 s. j" _; U8 j/ b" s& h( }E.状态模式(State)
1 O! ~( z: ?( _# V7 i# `' u( t" ]5 j4 M# y' [
' H+ q1 X' ~! n- I( i5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?9 c x0 f. t# ^' Z; p9 D6 c% i/ G
: Q# t6 M% c$ \* t$ T& s- S+ e* BA.1个! ?" t9 M; W8 i) z
B.2个
$ F3 K" C$ |- @+ H7 p& HC.取决于系统资源
, t9 z: B# J9 N, v. L: K# CD.3个
5 J5 Q$ k3 j8 o* T& S6 |! jE.想要几个有几个! y/ q* O8 U" ?7 P8 R. i8 C
! d) L; }( s1 }5 d( ?6 S
) |; {: v* I7 |% Q2 F
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承: N, m' n0 j. d" y0 f ^1 C
B.接口
" y$ V5 k' `0 W: j& ^C.抽象方法5 P" V; h A) t# ?# a& p w
D.Private方法9 x: Y* c M: R
E.函数重载(function overloading)
g0 W/ m& J' V/ Z4 p" a! u" e' y/ u# K$ q, Y$ @. u
' g- l# y' |+ H I8 G7.假设定义了一个testclass类,它的构造函数的函数名是什么?) x8 |- D/ o1 g" a* G( m: x" {/ v
& v: z1 t5 |+ l3 g+ V. k
A.__construct' P) p& H6 |, Q6 x
B.initialize
& G- T% e+ R: _0 y% D3 WC.testclass8 P) p# z+ M, h& z' Z$ b: j; x$ w
D.__testclass& b/ `2 K. I" x2 t: D! e- e
E.只有PHP5才支持构造函数
7 F& Y+ q8 ]% x5 v. X! O ~1 {/ f" g2 T
; i, o! e+ \6 L. Z) r
8.一个类如何覆盖默认的序列化机制?
/ N' o3 V4 E* o. `2 U
( z7 k1 n3 g! `" ?: QA.使用__shutdown和__startup方法
4 B5 C o( I: wB.调用register_shutdown_function()函数) v# Q% q: J/ J$ V$ g/ n5 A/ F
C.使用__sleep()和__wakeup()方法
9 Q6 P% O) z2 ^1 e J, b' ]D.无法覆盖默认序列化机制, K5 K* s6 p+ W; @, l9 h0 U
E.使用ob_start()将类放入输出缓冲中, i& }* a' M8 u. U! Y
5 J0 v% \' k$ i: J4 D8 W
/ e0 a/ ]4 P: @# l5 ]1 k9.以下哪些面向对象的概念无法在PHP4中实现?& [0 T" u! F& z
- u% m7 o4 ` K" I! A@抽象类
% ?0 N5 F) g* \" r' w6 _; v@Final类# b- p4 ^5 Q0 O1 E
@Public、private、protected(PPP)方法
7 F" o t0 A# F/ F- j@接口$ v! s8 p3 C' S1 F _2 u
- d6 k/ A5 t: ]& G8 ?: i
A.抽象类
* [$ m0 h% K2 b" e* jB.PPP方法3 o- J; R1 r7 O( [5 k
C.PPP方法和接口9 w1 N+ Y0 J- r$ Y+ [
D.以上所有都不可用, o9 Z7 @8 r/ S6 G# l. x1 k6 v6 W
E.以上所有都可用 c; _+ h+ z) T/ E% X/ T# p
, X8 s x& T0 L8 Z% q7 u3 t" H
: }5 u% D/ C8 p# C O3 e- M6 ?2 G$ V
10.如何在类的内部调用mymethod方法?: C, k, I9 a! Q" x
9 B! Z) U4 L) \0 X
A.$self=>mymethod();2 U) ~- Y! t5 q, g& v
B.$this->mymethod();
5 g# _& b% U3 m G6 ^C.$current->mymethod();# q, @+ L! a6 t/ n. C4 D- h+ x
D.$this::mymethod()
- x1 o; m' I8 }5 v w; e% ]- G$ J# cE.以上都不对% c* K+ I3 X: \ W! S# Z) j, A
. `. k H$ ?6 F& d+ ?
, a1 o6 M1 O4 r- |* 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.102 E* O& o$ Y' ^# P$ q5 d* `
B.Null8 i0 t- v3 P: o/ `& G+ b
C.Empty
: d$ j4 W! J5 k) w* X0 H- z+ j( gD.什么都没有9 q. {8 N4 t" |8 ?8 n# E, N
E.一个错误) R/ p5 ]9 q. ^6 ]% I
. p% R9 }# J9 b8 C
$ i( N0 D- D1 G+ K! |; g12.以下脚本输出什么?-
- <?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
! p6 k$ b& Q0 n- F# \B.5
. i+ Q* a0 _& rC.25 Q; z/ ^2 @4 y
D.Null
: b; L) z+ J& \2 DE.什么都没有& a; X9 Q9 a: J& O u
% r* q; A) j7 v1 T) A: b( y, D: K/ H
2 y2 ]; Q! \' D: B: J2 q+ v1 k13.以下脚本输出什么?-
- <?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+ d3 a- A0 D$ v2 U# Y
B.10
) F- K' m% Q* p' y' P+ H/ tC.什么都没有
7 l; r! d9 T8 p! bD.构造函数将报错- s3 ]4 ^- ]! [4 ^& [( R
E.5106 R& Z2 r" E" \/ C$ @5 @8 v7 b/ l
$ _# }% O( j& o7 W9 k2 k! T
$ I4 V+ n) J3 u/ r
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函数必须返回一个值
8 L$ k5 n* s$ [3 q: n0 Q AB.reduce_fraction函数必须接受一个整型值
$ P+ W4 t/ V DC.gcd函数有问题! Q5 }- M2 p( w# D/ r
D.必须通过引用的方式传递$eight_tenths对象4 Z: T$ N% j1 K; h# ^' F
E.对象的实例不能传递给方法以外的其他结构。
/ M& N5 Q/ m3 _0 G, ~3 @, H* ]* ?5 J# m
8 @; s* ?1 i7 V7 B) U8 y
( C$ _$ i! h; C3 c6 N+ P- r; A9 ?" r7 R15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法% r* K+ i8 M1 E4 y1 l2 S$ Z
B.生成myclass的实例并调用mymethod方法 H2 ~) Z" P* A0 L
C.产生一个语法错误/ |. N) K/ u' s3 J7 }% Y; a
D.默认myclass类最后被创建出的实例并调用mymethod()
1 E+ D1 G' X. b. _E.调用名为myclass::mymethod()的函数- W2 L o2 d6 H! B4 O& c
; u1 U7 ]& X& W3 ?" W
0 }( Q! s9 C2 a X# ~3 B- g# s! T16.PHP中有静态类变量吗?
* n- P t! v P4 l$ u5 p: ^
0 d& a7 Q/ k) y5 e0 Q( bA.有7 o6 `1 O M9 d' Z: z2 B9 T% ~' y
B.没有. x4 q+ n* T4 X6 |/ B' ?% r
+ Y3 k, I. _$ h7 e- T
" V: f; {- m5 C& b9 c8 q17.以下脚本输出什么?-
- <?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.16 R5 E* `! G) c
B.2& L: _7 d( e$ y3 t! {0 c
C.一个错误,因为没有定义a::$myvar
1 e. z+ Z7 T. e( N; M- jD.一个警告,因为没有定义a::$myvar
9 x) |; `' l C3 I" y* B. w3 rE.什么都没有. |; W" _, L0 g# C8 M
) }8 e! N [1 p- w
$ c0 ^% W" i8 W5 s) W18.如何即时加载一个类?
( h- L9 C5 O7 {0 R: w& s1 `
3 g; [& [- ]: cA.使用__autoload魔术函数
% W8 o1 L( l' O' _B.把它们定义为forward类3 B Z: y0 Q' l: U! @) U! {5 o
C.实现一个特殊的错误处理手段
0 L9 j! R8 [* p# RD.不可能
5 K& x" t* }3 o5 {, dE.用有条件限制的include来包含它们
% C9 m0 U3 O) N' u3 U* n% q8 ]% _" Y! g% K
$ `/ Y# [( u4 A: `2 R8 j19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?4 s& }: T" @6 |" F! c1 G) l/ a
, X0 n4 L ?7 d% n6 P2 W) \/ [ 答案:__________
( [0 G8 w; L' Q
$ z: K% [% p* U }, B' X- b: P( @2 [" t( \* g7 R
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
# U! g; n& t6 X* U0 D" DB.一个错误
- } j2 s, f4 C" ?* q$ b: lC.一个警告
. T8 {# i4 O7 p, q( Q: oD.什么都没有
- Z- A4 s9 r( k3 \( j% o% N% l$ c8 B4 r, [5 u& l" x& n5 v% t3 k# s
+ g4 u# [, T& v8 ?5 f
* V$ F) t, f7 ?# u, K# [答案速查5 i- l- w) m- t+ P% T, A( K* `
1.类
4 x6 v: ]' S. C2.BCD
5 V! i7 ~+ E4 A1 [1 {: I3.C
5 o* h+ x) Y9 j3 ? `4.C7 a! W @& ^# P, G, I0 w
5.A* `# s% N- d$ _5 y* Y% b
6.C
- ?5 v: m" Q4 ]- H1 W2 {! s7.C& M& D! ]' F( |
8.C* ] D$ f0 Y9 |3 \9 g
9.D
! D- i" F. C4 Z6 p8 r10.B
8 @. \/ w; B) t. y& m7 @11.D
2 G6 W9 Q& U9 L/ m) F12.B& T3 H9 s; b; o& Q c6 d2 T& }
13.A
6 J6 ` k8 L0 X+ e4 t( X$ X14.D& R: m7 N% K; u) c) S2 z4 l! n$ [
15.A7 C$ r6 I& I% c1 u
16.B0 |+ _* e- R. l2 f: p
17.A
( T% {" P, E, f: ]2 Z18.D; L7 V @4 e! V' ]
19.设计模式
" L" H/ j9 W P e C20.D( ]$ m( G! @2 Z( _+ d4 h* Z
8 k% o; M% J, Z* M: L: R6 |2 R! \
6 T7 ]- ^9 t; X3 d% f* u/ u. X
% D8 n. R$ L3 ^5 I- f答案详解* W! N0 L* ^ f% F! j
. {) ~/ Y$ U G1 N1 U3 O& L; J( I1.类是对象的蓝图(对象是类的实例)。
, i) H s1 ~$ K. x( X) ^( i2 a. u
( ]: ]$ B& A; C; ?+ B+ A' g; s2 t2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
: `' O) H, i& u7 X0 y% b/ Y
! a B2 }$ `5 G( i3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。0 @- d' V9 r% I' m' I
# y' }6 G' T. F/ L- M4.单件模式可以限制一个类被实例化的次数。' h5 u$ T1 U) y! A* [( F
7 R+ E; M) d# Q6 k) u) j5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。3 T# ^+ J: \- ^* p
/ v; r+ [4 w# @, n& c
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
+ }! P5 z4 n- N, z0 M1 t7 C# }3 q) [8 e" T- K. H/ p
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。+ l r/ J: h- n- n) ^
2 V& R, C. N# [4 [4 _8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。' `' `9 s# r2 k$ N k
4 r# t3 E+ X" u0 ~8 i- h9.PHP4中没有题目选项里所列的任何一个概念。答案是D。; z' {: ]) b% P) n; Y5 ~8 P
9 h6 e; c/ K& ?* H. m/ ]! f9 \7 ?10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
7 O9 l8 J+ i {( @& t
4 t) A& n2 ^9 A8 _11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。- g3 P0 ]7 B0 b5 Y& P
; E8 n; Z( c/ q, P/ u" g12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
4 R4 p9 {- P" `+ X- o" }. l, c
0 X9 U' T- `* S" f* A13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。, n+ P( p7 P+ r- U# n9 K
; {2 T8 r4 j& w
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。2 {/ c) u, K7 Z
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
& B8 ^6 w/ n7 D( X function reduce_fraction(&$fraction)
! P1 t8 B A7 Y W( o: N答案是D。
) O2 F6 ?; E2 ~7 h- l) r8 @7 i4 M' B c( E3 w0 `. R2 T1 F
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。1 ^1 k, H- S3 i
, B ?% `0 p4 \" `6 M7 F16.没有。PHP4只允许声明静态函数变量,没有静态类变量。# u. h( {7 n7 q+ n; o/ U1 I- O4 s
+ z1 k) c; y7 o' _9 l
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。0 e E. T4 e+ q3 x* `( T
9 _. v! P* Q1 l8 ?& U18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。. W0 q/ w; o" W
' }' j4 y5 K' @7 D: T" f* A19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
- S- Z" s5 k6 n% I4 c+ n$ H( e& a% @5 G, J3 g8 z
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|