|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14347
- 金币
- 2459
- 威望
- 1647
- 贡献
- 1407
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。* {, _. ~- R$ }6 D. m3 q3 C
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。; j& p) _ ?- Q
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
$ Y- F6 B) T/ I* ~1 }& d' y; x$ {( H* B q k+ H& [
问题
+ Y- u1 g/ s e
7 k! R" h7 @* E6 [9 H4 z' z/ q1.对象的蓝图是什么?
2 r& U9 p; `. A: w! h. B! L3 v) h
4 Q+ L/ t6 w" B答案:____________( ~ `6 m5 l5 P3 ~; y1 R; [
0 O& Q4 I8 h+ p5 U- N& Y
$ x/ ^$ ~1 s1 ~# t C% {5 b3 ]: u2.以下代码执行后,数组$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
2 N V: h6 u# D. B# L; X& SB.b
7 F5 [' |; f# c, pC.a
0 O0 w7 J M% HD.d J) Q1 x0 R Q
E.e
5 C4 R" G) r4 u5 D9 r7 D( _. c, ~7 `+ e8 I
. H" [! F1 F+ V7 ~; p8 _: \" P2 Q! n
3.如何让类中的某些方法无法在类的外部被访问?
4 o: y2 ~' Q) [; w" b+ R1 W
6 W( z* Z3 H$ A4 R) SA.把类声明为private: j. C$ w. h2 V$ A/ \# |1 G; w
B.把方法声明为private- o/ ^& [0 @0 D0 g1 U5 O
C.无法实现1 W) p: d' C) @" G* @! h% T/ |" C
D.编写合适的重载方法(overloading method)5 i3 }6 q# i- j* m* F1 d
& V8 Q) r! i, ~: k0 q
5 w4 |. f- @$ X4.哪种OOP设计模式能让类在整个脚本里只实例化一次?, T% g% b1 v" A# o, ?) W
% t* Y0 O- J5 A Q3 o% F8 b9 x2 M+ DA.MVC模式+ C4 D* g% r/ F' u) ?4 Y( E8 T
B.抽象工厂模式(Abstract factory)
7 I7 }7 b' @0 g- C3 f& pC.单件模式(Singleton)
# M5 j1 d0 U! h0 i: c; I. iD.代理模式(Proxy)1 D$ X) i! c2 G+ M8 c% ~2 z0 P* \
E.状态模式(State): j$ y L4 m, }0 p0 A! x' C
+ j0 h- h9 V8 _/ I2 _0 [# [0 ]) W& a- l" B) z
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?9 A$ t+ Y& G: Q+ ?
. U: V3 T. x. Y5 p, T% t: X) CA.1个5 Y2 o R: Q( V6 V
B.2个
1 ~( {) u3 l- o0 r3 K, yC.取决于系统资源- y1 w3 o O( i- f* L S
D.3个
! b' E# [/ |* d- g' TE.想要几个有几个- B: K7 b6 T; H) W% g. t5 P
0 N @/ n3 l8 ?- P& N& X+ `
/ s; ]/ Y8 a+ A# m6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
6 t0 \; M4 e2 X* \B.接口
4 T: r- }$ d1 y4 M. ^ kC.抽象方法
' e9 s2 m# v8 rD.Private方法
\2 B- Y" |4 I) k6 S3 D. s. V: dE.函数重载(function overloading)( ~1 i% H& d/ b/ C9 R7 ^
$ C, g1 `/ r2 o" g3 ^) G1 j; k
1 Y' \% i" X5 {2 n( g! ~
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
0 c" @/ g @# w D- P* s
; j8 z/ x, u4 V3 U( V: LA.__construct5 X/ }. P% R# f: Y. t7 u' U
B.initialize( M7 M. l$ X' S! b/ Y! d% E! O
C.testclass: @. l: n! f1 O$ O3 ]" B6 N
D.__testclass# S: b' ^0 L% K$ w$ @, t6 x2 I4 \
E.只有PHP5才支持构造函数
* ]% z, e1 o8 P! m" \$ i; H$ i2 ?
8 m; D! `& l2 ]; g$ n
& I& D' B/ ~! B; y; e" H8.一个类如何覆盖默认的序列化机制?
& g7 t5 ^. J4 k+ c1 J% U- _) a6 M8 H) K2 |3 D$ m
A.使用__shutdown和__startup方法8 [' s( n) U% u! F8 C
B.调用register_shutdown_function()函数
* j; h# O& F# n& ~C.使用__sleep()和__wakeup()方法3 w$ C' w: ^3 U% B: _* t
D.无法覆盖默认序列化机制8 T; S# O1 M) A+ q
E.使用ob_start()将类放入输出缓冲中# I. j6 ~/ n0 H! R) |
6 ^) k( k% z( c E8 z: n. e }
. V# a/ m. W6 @" D
9.以下哪些面向对象的概念无法在PHP4中实现?
, Q j# @5 k# [! B! p. W1 B. l0 Q
5 A; u: m* x; w$ J0 e9 p; L@抽象类
! f8 n9 N' X9 R4 w' S: o# o@Final类
: b& h8 {+ @1 ^( U' Y@Public、private、protected(PPP)方法1 i+ C" p3 p4 @' o
@接口
; Q/ u6 _% F2 N2 Q0 ^4 }% `
8 ^5 u! z9 `/ R# e6 V& \" KA.抽象类
9 P$ S, q, a$ [B.PPP方法
) _7 z i. o7 I9 TC.PPP方法和接口
9 R0 p3 {; T( U ]: }4 z( JD.以上所有都不可用
. h3 }$ ~* A8 Z+ M5 K1 ~/ NE.以上所有都可用
* O- B3 q4 A2 Q, [9 W8 l1 U2 t( f9 T; |) M
' @5 t/ e1 v, x3 ^& ^2 N+ Y
10.如何在类的内部调用mymethod方法?
% a4 a) a) ~' Z/ ?" }2 ?3 y/ g P5 [- G% B* m! U
A.$self=>mymethod();
- A r5 P6 \, R9 fB.$this->mymethod(); V; P0 E5 X: ?1 `
C.$current->mymethod();
: Q/ w- |; A+ a, x) ^D.$this::mymethod(), Q% P; p5 J. o( C; J) p; s# y
E.以上都不对" V# o/ [ b5 L7 G* R2 P! V4 {) B
0 w: j( g; @$ F& v
/ X, Z2 x" d! W11.以下脚本输出什么?-
- <?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" q' I" h$ Y. B1 k9 r; g! P7 T9 \
B.Null
) ~- J( `/ V& l4 H' e* ?9 jC.Empty r2 }1 X; z3 n9 i
D.什么都没有
% {9 y$ w: H' z: _E.一个错误5 u7 {" d$ T0 _+ I0 H
/ t+ M k5 E x) j. }: ]+ v. F N5 b1 j2 k: v
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
2 W. @- \5 B9 X8 `( @B.54 ]* x/ r3 [; I0 M4 E1 a
C.2% R' D* \1 _. k
D.Null
" b1 G" M' O7 G- g3 P. {5 Y% pE.什么都没有: b) l' _6 J# l2 o* q- B4 X, z
* L; S) l9 j, i% d) J# a1 o
8 A7 Q. n0 H: n6 a$ R7 p6 u6 q! f13.以下脚本输出什么?-
- <?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.55 U$ ^' J( D1 v ]
B.10
$ O) X p2 |5 Z3 u2 J' G6 W( p6 N3 TC.什么都没有2 T# j& z. X9 \% R% b
D.构造函数将报错
" ~- [5 D) [5 UE.510" e C- J" S. U* q5 o& Q
# [0 r$ T. M0 C
$ z( J ~$ ~) ~- f' H14.考虑如下一段代码,执行时,$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函数必须返回一个值
: N0 z. t1 u4 EB.reduce_fraction函数必须接受一个整型值
* I& ^2 |' S! ]. {8 F2 a! {C.gcd函数有问题1 t0 {: n4 p& q7 ^4 H& B
D.必须通过引用的方式传递$eight_tenths对象* u" w6 X9 J* e* s
E.对象的实例不能传递给方法以外的其他结构。
) j& w4 w; d% J6 @ t3 I' P8 `0 W* D
7 S" Q' Z, @4 q) w+ [7 T& ^! K- o2 ]) V: V. M8 x+ h, l8 b* a9 i
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法3 j, V+ V a' n# C
B.生成myclass的实例并调用mymethod方法% ~1 K5 H5 T$ ]) {7 E. Z
C.产生一个语法错误/ S- c/ Y5 y1 ~6 B4 f, i
D.默认myclass类最后被创建出的实例并调用mymethod()1 ~/ }& O- r! P& ~) Z8 _6 D/ Q
E.调用名为myclass::mymethod()的函数4 U6 `3 |! Z1 g9 k9 c$ U( H
: z7 M4 |2 _9 V% ^
- u) }' z6 ^, |8 e; u* s16.PHP中有静态类变量吗?0 T3 q! L! }" @9 Q! ]/ s
0 Y& l$ s3 q+ \( u k" bA.有+ k7 d7 D @9 K& J, v
B.没有6 R0 d8 l" m" K3 L
z3 R7 I- I. j2 K
& [+ c; W; T. I: 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
8 x4 }( O! L. B" c! v( ]B.2( h: X6 ~( ^. k- K1 }" s
C.一个错误,因为没有定义a::$myvar
! @4 t1 U4 x# H" [# Z0 nD.一个警告,因为没有定义a::$myvar2 [2 J. x* g: z/ I* A' J n/ F
E.什么都没有
2 D2 n+ A. c" s3 ] T0 ]+ \% n" n' E7 r( u8 x
r$ a$ M( E: u
18.如何即时加载一个类?
, z0 {9 P& a' u8 J
* |. X4 ?' J0 N$ M4 FA.使用__autoload魔术函数/ }+ I" [ e% ]) i
B.把它们定义为forward类
" ]9 }8 u! \8 P3 A& e8 pC.实现一个特殊的错误处理手段. q; Z B+ r: b! X" o
D.不可能
! a; C, @& X ?E.用有条件限制的include来包含它们
V3 M! V& j$ i5 @4 K
; Q: l0 m; z [2 `! X% t1 e& R" i; T3 ]- v! M: C
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?+ r# `6 C1 Y2 d& `5 N
) S) P$ C6 h# `& _; g! g- j
答案:__________& U+ P; r. @3 w- \( D6 N6 c
7 s+ ]. D) e q' O
, T# _8 N( j2 W: ]# w+ e2 B: x) m
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
+ G/ H' e2 x4 R3 oB.一个错误
- G. @& ?* R8 V- Q2 x8 @C.一个警告' v' ?% z( V' ~" g P3 j/ u W
D.什么都没有( ? d4 P! _" ^/ c9 y6 e. k. N
1 Y% p; G) G6 b/ h* W m- V! U
3 S' |9 X9 b5 J+ m# Y. t: ?1 F) p2 H! y3 Z
答案速查 a5 [5 I% y! F1 N! [+ W: [% E
1.类4 j) W0 l5 e: c+ |- X2 L! {
2.BCD/ i3 B" d8 s+ S8 E- \ P
3.C8 G% e% s" d i' ^( H9 o# Q
4.C
5 P+ [9 R2 A- J: ^( _3 I& k5.A) n6 |- b0 M( v# W+ o9 e. m
6.C `6 |9 F7 T5 {8 e9 U3 y0 f# {- z
7.C/ l( X" u+ r! z. |3 H
8.C
( `' K9 b# e( `1 t9.D
- G, W5 Y; e" x10.B
* H- P2 Q5 C% o, \4 b2 }( Y5 x11.D( |4 z9 t- ^! j7 [7 U( j
12.B7 d! t* [: ^0 V+ j. [' H( h6 w4 P0 X
13.A
4 c4 P" {7 ^3 s3 }: K. M14.D
1 N( E9 J+ a0 X+ ?- u+ Z1 M15.A
+ J$ k/ v$ j% }16.B/ @( [# w. V0 ` V6 Y
17.A
; `4 l) Q: w, T r' q18.D! i) a. m" I+ \2 I3 }' Q
19.设计模式
: ]* [, N* q. Q2 I6 F8 J20.D
o% h6 N- S6 A5 }
& A. c$ |2 m* Z1 I* ]% @$ `% G7 l: }/ R0 {/ E3 p
5 @! u6 |+ {1 R* A$ w: d& E
答案详解. z A6 i. m# I9 z& }
d% |# o v/ x# w# Q( z
1.类是对象的蓝图(对象是类的实例)。
: u8 E8 Z1 @8 s7 Y
8 Y! g+ W9 x5 p* M9 \& n2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。* N: z" }. y( n+ D" }; |
9 I4 ^9 q" R8 x5 E3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。6 P# x* i, T7 k8 C0 l4 p7 r
; Z; m. @' q1 ]/ N, Q; u4 X
4.单件模式可以限制一个类被实例化的次数。
( ~" ]- r9 k$ @2 P
6 N3 j4 q _4 j* U N4 b' ?5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。; h& q3 \, ?* |2 J
9 f8 D$ C9 v* h Y7 s8 F }5 {' a6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。" K5 G9 {1 F# @7 c% Y: x
" e- d+ D1 e' N: y9 o) n7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
5 q s, L; v1 }, p' N
, Y9 Q/ r3 a; K6 q3 V0 e4 Y6 b8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。. h3 U5 D; i# e
/ @( z/ a5 L6 [2 n. o
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。& k8 y; V4 F4 P. o1 t/ f/ T
& k S- k2 }5 {) V& I2 P6 j5 _ V
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
6 T! G. t+ X+ k+ Z& U% m0 w% C& w
5 y* t1 c7 v* m# E2 v11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
' B) x8 f. {6 J! D# P; D; \( {+ H3 V O% |( C4 u
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。' J% P9 c8 s4 t& \( z; o
$ ^- h2 _. n+ e4 {. O: I4 |13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
' ~3 C$ c, \" Z% \
- t, F2 p5 w0 C& r14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。& ]! G' P- a( Y" ^' h3 P/ e
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
- y1 {) C$ }/ p6 V0 ^ function reduce_fraction(&$fraction)2 d* @& U5 ~9 l; D
答案是D。
0 ~) e# ~# A( k4 g2 F& u
- g7 H' K+ e/ a8 f, `% k4 K2 k) O0 r15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。* U1 t! I7 ~) O9 ?* A; W
1 u! P' }$ L$ D& {# a16.没有。PHP4只允许声明静态函数变量,没有静态类变量。* [) H: c) V( R. n! [$ A6 w- ^8 v9 p
0 D, A- O9 V& w2 n6 ?4 L! s
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
+ T$ L% x- s3 `5 Y" `8 B. L3 }
! _" ^6 y/ F- ~' F5 Q18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。" D: f3 S$ u9 l0 U7 i4 f: p
4 }2 e! @. R; N0 U9 _
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
& p! P& W, s+ x9 N2 j: `. N+ W4 j; J( A, J6 h
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|