|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
/ C( B* s. O- ^5 @. TPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
/ I* t0 q1 k# X4 A! v% k4 u本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。# s! B8 b. _% l+ [6 d2 _
# E) b+ Q: n: E/ {4 M2 e* n问题; H2 |4 j3 Y4 {/ Y: k7 I
4 I0 S7 r4 G* x3 M4 t1.对象的蓝图是什么?' X1 S$ ]" z4 J% e: s# X0 @
( G. M" L# r' g) `& l答案:____________
2 x! J, V4 F/ [ L
* q' q. G1 o. j( C
( _/ p8 N5 J% l2 f( D4 S3 E2.以下代码执行后,数组$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
! r9 [. O2 N& z) h- cB.b7 F( }1 C0 A& C$ p5 m% w2 p: a/ b3 _8 L
C.a
* e5 J. h: E. J" N( d% [4 PD.d
- U4 \: l/ L. r0 q, O+ x! ^E.e
6 v4 Z; Y2 [8 B
# q( _& Q7 p3 m! _0 L0 u
3 X3 u: X+ m( ^, I% G, c3.如何让类中的某些方法无法在类的外部被访问?
& v: T: X* K* s$ c
8 j* B- z9 m9 n3 K" w7 D1 F- h7 D5 iA.把类声明为private
0 M. \$ f$ c3 B- K; J6 t TB.把方法声明为private( x3 j9 w" E5 o& p* V# M# s+ a
C.无法实现
3 w1 F. Z4 g7 y( {" ND.编写合适的重载方法(overloading method)
5 `+ C: W0 _: Z4 h. a9 e6 d
3 l- u l3 D* e4 h: @9 C( J' b3 R, Y( ^
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
. ?6 E: Y3 B- C- y& V. C0 f# b
3 ~# E5 c5 P' S/ `* tA.MVC模式" j: W" K* v/ I8 y9 W i# O2 e9 n
B.抽象工厂模式(Abstract factory)
5 c5 }( p! y8 v8 E5 F+ nC.单件模式(Singleton); i; W7 D! p7 B% R4 J# g/ G
D.代理模式(Proxy)3 h8 X& M" @, a, l( Q, D
E.状态模式(State)
/ G& c7 m7 x. T( ]0 U% Y% h' N# J0 l7 k+ `# G7 ~4 t
2 b3 `( X' ?# m. F b5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?- C. ^9 g' Q- |( s
* e* b2 s: o) E7 Z" y( W' {A.1个! H; @$ p0 a3 ~$ b0 X
B.2个' `& M% r. U4 e* g7 G0 E3 H0 B u
C.取决于系统资源" d* X% J; @8 C
D.3个6 [, k3 a/ @- o$ s/ ?3 }
E.想要几个有几个1 `7 d) k, p- Q
x" n- I; `! M6 S4 d
; F- D; j# v r; j7 l% |7 y6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
5 R4 ?3 ~6 n8 x5 b4 J! u' d2 UB.接口
# |0 |1 x! L e; {% ]2 tC.抽象方法, @5 y: ^- ]2 A L) S1 ]
D.Private方法
* @" d. R7 O, Q- _' M6 Q3 HE.函数重载(function overloading)
. Y1 ~/ W; B+ M# v- U
_3 {, Q" p/ |' ~
' D- u6 M3 ]+ R7.假设定义了一个testclass类,它的构造函数的函数名是什么?
2 d( m" ^ z/ }
' b- S6 N$ \$ N8 S; r1 P' S( B/ tA.__construct* d4 I- b+ x8 l9 z
B.initialize
0 Z- N; P; j6 |1 wC.testclass
; y. @* Y. `) c$ ~+ Y ` N: BD.__testclass
& r i3 [4 j2 z `+ g) JE.只有PHP5才支持构造函数. z; Z8 a% P! k4 H
/ H, I4 n5 U& V8 m+ Z
2 t( s5 q2 J- P; H! ^8.一个类如何覆盖默认的序列化机制?
. }4 K0 c! s( k. K& T$ |% I, I5 A) Z4 j
. K- i: H% A& ~- u6 o, uA.使用__shutdown和__startup方法
5 a* c+ f( a4 I5 N/ \ ^B.调用register_shutdown_function()函数9 z5 D! R5 j: h" j. r( A
C.使用__sleep()和__wakeup()方法
1 h( g9 b V8 x# BD.无法覆盖默认序列化机制/ {$ t! U9 _1 u4 M
E.使用ob_start()将类放入输出缓冲中
' t4 w" L1 g$ r$ K) }& ]$ Z; y: t6 k3 i8 w7 ~2 t
& D" P- U4 {6 [( A* s
9.以下哪些面向对象的概念无法在PHP4中实现?* c$ r+ X7 X4 _1 Z: z1 g( K
* a, F1 @# G& O
@抽象类
% q3 `2 T4 \1 D. u@Final类- T/ T9 ]- G# N0 N& g" t5 e
@Public、private、protected(PPP)方法
5 {( w. M' m1 u/ l- X- b+ x# W- D1 |@接口
7 S/ p# d* N4 }* ]9 G1 N
; _2 d, Z1 f0 hA.抽象类
; q2 I- R0 [4 D% zB.PPP方法
$ P! N% F0 ~; N1 g/ q3 Y. _( d/ XC.PPP方法和接口
1 ?1 r' K; |* w8 V; F GD.以上所有都不可用
1 z4 S2 h5 g& d! y9 J% {# u, \- @$ EE.以上所有都可用9 o$ q0 F: D. ~
& v' \! }% F2 @- I5 |: M0 D9 a1 h5 m/ u& Y2 p6 Q2 O/ L$ H
10.如何在类的内部调用mymethod方法?
& K1 M: o5 r0 S+ _4 {, X- {8 i0 L3 H- d
A.$self=>mymethod();. i: p$ t, a- l( x! L0 p4 n
B.$this->mymethod();4 V& D; x5 `; D, k" Y ~( r% J/ T8 N
C.$current->mymethod();, H7 C5 {, G/ C T/ j
D.$this::mymethod()
0 k+ G1 v; i7 W# B' Z- c" W9 ME.以上都不对; h4 g: C9 a: w, O1 l
" W( [6 A X3 R* l% F
# O" e7 R) w3 c% `9 O# _9 `; r11.以下脚本输出什么?-
- <?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.104 Y3 O! d! Y" H5 _7 F9 u- E
B.Null/ K6 {. f* J" ]* t5 j: G0 O
C.Empty3 j; q: v. @2 T
D.什么都没有
2 o6 G- ?9 O) Z; T/ oE.一个错误
, {% P, n( f0 F2 @6 R8 `
: t( h5 v4 Z/ N/ @/ U% _! N+ [8 U5 K4 e6 I, @* B
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 G* y2 O: }: JB.50 b# \" R& }8 }6 |- ~/ ^
C.2
6 y$ Y1 ?$ @1 i/ y2 DD.Null2 A$ K W9 u% R4 N. K: u9 O
E.什么都没有& z7 p$ o& T2 M, O
6 M7 \) C) ?2 M) b
! c0 E( J+ x& j* e- ?
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) Q b5 k3 ?/ M+ ]
B.10. b0 X2 }: V% x8 E) `" N* |; [0 k
C.什么都没有
. ], c4 Z$ @# e' x' p, d! U3 q* L0 BD.构造函数将报错
5 }& @0 H+ d6 n+ s" dE.510; c {' e: `" J3 I8 l1 ?6 F" x
% B& E1 B4 A$ \. ]" k! ?2 C. G
$ i" n8 |* L2 m+ x% ~% c; N1 V14.考虑如下一段代码,执行时,$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函数必须返回一个值 t3 l% J: j4 h6 n7 n9 n0 `6 ^
B.reduce_fraction函数必须接受一个整型值
0 k" V2 u* C5 PC.gcd函数有问题
C. o6 ^, p qD.必须通过引用的方式传递$eight_tenths对象
/ X3 h4 T2 m; W! d4 }+ qE.对象的实例不能传递给方法以外的其他结构。3 B( T% K6 @ |7 D+ |
3 J5 R: f( i% y$ A! P3 B" N# Q6 g* U
% B% f( C& g( l- K8 N15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
# Y8 Y6 c, r6 fB.生成myclass的实例并调用mymethod方法+ o1 m5 F n0 F# X& Z0 Q
C.产生一个语法错误' W" x! S7 R- V
D.默认myclass类最后被创建出的实例并调用mymethod()
' t1 V- C# H5 [) Z' qE.调用名为myclass::mymethod()的函数1 D6 I3 ]! c& R7 U; i4 q) V, m ~
7 M* {: f4 Q& o" k/ X
. F1 i8 w$ ]9 T, n! n! k2 d. x; v/ X16.PHP中有静态类变量吗?
* A, j' a! m+ o1 F. S) S5 s
: P6 Q3 l! D1 I O: Y2 \3 cA.有
+ N, L/ z. q) c0 r. w5 X7 G4 S" C) FB.没有0 k% @3 ]# R% j9 b* B+ f2 o' k+ y
2 D$ V. {2 q+ l+ c; b! T
6 ?2 a" s1 H9 \; B
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/ l8 W( y% {2 i8 i- n
B.2, T# ]1 g+ r6 Z2 `: S8 b) Y
C.一个错误,因为没有定义a::$myvar! H, }( R6 K$ C; a
D.一个警告,因为没有定义a::$myvar" W W4 H6 g- j9 e4 A
E.什么都没有
) ~3 H( d8 Q3 H! B# u' n1 I/ T7 X9 N1 ?) G: w& A
5 n( G/ \, G' w* D18.如何即时加载一个类?
: V$ ?$ X8 s$ {+ x$ K) g
* G3 \1 B8 Q- a! C* q' DA.使用__autoload魔术函数; f/ q& |3 X7 ?/ w& f
B.把它们定义为forward类
a& N8 q& H8 rC.实现一个特殊的错误处理手段* p0 j( V: o, j4 M7 k: @- [7 z! ?, d
D.不可能
: h2 v, I# y9 j- O3 @E.用有条件限制的include来包含它们0 D: `' M( U7 v! [) R
+ q: ~/ W: Y! Z$ q, ?) U& K( D1 i6 H; J( a
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
5 V" D1 `% j" I v2 [8 U3 x O
8 Z# h; s8 p! x4 e# L 答案:__________/ L* n% u( p. f9 [' W
" A* b4 I# z3 Q ?
, t) T& X+ g& ]1 V& E/ Z
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
% H D& a" Y# L- C: [ dB.一个错误4 K" \- g, a# d, F& m
C.一个警告
) U1 ~5 \ C; d: m& sD.什么都没有
, }# b( [/ ?7 S u% n+ s# k& Q! h: @& t- K( o1 h: n; j1 W
# L6 K6 [; @2 p4 S" t7 F* q4 S2 O2 K9 K2 u P: X" P4 q$ H$ x: G! V
答案速查; j" `; o* C0 ^' _; k" y
1.类
- W$ g" w$ K" b+ w: ^( U' {$ \2.BCD' K; B W. E2 }( f9 {
3.C
4 n, f+ G& f5 }$ M4.C: w) I5 U& e1 ^; S* v
5.A
+ n1 D) K2 A, L3 O6 ?) {6.C
: u. q( p4 N9 X8 J& d3 G9 i7.C
6 Z# x5 s( Y; b+ ~( x8.C
9 p" N+ y. U* j+ l9.D
5 l& O" Y, ~! o% Q( ^8 C10.B: P( }. b- c" @" B8 _
11.D
: O9 |' b$ N; H/ X7 x+ s4 ~12.B
# z% b: L' q" P( N" x; j13.A
2 z" o1 t+ }4 `; x" u9 o g14.D2 V* s( \; v, H# }
15.A; a" ~ q( ~: k: S
16.B
; @; A# Y9 t) D L$ e17.A
7 a$ l. J6 \& l4 U: \3 Y0 k0 {18.D
" V9 M" S5 @, O/ r% p8 N19.设计模式* e* F0 E, V$ y; j# Q( d
20.D5 ]* z& t/ o$ f. l; A2 g6 M& D
8 L* e& [5 b! @) V7 L a. G: ?" e6 B3 g
+ C) S8 V2 v c
答案详解
" Z# C2 P" R6 y2 L9 n
, c( f$ j5 I) F' s1.类是对象的蓝图(对象是类的实例)。4 J" j8 `6 I7 @; a' J7 r- H
7 [- l1 |$ y0 Z+ c V* a+ Z4 Z3 R
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。- C: O( A" M3 ~/ R) r+ A
! f$ f* [, |" _; N7 E! B* q$ u3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
6 G: N+ Z2 w5 i+ ~, f) @! }! F# Q3 \$ H& [) Q* d' d
4.单件模式可以限制一个类被实例化的次数。
! l( ~# v' y8 g# J$ v; |1 x1 Z* K, o( k) Z7 g! i
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
' q* @" g' x7 K# M; h7 P: z2 k" C7 H, u6 R' L
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。( x" a1 j! b+ p& b0 K
6 h1 r: v0 k0 O; N+ n% _
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。2 c/ |" Z( r! S. S, _* h
( X# }/ L* r$ I$ D* W* i) ?8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
8 s! I* e5 V% b3 p# C2 `. k. Z1 l C) _1 H
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
Y$ i! n2 x0 p* v6 Y8 j' R# P/ b, F
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。3 ?4 b D+ [0 i5 H. N- `- `
: h: Y; l( Z4 C* o0 M1 ~' _
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。* Q- h- a/ M+ K$ ]$ t! L7 j
# z6 I7 _2 |* R9 y, S) N12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
5 h m5 T8 W4 m4 a) c
- g: G6 [+ _& h8 H/ b' f13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。: t3 N9 r- T0 I( r
. ^% `* _" O! t6 D0 F14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
& A- `! p3 z- d9 \7 ~' b回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
; X$ \6 U( g) z" X6 T function reduce_fraction(&$fraction)% x: N; f- \. s# c% x
答案是D。+ v, T# t# a$ ]( E
2 x/ p) u( }' M/ G- |! K, m15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。. \: u7 A8 n7 ~9 ^7 K+ H& k5 F
2 H, M2 r/ K2 j& U, \
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 ^1 _9 J& \5 Y1 d3 t% V
! k" Q) }1 J) u$ q8 d: [8 j
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
& h+ Y. Q b- y* c/ Q N
; T: q4 d' Q9 ]- r! m8 u18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。# c8 ^# f8 w/ E
. c4 d7 ^/ ^& J# N/ Z
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。6 c, W4 A2 G2 D3 d2 S
( J2 s8 @4 N- M6 h( Q; Y
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|