  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14171
- 金币
- 2376
- 威望
- 1647
- 贡献
- 1324
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。: ?' T, W3 Q: @1 y5 y/ a
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。9 v6 r! ?; f1 d7 c8 S/ f
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。* i$ x% d/ X5 B% H8 |7 q; A
2 p' W. O" R8 F# l1 z3 ^问题& i+ g! C" O2 m4 B4 h
; v% x8 p* F$ _: I7 _1.对象的蓝图是什么?! U5 Z; N5 a$ C5 T
- N3 b7 |+ k; Q {4 t
答案:____________4 o; ~: U8 i( F' }" p% u8 Q
- I1 ]7 `5 i: l0 S; `
; T' z5 `$ `" T' k6 P I3 }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
* ^" M+ c+ \3 g+ S$ v0 O! nB.b
6 N S @" x, bC.a+ b6 n# H6 K. N' `/ Y u
D.d# V/ D: c( w! ^$ U# w% C8 C
E.e! ~$ b- Q, ?* j& B" _
1 P+ F' p% U6 N# ^
7 ?0 X, w F2 g: _& z, G
3.如何让类中的某些方法无法在类的外部被访问?7 O' }4 I1 s4 Q1 T4 J" }: P
% O6 O; K9 V+ d! v- T& I- zA.把类声明为private6 z4 w- c# P- f- a0 x8 ^$ l A3 ^
B.把方法声明为private
5 R5 s4 D. n! w( e( W8 YC.无法实现4 Q: j1 [& d. m0 L' c7 o, |
D.编写合适的重载方法(overloading method)1 T: Y* G, z4 p' S9 @
7 l+ f3 @$ S, A( ]9 Y$ ?. R7 G3 h) j0 \; T+ G
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
7 J# _# N- U: I& }' d
6 P0 T7 J' e2 S2 @A.MVC模式) Y! _3 G$ u Z, {% t# m# A
B.抽象工厂模式(Abstract factory)/ u$ v$ ~& c0 u5 r* }6 n( [0 I: s
C.单件模式(Singleton)2 G0 L5 J" A+ ]- k7 b2 U- I
D.代理模式(Proxy)
. o/ n3 f0 _( C5 bE.状态模式(State)
5 I# t3 M0 y7 o& G/ i
: K# i5 h/ Z) d' a" t; G* e+ z" S' I) H8 F
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?5 Y" M3 w( Q$ Q
& r% Y, \% Z& {: x, _8 O
A.1个( C3 v4 w' L) u6 x
B.2个! ]3 h3 J ]* l$ g, x
C.取决于系统资源
; B+ j$ i8 I" h8 f, ED.3个
. f% @" S9 I7 q3 k: H# `5 j0 qE.想要几个有几个0 o% B* W/ a/ y9 W( Y3 ?. s. f& r1 N
: b6 w0 R; ^1 n; A& o
: z, q5 r% i! N6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承& m- f: ?: E) H
B.接口
e' Q6 e6 G! @! ~- Y. |C.抽象方法' T: L& E4 |4 ]; V' b( a) I2 ~ U
D.Private方法
2 Y- I0 Z& ^; P) rE.函数重载(function overloading)
! Y( {4 B; }) s! q- p& i; R
& q. R" Y( p* _( J5 n# i8 n
# ~* h' G" m; M+ c% w) K7.假设定义了一个testclass类,它的构造函数的函数名是什么?
) F k# i- s+ z8 {. e1 x- ~3 y4 L' G9 x; |$ i
A.__construct
m) Q- s b" M8 YB.initialize
" w1 ~2 B" ~2 _2 }3 M6 M6 ?5 t( `C.testclass
, A* g2 e: t7 H0 V1 AD.__testclass4 h6 `: r; V; _- @3 I
E.只有PHP5才支持构造函数+ }8 n+ h3 H3 F) B* S; u3 Q
5 g \8 I$ I4 k* f& C: T
# M3 }; a% S. s% G l8.一个类如何覆盖默认的序列化机制?
% v! a, C( @! R. ^1 w5 o; T
' u$ A+ g4 A4 G: jA.使用__shutdown和__startup方法
4 E0 Z- @; V3 | D7 VB.调用register_shutdown_function()函数
t( e" f$ ?+ s/ ?0 aC.使用__sleep()和__wakeup()方法9 H7 K# o1 R* O& }/ f2 ]' a% n
D.无法覆盖默认序列化机制$ O2 v# w* N" f! y
E.使用ob_start()将类放入输出缓冲中% T: w" _+ J% U* i) V N5 U
5 U9 Z' i* F$ X: g9 a2 z/ J* E) J; T" U; G. T( y
9.以下哪些面向对象的概念无法在PHP4中实现?
0 H) P+ ], X5 o! X: N: l2 ~9 M' h; h' o
@抽象类; e1 V5 r4 r# V" P6 C
@Final类
) ?+ M, V1 W# A8 h1 ?% L2 v; L4 \@Public、private、protected(PPP)方法
: f0 y" t2 v6 G2 ^$ u! a( N@接口
4 K8 b! F: ~' I0 f& F8 x* M: P+ s# ~
A.抽象类& ^* o0 {$ f/ U5 O# ], i
B.PPP方法1 M( ~# r# }. g8 o( t% u! r% [
C.PPP方法和接口5 _, E' }6 _* w
D.以上所有都不可用
9 D) B/ \8 [! t2 ?7 T [3 FE.以上所有都可用( X1 S1 ] j3 h. g: D g+ c8 C
# r6 R& o" @0 o3 p, _& S- b3 n# x, U( ~& G6 w9 {
10.如何在类的内部调用mymethod方法?+ P3 {( r0 N" l3 ]) T) h
. K5 |0 @6 z# R' m" N% C
A.$self=>mymethod();
3 o' d2 Y( c; B" zB.$this->mymethod();
0 H# d" Q7 ~( z& HC.$current->mymethod();
& `9 `" v4 k" y1 s. X+ Y5 Y2 vD.$this::mymethod()8 j% _$ K* X+ [' N
E.以上都不对$ ~, s+ h5 n& B3 b
% c' c/ V8 g. A; @+ k& y
. r! W4 `5 O1 l11.以下脚本输出什么?-
- <?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$ w' N! p- {- D. M! q( u. A
B.Null* O! [9 R- m' S
C.Empty" g4 N2 C; ~; O6 {0 o. ? ^* H6 S
D.什么都没有
: A/ c1 h. h6 k3 N2 Q* t' ~E.一个错误
0 z7 S' v, F9 s) W: U2 j# H! G
7 ~4 w7 w) V7 M5 _; g7 S3 H+ c0 i; x3 L# I* W
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
/ @7 j8 f* ? G! z4 [B.5
" ]* X* f/ n4 I) g OC.29 ~0 S, V- x- i5 q. \* ?9 c* x. U! s
D.Null2 T# U% A$ d9 Q" _4 ?
E.什么都没有8 A- y' O$ f# B
/ }+ N1 k/ O2 C. s; k" [' V0 m0 y, G" [
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
% Q7 U; \) P2 c; [* b ?8 ]B.10
1 d! @# l& \# x1 {$ a$ K7 yC.什么都没有' L) d* S$ g% c4 {! f+ n6 c
D.构造函数将报错
$ P6 G3 [% g5 m% {% K' e( G! d: M# gE.510& T ^+ y2 D) \6 k7 V2 V
, w3 U1 S0 V8 a _& P
: V% \# Z2 ^* K1 C7 }! w14.考虑如下一段代码,执行时,$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函数必须返回一个值7 u6 t# M" @7 V+ y4 K
B.reduce_fraction函数必须接受一个整型值
1 y w* D4 I* h1 o$ @' V' lC.gcd函数有问题
2 Q) M0 K) e/ r7 g/ m+ m4 AD.必须通过引用的方式传递$eight_tenths对象/ \0 C7 |( p* m, x
E.对象的实例不能传递给方法以外的其他结构。7 T" L. v* c$ E1 }7 H( C
4 Z9 \: H- v$ T0 }/ j N+ u8 C9 F4 z# N/ q) V; e/ b
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法: g: s; ~6 M8 Z) R% R
B.生成myclass的实例并调用mymethod方法5 Q6 W/ P" }5 d. y0 g
C.产生一个语法错误# w) D8 u8 H- D( u3 X4 g( M
D.默认myclass类最后被创建出的实例并调用mymethod()
6 \5 H6 ?9 ~4 b5 `6 M. KE.调用名为myclass::mymethod()的函数
) b$ P6 t9 }+ I" B) f8 E% Z) f. u& k
J r/ }- g) s! ?6 I" A) c% d) w
16.PHP中有静态类变量吗?/ P- ?8 ^2 I6 x3 A. R+ I+ E0 @: e
% X2 N. r+ ^ ]8 n# q9 }7 [1 SA.有
) b4 F, f9 n N. e# \- r- sB.没有: b. _* O0 k! c1 L9 j. N
3 z* y7 I" ?6 @
7 ^ w1 S, w* M- g17.以下脚本输出什么?-
- <?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
1 N. }( O6 S! J! z4 P- G+ YB.2( A. y2 q, ?# Z4 B. n, ]# V8 [
C.一个错误,因为没有定义a::$myvar4 z: P9 g3 A% F2 c) q" m" M3 G6 A, V8 }
D.一个警告,因为没有定义a::$myvar! O4 L+ M* |8 v% I# H" @" I5 R; L
E.什么都没有
7 x. n2 q ~5 Q9 ]3 U
! }. ?5 z8 M. F+ S- e4 H2 e$ c2 P" U8 J3 n) e% [0 {9 q
18.如何即时加载一个类?
/ v) l! T: M8 U2 |6 E3 Q. v
& f1 C% U/ p, J% C5 gA.使用__autoload魔术函数7 K( e4 ~; H. h) Z9 I7 Y! Z P( p: n
B.把它们定义为forward类% i% N4 R; Z7 q! s" C2 z4 \- V
C.实现一个特殊的错误处理手段
# o. [7 D: n2 p% VD.不可能
) I x- M1 h2 H& lE.用有条件限制的include来包含它们1 W8 ^6 d/ x. f4 B2 V, I' u: k! S
. J5 l) b5 l* H( c/ q1 r8 u, Y7 w- {7 F! A; e
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?# L3 w- Y' ]: e2 Z
: i% i6 {2 }* @4 F$ j# v2 U 答案:__________& d" J! m9 i: s1 L- R6 n
- h A5 v" g, d# ~4 r. R
$ H" j$ D; j$ p, n1 H2 I7 H
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
0 E/ w5 R2 J+ E" gB.一个错误6 A: A% u2 {. b' o( h; h+ r, T
C.一个警告; ^$ _4 t4 X# n
D.什么都没有
. I1 }* j# n) ~
, @. [% H0 b" Q0 F2 n8 n+ @. I
! L0 r$ |3 V' e0 ?* ~: i; D
* Q( B8 G; W" K2 j9 h答案速查
7 w2 s1 Y, r/ R1.类
1 D! e% P5 g0 a% C2.BCD1 e% R- V. ^% A8 t
3.C
2 ?: ?4 ~+ g J5 D# R% s) g& y4.C, v% k; g2 a' M
5.A c& C$ ]. z6 E* P8 o
6.C
8 E, V) a" \7 @ U7.C$ W. q1 J/ D/ Y
8.C0 M0 v/ C( e* t: ^( t
9.D/ g7 O& d$ m$ v/ R9 ~8 t
10.B
! D4 r7 k" L) m3 S j8 i5 X11.D9 F) s3 n! R$ p
12.B# J4 Y* {& h; }0 J% ~' T) p: P
13.A
* l/ Q6 y8 A1 u {2 s* y f14.D& t7 \( w3 j( W9 y, h
15.A) Q+ P6 j! ?( E! {# S( i
16.B% \# X5 U, c4 i* w+ I4 S' w
17.A0 g& z" p9 H$ ^" N
18.D. b9 `6 v$ f* [: f3 ^/ i" P
19.设计模式
9 ^2 {4 q# _ q2 n+ g8 l20.D p }" ?5 O' O) M7 Q( @
3 H7 w) X. s" l J
8 s& j$ R2 |5 a8 L% b" r' _4 }7 R: A- ]% R
答案详解
; X8 L$ R# t! N) z, p7 Z/ r! V
) a- I. [2 I. u5 ]6 F1.类是对象的蓝图(对象是类的实例)。& Q1 l8 Q0 g1 H( H8 v0 Y9 {8 c0 |
% n1 u N. q! I' Y# [0 ~0 r7 z2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。* C: V. C8 I! S* t$ \. C
) l& U# O5 P& X; u+ Y
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
; _& ^/ w6 I, ]* y
, V6 a- v9 {. h, J; `' O( s4.单件模式可以限制一个类被实例化的次数。% u; W" f) x# p6 k
) k' o' B* K E( J& s. I0 G2 B5 Y5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
, R0 `2 t; m7 R3 \) b9 l6 m" j' X5 E# K% p
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。# B) g# t! A- K% H
" P9 Z3 P% z7 F9 X4 x8 A
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
4 g+ \4 _) s9 G, K- B' |. F! B
3 V1 R' U9 n2 f" j6 O5 J D9 x3 a8 z1 ^8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。! ^+ S( G* H! R- l; `+ \
) }3 I3 T v" k6 ^
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。; G1 S2 V& G @6 J5 m
+ G6 X5 Q* f" s7 J% l10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
+ v! p( r' E+ j5 e- k0 E' P3 H! t7 m w- z; Y( F
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。9 ]' Z. q1 ?/ Z
* u8 K8 N$ h: O5 k8 `12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
# V& a# }* W+ c5 U4 N/ ~% L0 f& u$ i, n" D" e5 s1 J
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。) { K! G* L% ~2 c8 C
6 [5 N+ X6 }) d$ S3 U i; i14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
( |$ v4 S$ t) o' l& E2 ^回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:* L9 H) e6 {; M7 ^" {% ?
function reduce_fraction(&$fraction): J" G, g0 Y( G- x' M+ ~
答案是D。9 G% ^9 F( [, S, ?9 K
: h, I+ F* i3 U3 u15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。3 S' M& e4 v1 I9 q8 n, X* ]" C8 @
' H& F) E. h }6 V- f$ r1 Y* w
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
' Q) H- N3 H: j9 z4 @6 U" O
; Y$ B1 l; ?$ m17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
B) b: t( U% T7 _* l# W; ?
* t7 U. n3 o, @+ q, s/ }2 [18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
; a% M1 c0 i# r( z9 P( a
; p" D& R; ? Q19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
) R- y+ z! f% M+ p( @ l! ]
2 R* P6 h, Z" Z20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|