  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。: c' k1 I% P k1 Z/ B
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。* I. }4 ]) k% a S% }% {* b
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。9 ~1 P7 @5 ~ O: }+ @ L
& |" E6 ]: a& b' S
问题
6 X) B1 S5 o1 p# \1 k6 q, p5 s& X1 z2 v2 C2 a3 @' d+ g6 E
1.对象的蓝图是什么?
2 _* M* K% k, @1 H% L# a6 z+ O
) q2 ]4 r, m4 m: A. N d3 n答案:____________: I" Y x" v, x% Z& g, {
' p5 X' B q9 X* z. T: H& H
- I- c% Y D3 E! N5 n2.以下代码执行后,数组$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. c, K1 }6 s4 ?
B.b
7 b5 ]+ ^7 v. _C.a
* o6 m+ Y, B# q! {7 zD.d
0 G. q1 b% r$ S! c$ G: z' W JE.e
3 }2 R( K* {0 s/ i/ B. Y f
; D% v9 c+ i5 t5 t* A* o& ?" o6 l5 y" L' L, b+ ]: l* e( H" |$ F0 w! r4 G
3.如何让类中的某些方法无法在类的外部被访问?
8 k7 i: R! h- l& j& g; ]
e) I+ {* b; |1 D. r+ AA.把类声明为private( _# k$ S2 k9 D. f5 N
B.把方法声明为private1 g; ]/ a7 C+ A
C.无法实现
5 j; S! ^3 G; N" m( E! U% CD.编写合适的重载方法(overloading method)
5 M# l$ o; Y9 g
" b* k" h5 q S& o/ c' s* E8 b3 ~9 f6 H* c; k: E3 ?/ F
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?( U7 _+ r* N; _ Y* @5 C; x
/ @) s+ F$ _& a# k) p SA.MVC模式! T# @& H) a1 d/ V
B.抽象工厂模式(Abstract factory)* k4 A4 _2 n" R7 F/ b- `
C.单件模式(Singleton)
- C# x* ?% Y# E- h% ` |) LD.代理模式(Proxy)7 b, `$ m2 B1 c
E.状态模式(State)
: ?8 p5 J/ S6 Q$ M9 d
+ u$ J+ m9 O1 U; @3 B1 [, ?& r
b2 S& X4 K' d: Z' v. z5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
0 k5 T; n: G+ L& o5 S) x& N$ e8 f5 C4 t2 n% Y% y
A.1个+ _& u6 c3 I1 r$ Q
B.2个
" z+ }# b" C7 G2 s* W# C" o$ h7 DC.取决于系统资源
! |' |+ u/ k5 K! K( |0 `D.3个
- P% ?9 g2 T4 TE.想要几个有几个
6 B! f( N6 s2 I6 P# _
) o2 M3 A" H6 k C2 s
1 t& S" t9 w; ~5 t: z Y+ M6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
' \6 H7 C# k9 h( i' K! T. KB.接口4 o. _# i+ k- Y5 g
C.抽象方法
/ `8 l2 s6 g- D6 `D.Private方法1 G3 t0 F2 u, `& {* b
E.函数重载(function overloading)/ O3 P9 l: E4 n! j, L; V
8 r1 h9 M; W( _" d C
' L+ X# ~4 N2 o' h3 z2 }7.假设定义了一个testclass类,它的构造函数的函数名是什么?
1 W( v/ W: k; W+ h, h
" X [1 n# U- m4 x: eA.__construct! u' b f0 Y! M. W, G
B.initialize" B# O6 ?- w. L, z5 u
C.testclass6 J5 R, d9 H1 R1 p, P3 z ~
D.__testclass
! ~6 ~$ M3 N% jE.只有PHP5才支持构造函数
2 O4 ^, r) N# R: @$ V& Q+ ]- g7 n- f
% V* V1 A, s* {6 i) K2 c" r) S2 T |5 Z- x; m, G$ Z& g# Q, G
8.一个类如何覆盖默认的序列化机制?
8 n" A, t! L2 z8 N! E. J2 @% I
0 g: p( y, D* S, SA.使用__shutdown和__startup方法
* i" Z) U ~2 [- i4 w2 x7 ZB.调用register_shutdown_function()函数1 G9 l- L* c. n9 n8 I
C.使用__sleep()和__wakeup()方法
/ p2 ^" `& L1 SD.无法覆盖默认序列化机制+ f! J' X5 M3 i1 q. I, a
E.使用ob_start()将类放入输出缓冲中( J1 b) k# @- I7 M
; P# c6 e6 |2 b3 p! a/ C) Z( R/ q+ j& G
- {( L H: Q& O# Q* s- D* C+ }
9.以下哪些面向对象的概念无法在PHP4中实现?
# t2 ?5 }7 l) q( q/ U$ i) `
7 n0 Q' L; y9 _+ g1 v@抽象类+ a* @ m. L$ n3 T# E# @8 g
@Final类, x1 _- f% H* I
@Public、private、protected(PPP)方法$ T. x: G* Z& ^; c6 a" A
@接口
/ b4 Y& O4 {) G( `9 ]' |1 I, ^, ~* B) }/ l \" _+ W+ M1 ?! X4 G0 | }5 l
A.抽象类
5 h: g4 R( A* Z1 oB.PPP方法
- j1 K1 O, g5 B7 d4 XC.PPP方法和接口
! F8 c* t, O$ ~9 XD.以上所有都不可用+ b' `5 Z* P- ^: A* D" P: Y
E.以上所有都可用
$ |3 q3 c s/ ?* f* N
. P4 _( [% m% y9 {5 W/ o& b! K# k3 r- U" e" c p
10.如何在类的内部调用mymethod方法?7 |% I; j5 t0 Q/ U- R
6 |0 X# V5 o6 @2 @) z' \" j6 A; g
A.$self=>mymethod();
5 x# T3 h I: [0 [/ bB.$this->mymethod();3 c5 n( s$ M2 R/ A \. a& D
C.$current->mymethod();
; V5 N% E9 O, [8 n6 f9 K. I5 MD.$this::mymethod()
8 w$ P* b' D) h( k6 C; z$ K! ME.以上都不对
: v. t6 S& N7 H" {" l1 q
$ e8 w3 o |$ H) }" F% r+ c+ l: n N8 m7 ~7 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.10
- B% |, D- U5 |% [6 i2 G7 oB.Null! l; Y# D" Z( d( r& x# k
C.Empty7 U) ^3 H3 M" h
D.什么都没有
2 Z- s' u9 M L" O& \: AE.一个错误 j& o5 I; K- x r# N/ j
% Y1 _ |* Z5 ^/ f7 D/ Q1 w
) [" y& z8 I8 y2 G2 `: N
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.100 h+ ?8 ?; L2 k% ` v" d; W' |
B.5- L8 j1 L( F5 g$ t+ D
C.2
( P0 j# ]0 m' ^" w" g, hD.Null- t$ ~! I, d6 L8 `
E.什么都没有( }/ T/ o1 R0 h' }; u6 A+ t
5 L# F e G+ h) U' ^- w2 j- |
, {* X3 _ ]. r5 y7 ?8 y. t13.以下脚本输出什么?-
- <?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( [. P, I8 v9 F4 O" _" W
B.10
! a& j4 s; ~! j1 L4 bC.什么都没有$ ?7 j; t3 I2 E: F; r
D.构造函数将报错4 `; G+ ], m; q+ \6 C/ v* z/ M
E.510
1 e' R! o( I. Z7 t1 I; Q, ]9 W! I* k1 b; y. C# l
. x4 b# Q$ V$ Z$ _ g1 n
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函数必须返回一个值% d6 T# Z7 o" x+ [# w. l
B.reduce_fraction函数必须接受一个整型值
6 v1 Y* Q6 e' R' F8 ^; I" L, PC.gcd函数有问题
8 \2 Q, S; M& V" x( q' dD.必须通过引用的方式传递$eight_tenths对象
; D" B- h% \( F! l5 ]E.对象的实例不能传递给方法以外的其他结构。
* J. j, v# Y9 q( ]4 M
: y. t! K/ M, w0 E7 c+ G* _( P1 k
3 T% N9 e. o4 w1 m5 n15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法3 [2 y9 d/ g: \) M
B.生成myclass的实例并调用mymethod方法
' n0 Z/ D1 {1 eC.产生一个语法错误4 O: g5 Z3 c! j4 m5 _
D.默认myclass类最后被创建出的实例并调用mymethod()
% }/ p9 K5 w2 h; [0 ?7 X1 H: HE.调用名为myclass::mymethod()的函数. v, l* z3 z3 } G3 [/ h- R
" [2 [- p' \6 W( p+ D
. ^4 \$ \ Y- g% }1 L! c2 J- D6 H16.PHP中有静态类变量吗?
+ L9 b2 G( ]8 u! B u+ ?# d7 i6 x" U) y5 Z; r) w
A.有* g9 U3 W! i3 ?( ~! r& [3 T
B.没有6 j K! z I+ x0 S+ t' u+ e
2 O0 }1 M+ D& w6 s$ `8 Z/ w6 K$ s \9 b, o" J- D; `( 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* W0 B; n( b3 }8 B j
B.2
* Q& H. X Z2 R0 _C.一个错误,因为没有定义a::$myvar
' h! K$ z; O( E# QD.一个警告,因为没有定义a::$myvar. T0 l) h6 i5 E# l
E.什么都没有
1 h6 e( L4 K5 G2 Y1 \8 A$ ^; M7 k; {( P
( S% y- b3 @! D( F W4 @+ c: @: _
18.如何即时加载一个类?( j2 G- T, m5 k( a- R- F u
8 H6 L) r( N, U2 i9 p% S+ B
A.使用__autoload魔术函数( w4 j) {7 F4 E* R
B.把它们定义为forward类: H& a$ m* @! b( D+ |2 D! x1 S
C.实现一个特殊的错误处理手段6 @7 t Q# Z1 o& e
D.不可能
1 e7 X" n, ^9 D( j0 @6 WE.用有条件限制的include来包含它们7 ]4 z2 b, J! U# t
0 X. T8 ?. R, r; ~6 {6 {& d
" w+ x! l) C7 ?: E
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
[/ H" W' q; o) [
1 x) w8 v. v8 d9 X; {. R 答案:__________; Z/ i+ ]9 e7 y+ N Y
, h9 L( v W7 e; i6 e, ~
. [* ^, Y6 `" c) H# `" w, l3 w
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
5 G) N# v/ S( B0 l N. G2 ~! fB.一个错误
, Q" }& f# d& N3 d* oC.一个警告
7 j i/ C& Q# M. a$ `! _D.什么都没有9 U$ L g) I0 A2 g# Z. ~0 Q
( n4 A! w7 S/ ?. Q% [ H* b/ G. F
) S, u) m a' ?8 j+ K8 `. N/ o9 \; }
答案速查
) k. T8 V* V! Z4 w, L/ @0 U1.类
2 w0 d( w5 x% D0 ]2.BCD4 \, t) u: K3 |9 z- J9 f8 n% B7 {' x/ `5 T
3.C) L- [" z1 e, J, \! u
4.C
% H" u* G, F- E1 `; b5.A
' e# X% U5 p) j: i- R/ m0 C. l6.C1 x3 R/ l5 N; e" ~7 f. z
7.C
& S9 V0 F8 v8 P/ ?2 @- N+ I, C8.C, ^" ~# I& t- D, `
9.D
4 m' O: I; `9 e7 K) q( o10.B1 ]7 x6 C* s! R" H
11.D/ A! B& v1 P, d% ^4 t' d3 q
12.B3 F5 L' P) W8 U: i/ h. t
13.A; O: q+ O8 I# j0 _# j4 S
14.D$ i q6 o9 L0 C5 |+ S! o* T
15.A
' j) p# ^, {( N6 t+ v V16.B
- u' |$ J% t: c1 ?4 K17.A
0 z* J+ X; c' C& U' f: F A18.D. H) J# U, N# q
19.设计模式
! ?( Y5 z; W, g20.D* Q5 v) i4 }& f9 X. |6 j4 _
* K3 B5 ?3 Q( M7 r
" j2 A& y7 w# S+ f& |) i) Y3 U: p) T* A& `* K% O9 l
答案详解
" {/ S9 I/ G2 u1 U8 {% \. ^- z L: ?, u) t$ y0 _5 j% M, n1 M
1.类是对象的蓝图(对象是类的实例)。( A* l& b4 Q+ O3 N, L9 Y
! c& G% T6 N" J, l
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
7 x R+ X P4 a& b
! ]2 n7 H* H- q h# y, t3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
) B1 W. g+ x% F9 f' C e; ^' l/ z9 W) D- r* c8 K% F9 Z/ {' P
4.单件模式可以限制一个类被实例化的次数。- A+ @6 D5 B' r) U i7 O; F( J9 Z4 S
O7 r" B, I- T, `8 v& V5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
, ]; U$ [" _! l/ G8 N: i2 F) a8 S! q3 ^8 U. x
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
# q$ t$ M# V1 D! c8 u4 C/ z* J( [" ?. j3 p4 p, @, m, r1 `
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
# L8 E1 [/ `# v
4 f, S, ~. `% J& }! Y$ Y8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。8 t' J8 P" W z
' D& y/ _! I7 O8 |- \( C7 d/ P
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
8 I3 O0 h# Y7 x
& T9 A3 B2 ?( w2 c9 W- g7 ^& q2 p10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。5 D0 m l- ~* I/ M
! R+ |, O. G- n3 T5 [; W3 l' g0 Z0 y
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。% Z2 }$ H- m. y5 }" i0 @
: c; A- R, d& K4 t& I) h
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
v" w# e% Y$ `2 t6 V! N9 P9 Q2 t7 ~2 N2 \6 E
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。9 s6 Q6 J6 ^1 m! u' B
4 }2 W9 p/ g' y) c7 U( z14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。0 y9 Z2 E- J: I" }: I5 o# s
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
0 v; g6 Z9 e; d- I% f- L& U6 w function reduce_fraction(&$fraction): I2 k6 K5 T% V! D! Z+ t
答案是D。: D0 G3 x4 X3 I5 w
* F: R4 J" c, t* J
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。6 c8 I( X0 _$ U. Q+ c
# j2 Q2 H6 Z `. g0 `2 I F
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。$ |: H* e; r% i l
4 `$ y. k6 ]7 \# E2 g: {5 p( r7 J" k
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
" {, B+ g. p- j8 r/ j/ \" C% w3 m4 P: q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。( @+ |) o6 g \- {: V- l
. ]( n s" ? x) ]7 d19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
+ J ]1 B; N& x& q- r5 D R: ]$ L9 Y+ J( U- O
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|