|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14389
- 金币
- 2480
- 威望
- 1647
- 贡献
- 1428
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。7 q: a# ^* ?/ J* P3 U. S* K
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
N, c4 @' r/ `4 |. R/ U- [$ ]0 ]本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
/ ~; S5 l4 T: A. C" D2 z; p N1 s7 W1 K1 Y4 m( n' E$ W
问题 B+ e4 o [/ w2 Y% J
) Q5 ~( s- W1 m; m
1.对象的蓝图是什么?0 B- W. {8 w& q8 e8 b4 z
4 C& m$ \/ c% _6 v
答案:____________2 I& ^: E( i% g# R9 v
* ?) Q( ^$ j' Q+ O
2 c/ e1 z. M0 s/ a2.以下代码执行后,数组$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
+ V2 P0 o0 t7 W6 T4 \+ S4 zB.b5 O7 E/ J6 O" f4 _/ V
C.a
, t2 I; D i" J1 LD.d% D7 S) d/ p2 b2 g
E.e
3 T$ ^" f/ p$ T* C2 @: |
5 K+ A! C: \; p f. @7 J r6 g4 m0 I: f) C% c' y0 M$ a) [
3.如何让类中的某些方法无法在类的外部被访问?, q2 b( `! [. C
& h+ K O5 b( G' D8 S( xA.把类声明为private
# l$ j7 b @8 aB.把方法声明为private
8 P$ {" H7 Q- @# ~! {0 t; [C.无法实现1 Z# Z4 v- l9 i2 V: j8 H# v5 E
D.编写合适的重载方法(overloading method). J- D4 }, Z8 ?5 c# m+ ?
- n( z" R/ S! V% m& P q8 @
- G* m" A; m/ Z( b: b6 G4.哪种OOP设计模式能让类在整个脚本里只实例化一次?+ O2 C. X8 D4 ~7 }% Q
6 {" \$ j, e+ T
A.MVC模式
' V# H0 N) f0 h( z% T9 B; x6 HB.抽象工厂模式(Abstract factory)
$ `( l; h/ d( k! EC.单件模式(Singleton)( i% z" {4 h M. p" W( o l' a$ H1 }* T
D.代理模式(Proxy)/ S5 c. k0 x; S. O N4 R7 m
E.状态模式(State)2 o# j' ~) v% a5 n8 L0 L
7 Q7 N1 k. L2 Z. ?9 z
* g8 x6 ~5 }) q/ e
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类? _0 N# f# g- K% k, ?: G
9 z" [8 \ I5 m- y1 k4 [- RA.1个
5 p/ R' C0 P/ d/ yB.2个
) W* j! v4 o- {7 j/ J. z3 \C.取决于系统资源& Z: ^3 v5 Z' j9 r$ ~" e: Y7 r3 a
D.3个6 J3 f' o( A' C, M; [
E.想要几个有几个6 t$ {; E/ H2 l, p7 Q
. D8 T7 y& A' m0 l; d; {
8 D: Q' T/ ?5 C% H) _7 d6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承. u7 `: y* z/ @! \- M8 D# n
B.接口& h/ A- ^( m: X1 f: y
C.抽象方法
2 _' ?, s( E5 d# ND.Private方法
8 {- E# H% _( T Y! [E.函数重载(function overloading)9 B6 m+ u8 v9 @& w
8 y& j" C# u& Y) F
6 Q H" C' G' x1 z( {) i7 F
7.假设定义了一个testclass类,它的构造函数的函数名是什么?. _- f4 o$ R( r( K
$ n& z6 v6 n7 [# r6 FA.__construct* G7 @7 v2 A8 C5 d
B.initialize
/ x& C% |9 k% A4 s3 X& ?: J1 R) PC.testclass2 B0 X$ ^6 \) `7 `4 g
D.__testclass7 j3 H+ I; y, d! c/ `% f2 D
E.只有PHP5才支持构造函数
5 A- X& R' `" x9 H# Y# W b3 s4 b
4 R' u$ p6 X. L0 g9 h' x
8.一个类如何覆盖默认的序列化机制?: R: D1 b+ J m: x; p8 e
% U: d) T2 \( n1 H. d) A
A.使用__shutdown和__startup方法
4 g7 M; S9 ~% w7 q# j! [B.调用register_shutdown_function()函数. m8 h. {8 q% T
C.使用__sleep()和__wakeup()方法
6 W8 Z! K$ Q1 B3 `1 `D.无法覆盖默认序列化机制; F* [& T- w) D# Y* }
E.使用ob_start()将类放入输出缓冲中
$ `/ D0 G. [! w- B6 y2 g( N$ @! c# `
. ]8 Y0 }+ ]! x1 ?* e5 y9.以下哪些面向对象的概念无法在PHP4中实现?1 b+ U9 U: c% g6 r- z2 M
+ E, E. {& U1 o& `
@抽象类/ S7 Z" A0 W' q4 ]- ]' v" M
@Final类 B7 |. L- x: n& N# N4 e
@Public、private、protected(PPP)方法! h0 X/ C+ N3 D, n
@接口
/ j3 i; d2 ]! ?4 R$ f
& T: ^* K# W2 Y: @1 m9 z4 Q$ rA.抽象类
+ {4 }" K% W9 S) P n% [B.PPP方法 f6 F# ^ p, r8 j' z
C.PPP方法和接口 A2 [) |0 k$ V/ M+ v$ `( q& q
D.以上所有都不可用6 V+ n# B4 p; Z! r: N
E.以上所有都可用8 K, V8 A4 W! `3 O! J& M, H5 {
- s6 o( }( F4 V' n) C1 n: t, f* O- ?, \- n
10.如何在类的内部调用mymethod方法?
* k8 V$ }, U9 F1 q
, ~) k6 C. x2 y* yA.$self=>mymethod();, b- Z j/ W5 R/ o4 c/ @8 J* W
B.$this->mymethod();
9 D, r* c b2 p# x/ G1 vC.$current->mymethod();9 F7 j1 R" I9 s4 Y$ g
D.$this::mymethod()
* q, k/ u; e% {" X) ]% ZE.以上都不对
: J8 B$ z3 z2 e: p* y/ h
" i. x+ I. W: w# o$ U4 S1 P% U# k# r5 P
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
3 S2 B9 ~; P; U* e; z" F- m/ A uB.Null4 k6 k8 Z9 q, x% M
C.Empty7 j2 p% c8 b2 _" J
D.什么都没有
, Y6 z- e/ E! @) T7 c4 x$ mE.一个错误
9 I% L. l8 p8 P" r1 j+ ~4 s
8 \) R$ W0 g8 z" l }4 R1 O5 y6 w% P2 T
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
1 B" b" H! B6 u ^6 WB.5& ^" d# e R% H& d
C.2
& S& ~# L# t8 u* F9 E: P! l+ {D.Null) Q5 o/ D/ i; e1 E& L W, m
E.什么都没有
" v- |' R0 P6 K2 W: x1 H9 w4 G: J4 H$ O$ s4 U
( j6 O8 T) T: n9 ^" g, u" W _! ^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
, z% m% Q6 `0 B) H ]5 E% G, pB.10. n; f1 O" B& J
C.什么都没有9 ?1 P) A9 P9 D- o9 e+ [# ?
D.构造函数将报错) _) [' q' O# r& N! ~3 B9 h7 Y
E.510
# Y2 y |: C8 w/ M
% g+ ^# S& l: L! Y9 X( n1 N0 Z9 K% c6 {& F( w
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函数必须返回一个值
& ~) G c9 v) eB.reduce_fraction函数必须接受一个整型值
/ R! ?0 |) |" b, s4 S# OC.gcd函数有问题
# ^& x; V. C8 R$ }D.必须通过引用的方式传递$eight_tenths对象
) F Z& V0 ^0 r# X- BE.对象的实例不能传递给方法以外的其他结构。
' }2 [* u1 L/ @$ U+ t1 @) ], d/ m8 G" }
! l2 s8 t: ]1 u: |2 E' B: b W, N% m15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
1 ?5 f$ P9 m, {' w' G3 R, _B.生成myclass的实例并调用mymethod方法7 e5 Y1 j+ T4 C M
C.产生一个语法错误1 b$ |" T3 ?* F& T) a/ t; E+ b
D.默认myclass类最后被创建出的实例并调用mymethod()
. H) b- \( q& f& Y: {" vE.调用名为myclass::mymethod()的函数
) t* \. z/ y, g' X# l+ ~3 F2 T
8 l# v! B0 g. H& R3 `16.PHP中有静态类变量吗?
+ @$ p6 W& X( m6 W. b2 X3 {) i; x* R
A.有
7 C" ?: y" ^0 `+ r+ w& bB.没有* q/ _- r2 p- l8 }& Y" ~3 \
- _ V N4 ?, |3 e- G. t0 U
0 l! o( G6 s/ o# T, E& H3 ]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
- o+ k$ ?" {7 VB.2" k: r: ?, i1 P8 z0 E; |. d
C.一个错误,因为没有定义a::$myvar' r6 |4 a1 U3 e0 K. ^. D
D.一个警告,因为没有定义a::$myvar; d) Z* e5 d) @ S' m
E.什么都没有
: k4 ^! Z6 h; P, @) G' R! t6 ?9 d+ Q! Z3 ^
1 r7 S2 i0 S- t! f7 A18.如何即时加载一个类?
7 H. t! j9 h2 C
, E! F5 `3 w2 y u- DA.使用__autoload魔术函数- x0 d. z& I1 L8 J
B.把它们定义为forward类8 K8 }- Z; f. X* w
C.实现一个特殊的错误处理手段- Q. t- c) ~) j" J1 o9 m
D.不可能
* j3 w2 N; Z4 u/ c$ ]% e3 O5 ^E.用有条件限制的include来包含它们4 F3 q8 ^& S. a; D' X
8 U0 W. D# ~5 H O
: v( C6 y$ w( B5 k4 C19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
r$ r& l# B5 `/ S! n, U+ G/ b8 L: b* {
答案:__________, m( P2 {, l9 ~, _" M
' i" T4 n! R K2 L2 w
( y6 U% o- r1 r/ g- `/ O5 R( g
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
2 E3 p# T2 p7 pB.一个错误
" a u4 I* q3 N- ~8 @C.一个警告( ~* a/ O2 ?8 ]; `) d
D.什么都没有
+ \; }% o1 |; e9 |' u" ?
: P: W9 U( e+ h0 e$ t& ^3 U5 y% N3 i8 g) i
+ p' M: H2 {$ ]答案速查
' ]; R! s3 j: y6 `# x# M1.类
6 ?9 P, t* q; U/ P2.BCD( w }. O: v6 U4 _6 s
3.C2 E, |- b! ]& _8 }# J4 Y( B
4.C
. w3 U* i. w9 J+ d' u s5 B5 \& b8 W5.A: H' K+ p& u' e+ q# B3 ^
6.C. N' D1 y( }) ~# u& q9 x& w
7.C
, D3 Z- q/ n4 i' N2 a* T' L: `8.C
% ?; A$ ?: J( }& I3 k3 k9.D. Z/ E( e9 E% J! V
10.B
; Y7 }# {7 h- m5 [11.D6 y5 y% v7 h3 O. {5 E) l
12.B
# E' k, G5 B& U% g" ?7 B0 d13.A; T S( C$ S7 ?
14.D
`4 }/ r7 t& u Z* x15.A
* B$ x# c( Y2 v0 R7 |5 S9 |' u& v16.B
& f$ u3 q, K' `& q3 N# E ~7 n17.A" e1 i3 h" Y4 g
18.D+ `( s: }+ z! H I
19.设计模式
/ y/ j7 j# E: s20.D# G: @" R( N( S9 g$ t
+ T# ]' @- Z- n% g4 ~; d& c/ K+ a8 e7 h% x5 o
5 M, X- E, j' x$ r3 l Z
答案详解
& C7 l2 K3 @4 F
' u+ P4 i% I4 P3 J( C- V1 D1.类是对象的蓝图(对象是类的实例)。
. s0 h9 g4 t, p8 @
0 U4 V4 R7 H7 G# }) Q2 T! J, u; F. j2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
! ^) Y9 V# x3 R0 d- F
2 B& F# f3 q: ~" O1 g) ?3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
! L; `9 B9 Z- l6 P; D4 A* {
# r1 t3 N2 S0 Y5 f* a0 U+ |" `4.单件模式可以限制一个类被实例化的次数。
& Y. X2 S" x9 j' g0 M& V. i& Q( g0 F$ h6 H9 `! f' L4 R" F
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
/ C9 ^) |5 T: {: U$ Q, N2 f9 s
& r0 [, m$ ^6 a* t6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$ N' {5 ?7 o1 l' ~" A+ C6 |
& c+ D. t. p* G1 a8 D/ U0 k7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
2 Y; d7 b F7 }. i$ h2 D1 O' o4 y& h0 m7 [+ u5 T# [
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
3 z- P5 f2 F& h0 w; V* k" S. x& z
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。8 n4 z( ?) I1 {$ U
- x0 O" p: E5 z2 M4 k
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( z0 f) g& e$ P
, x/ H2 B$ v& v( ~11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
) ~! E( Y0 l9 o6 ?1 T/ x+ [# E. X! W4 n, `3 ~
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- w& @! }6 ^6 z- n9 P( |% A
9 [, G$ d7 m. X% b4 u
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
; _8 S: g4 }3 M1 y% k( m
$ F! B; _3 w2 P& d14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。9 c7 g: `$ x4 ^/ d* w
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:1 |1 B# p0 x; M9 Z+ J% t- Z# I
function reduce_fraction(&$fraction). U( R9 B2 _2 v. y) |! a
答案是D。1 e* M7 \5 A7 t. N
0 b0 h, @. i, Q; ~# G+ Z7 g
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。+ Q& R" n7 @5 I0 U' P
/ c6 G: h* N) X4 j1 D- n; Z
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。5 u% K% ^( `( }2 a6 d4 Z
/ W: {8 ?, w" s17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
% e( T. ?$ c) r
- Q7 F6 b/ \3 `4 N1 A/ g18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
" G- J" S+ T, d( z/ P: T2 g+ x. Y8 R' F: r2 e4 c- J7 w
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。4 u, V2 a: X G( F5 U3 ]
& i/ _: |5 g7 v+ T! a# x2 k! q20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|