  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。3 M5 j; _% U9 W I2 s
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。5 _4 h+ i0 _0 v$ c; v8 b( K
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
* M y; F- B0 P7 ~1 B* {3 u
, I. O C5 M8 ]! z; d9 ]' E0 K2 u7 T. C问题& t9 `0 V# n5 t/ g
/ x" H5 p Y) Y5 ?7 E1.对象的蓝图是什么?* G: S; F5 N; e+ |
3 Z/ F2 d. x, L7 r* D答案:____________( R* A' Q& _5 L5 k) X
5 K' C. p7 l1 y
( c# \5 s4 N! g2.以下代码执行后,数组$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
7 Y- i0 P, g# P9 K: m5 hB.b9 a3 l' l9 i! `# I9 { g5 z
C.a5 f6 ]2 J2 U7 h; q
D.d" E. A U% i( e7 r
E.e& @% l/ [4 `/ V' m, F+ t1 X
9 B. ]% X5 }) K4 B9 C) p. }
, I; N Y# y I9 s3 f q3.如何让类中的某些方法无法在类的外部被访问?
" Z0 ~% F# ?' ~3 R
# Q" F- v/ B7 q4 }% M$ eA.把类声明为private
" t* O$ d% l# w: ^( S) U" A: x' I2 yB.把方法声明为private
/ H6 Y7 l3 Z' A+ aC.无法实现& O6 ^4 c {) b& k% a) X
D.编写合适的重载方法(overloading method)
- I$ S3 i0 i: S9 ^, K, I' h. }$ c4 f9 X% V$ i, G. R
) V4 T8 i5 v! X3 P Y
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
+ L5 }* @7 d) d( A: [
8 W6 n0 c& L2 k. [# J. k, _) r1 ?A.MVC模式
! Q q1 l9 J" m! Q$ V9 [$ D0 J: xB.抽象工厂模式(Abstract factory)
5 M$ S1 F( b) d1 g4 h1 XC.单件模式(Singleton), q, W: M- R9 Y& r2 I1 ^7 ^7 o
D.代理模式(Proxy)
/ N. T8 H# |! ~( c% R. L" zE.状态模式(State)
5 t: b. E. {1 s3 \2 {& ]* n8 H) P' H% R5 S1 R' J) t9 [
0 l" ~+ c$ ?! ^9 n3 N% y9 X7 \
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?4 ?7 m" S. _4 N/ R$ k
8 H8 l& r, y3 s; @; |$ U+ ], Q! |, Q
A.1个
% ?) F9 @( f2 ^: K8 x4 }/ P2 K3 QB.2个9 H* w; ?" ?- |8 N% u
C.取决于系统资源
4 {! @4 X9 V8 ~$ c$ ~D.3个9 R% F; h: A# C7 X a# q* q
E.想要几个有几个3 n9 u# S% m8 B, R
- _+ G) `. L' t0 F' \
" P) h' }$ a: f2 J. B
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
/ r u0 S* B& S; g& f @8 oB.接口4 p- `9 |& w U8 a
C.抽象方法
3 g/ Q% G2 a5 s; ], R- `1 b) xD.Private方法& _ j8 n, e# c
E.函数重载(function overloading)
0 p: b' z; ?2 h- y0 m& V
. D! t2 X8 ^9 ?. Z4 B
& E0 m' _. E& J, C# t0 K7.假设定义了一个testclass类,它的构造函数的函数名是什么?0 R+ A% A& s, F! c( r8 s$ x# E
! ]! r( d& F3 j' oA.__construct. j: D5 m o6 y ]8 i
B.initialize- W4 z8 R0 P! K5 y
C.testclass
8 Q7 T# q- q# @* }9 Q( L7 LD.__testclass
5 j) J! R% H8 R' I/ f) ^; WE.只有PHP5才支持构造函数- N8 o# X/ n: t9 r4 n
+ @& @5 u" b0 g# w4 a- z
$ E) y! V' E% x% z8.一个类如何覆盖默认的序列化机制?
) h, A, i+ h, w2 K
8 ]+ A) h2 E7 I# _, U7 JA.使用__shutdown和__startup方法# w, Z, \( x7 M1 E3 U& y
B.调用register_shutdown_function()函数" y+ v) [$ Z, h, k
C.使用__sleep()和__wakeup()方法
# c$ N4 I7 L4 {6 R! K; U! |1 L& SD.无法覆盖默认序列化机制: w' C' R9 [1 o9 H" H3 B( i
E.使用ob_start()将类放入输出缓冲中( _. \+ Q1 _/ Y* v7 G7 B
5 ~" f i4 C6 x5 c! B$ q+ g+ k5 R
* }" k. h8 L" D! d4 x7 i9.以下哪些面向对象的概念无法在PHP4中实现?
2 m! @$ O, E; U: Z6 p* Y. H
" _# J: b( Q9 l9 k M( ]; x: h@抽象类
; O6 ?- [9 n; @7 f. ]! S@Final类2 U+ p& _8 e* N4 U @& Q
@Public、private、protected(PPP)方法( C. T F" [: V3 z/ y% q
@接口0 ?3 q2 [3 ?* b( X# U! K6 m
# O4 f O6 P$ x7 }$ [: fA.抽象类
1 W: N- {: U5 t+ H* [& s: s5 fB.PPP方法, P# {" s4 h5 R# U
C.PPP方法和接口4 V* \4 j% x% ^& V7 `# w
D.以上所有都不可用# e/ V! R+ o8 u; x
E.以上所有都可用8 T, s. M: V1 F5 I% f3 j) G
' ^4 e6 c6 K) d- d* Z1 h
3 L5 D! j0 F& v& A# u* E3 ]1 o" m10.如何在类的内部调用mymethod方法?" S, O: {' @- G ~1 M2 ]
3 X& L& C! E+ M. }, l4 |5 F
A.$self=>mymethod();. i& g7 Z n. M1 A' a6 u
B.$this->mymethod();
5 Z* p$ v' t3 e" d) i8 K# h4 cC.$current->mymethod();
- W: X, @1 F- j: K1 S7 kD.$this::mymethod()- E) u, @ V l2 F1 W$ |/ j+ `
E.以上都不对5 O7 z: b& \( t- B, Z, G
: c; h) a: I! T- M
! o$ R" t( ^) D# C6 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
; M' q+ L; C* S$ DB.Null, E( e. A7 i9 ]* c$ d5 ]
C.Empty
# z4 b/ s) w& N1 q* B8 d- w& v4 jD.什么都没有
7 T- g( Z0 t& g0 r6 l# G% G% zE.一个错误7 u. p Z7 V7 O/ d7 s
. k/ @# ?/ l v; C0 V
" G0 ]7 s Z- ^3 P5 U* q12.以下脚本输出什么?-
- <?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" ?- x$ r' U5 b0 h4 h R8 U
B.5
: c% j# d& I" d9 Z5 c) u! gC.21 A( _3 s9 D5 @( k7 |& S
D.Null( u) O% d, A* c: ]3 }+ N1 K7 g1 v: q
E.什么都没有' k: V0 G1 Z% q" d& C# u8 [
7 R! f Z) `9 s4 x# w% X
; Q2 x% U+ t( `7 i$ S13.以下脚本输出什么?-
- <?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
2 U5 N, X. I0 ~B.10- A* E! _$ t2 J
C.什么都没有
& T3 k: q! ~" U4 O1 m3 Z0 H+ M( TD.构造函数将报错' R# C6 V: F3 R5 C
E.5101 H; l" E6 C. O* i, G
' n# I- V( }3 e
* I& ]* a ~( }# 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' x' g1 y; S
B.reduce_fraction函数必须接受一个整型值' f2 Z) V& S+ I
C.gcd函数有问题
& a/ H+ {/ W: X' ZD.必须通过引用的方式传递$eight_tenths对象
: i, J Y+ Y, i; IE.对象的实例不能传递给方法以外的其他结构。3 W, A1 s5 @( G8 x
6 m' A9 |& I5 m' E ~: s# @
6 B& g. B# C5 V* N$ Q" G7 b# p& x: V15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法7 I. ?% Q1 e5 y3 s$ d9 f
B.生成myclass的实例并调用mymethod方法
. R9 |5 \0 n( [0 Y( y. m7 N) QC.产生一个语法错误( B) A" r$ }! m! R' V c1 s& \
D.默认myclass类最后被创建出的实例并调用mymethod()" `/ n M: V: V+ L3 E* l; c' N
E.调用名为myclass::mymethod()的函数9 k: T7 d! H0 Y5 _+ x
2 I7 E9 N9 p: g2 P/ o0 T9 j- H2 N: M9 w7 e
16.PHP中有静态类变量吗?3 q" `2 I# i7 c; j
- S; j! {$ m) s/ a! a) i9 I2 {& s ?A.有" O; z$ ^- Y) L# F
B.没有* x' e3 _/ |6 w" I& r
+ I( g8 |2 u! z, l
0 s* F0 U$ X! t( ~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.15 C* h( V5 z1 j3 X) k
B.2
7 P" L& }5 j- X+ IC.一个错误,因为没有定义a::$myvar. y% e% P; s( L* `/ d( V5 r4 j6 A
D.一个警告,因为没有定义a::$myvar% G% C( }2 n' J/ r
E.什么都没有
5 n' J6 v; P) G6 ~* z( M
+ |4 t) e# E) N9 ~1 Z) g' H
( D. q( s8 I* j5 O' ^0 Q6 A0 w( q18.如何即时加载一个类?% E! w5 N3 D. K. D- ~7 W9 p
; w' W" \& B" X! q: c$ U, `A.使用__autoload魔术函数
9 m" D8 x0 d! j; Z8 KB.把它们定义为forward类; ]: }$ T( u6 I+ K
C.实现一个特殊的错误处理手段
: f7 ]" M9 O# M4 P! R0 r) o, ^- [D.不可能* A* _% P, P J% K) ~
E.用有条件限制的include来包含它们5 `$ g, {3 H& K2 C+ G5 Y
B, b; B: D7 T7 Y, O2 k0 u
" P9 b+ o# f" E% Q7 C* f1 D19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
. k+ g7 ]1 d) u5 i/ c' S- V8 o# p, f1 Z1 [' T: e+ t7 j0 J
答案:__________+ P, c! n: e4 O Q( o0 W
; \% n5 r O% Z% z. D
/ M$ Q8 n9 v) E& w+ R2 E3 s20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called6 q4 C! }' p* [
B.一个错误; N" P* ?" E/ I' i" z x
C.一个警告
6 `( Y# ~ g* Z7 M. ~D.什么都没有
( o$ X3 Z' h; n+ M% z
1 j/ g ]: e& i% T$ h! a7 h8 g" O$ u" z- f- P
0 Y j. {8 z4 h. i
答案速查
$ k( Q- p/ m4 b5 @5 w& J# {; m& T1.类- [) C" S. b5 O: B" c
2.BCD( l+ S0 \& a1 B. [: L/ K8 G+ O2 ?' U" M
3.C+ i' |# @! ]9 T& C+ y- P/ l& E
4.C
2 ?' \0 {/ c6 d" r5 _$ t8 @5.A
: x. J6 h8 Y# d6.C
) Q2 S9 W3 _% T& j; s0 a7.C
$ T: ^9 P C9 T7 i8.C9 m N5 ]' F; o z4 y/ i9 Q
9.D
& @- S4 c8 f0 X( W; O7 s9 X) ]10.B
/ h0 X# D2 [* e9 I11.D: e! I8 L L, H: F; w& B
12.B
' _$ c3 q4 H5 u/ Z' J' ~13.A. D( f4 _4 f1 w! q Y
14.D
/ n+ c+ {) Y$ ?7 f' j$ R$ w15.A
% P. Y& ?1 t# j, t$ a16.B
" E5 n5 k9 P4 [' \17.A
* d' R! A% H1 C R18.D% F, p3 S2 q; Y3 ?1 Y" B: j- p
19.设计模式4 f( h R7 n' m: D/ a
20.D
( b N/ p. E$ p3 ~4 K" j" R. E* A9 C) i/ l5 U
7 H1 e- g2 {+ j$ ]9 v _8 J2 M$ p! F/ @' [) d5 F3 \' t
答案详解
5 L; `5 z, [. C0 R# w' C; U, h& r6 ^* m# v l) {0 V
1.类是对象的蓝图(对象是类的实例)。
' Y# ~2 H+ o! F9 j2 f
% m9 D6 n& |' o2 T* f. m2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
! R! }, c* `( @9 g0 ^9 @3 i4 x: p3 q3 o3 F' v( ~
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。2 ]; o" j0 t7 S% r$ I( r9 a
7 \) U% w# @ u$ [" {4.单件模式可以限制一个类被实例化的次数。
0 e: i- q% S6 j' E( ?2 S5 A9 ?* k4 c1 V; E) R( W$ h
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。) e! q6 V8 @( T X. X
7 V2 `) b; W* \) k2 ^! ^9 O9 n
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
, }% ]+ m" E* I7 P8 d W6 Y2 B1 P+ _3 o
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
" L) f, `0 Q# j9 X7 d7 W
: [$ H9 v' w1 J3 `" J, k+ O8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
' z7 d+ H5 T- J: N A/ N* E/ p r7 ?5 R) ^* H
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。5 y* q8 z- A8 \7 o/ c
1 s3 `. X& Z: x4 l10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。! H4 X/ O! Z; r' J ~
: O; k3 l6 V! H/ A+ B( a11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。" \( ^7 |6 T7 i8 X1 |' L
+ o- D0 H1 r* C+ R @& {
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。9 }, z9 r0 N7 T2 [5 F
( i2 `) \, K6 j* p
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。6 D& o5 A3 R; e3 ]; r# t
7 b# m1 t5 ]# Y- [& n- q0 Z14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。6 [# H$ B# j4 U$ i/ s4 V5 ?* g( H
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
" |! A* Y( _' r% M# @$ T& O function reduce_fraction(&$fraction)
* i* T5 d4 K( e" y: E答案是D。- j1 [. x2 }) c! h% T! [9 v
9 L/ b) ], e; A) I( X. B15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。2 a% J6 C/ d9 B. S9 m- ^9 y- C
8 y( M7 C N9 g/ }8 V4 a" l
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
6 I# {0 k. D6 T
a2 ?$ i$ D) ^7 P e! S17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。. o# V4 } Z2 |- K8 H
, d5 \& y; e8 O9 d4 }! ?18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
% L! p0 m I, B. p1 A8 b- q
! l) q' P+ L3 X/ B19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
) _+ K# |: V3 A$ b
; H: N5 }2 ^7 p1 Q2 S& q' ?20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|