  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14249
- 金币
- 2415
- 威望
- 1647
- 贡献
- 1363
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
" E& Z9 Z9 @# LPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
) ~6 i& G9 o3 Q. g6 N3 e本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
8 G1 g( y- J5 w. _- g- D' |5 C8 D
问题
( C6 [" y' }+ b+ L% j6 o; r
2 u6 N( U, |$ |& A1.对象的蓝图是什么?- [* t0 E- d/ [
) P$ N% ~8 c R' G3 K* U2 s7 u4 `答案:____________
: q+ I; h7 m3 Z, L9 E( N9 a7 l" H6 [
+ T; ^# U- | r" R5 R. Q* A* K3 v: \
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& J4 Y5 Z" R: r& {0 H
B.b$ t" S$ f% k' `. E, K7 f
C.a6 d% A$ A9 `, W% L( U" g3 j; v1 u$ v
D.d
; j7 d# ~) |" w0 D7 |1 c/ d3 F* {E.e
# O5 F' D) L, a% D2 V! q7 `; f# ]9 m, g+ V! c/ Q$ }
% Q+ N7 ?0 e- b( [3.如何让类中的某些方法无法在类的外部被访问?* M% k" v$ `5 ~4 T
& H! f- j' j$ l# A/ D3 I5 W9 f
A.把类声明为private
3 K- x; |, X7 B$ y5 Q' Q6 NB.把方法声明为private
, e- @1 @' `* R7 J4 sC.无法实现6 }% I3 x/ K6 c( c9 z2 o
D.编写合适的重载方法(overloading method)
4 m1 T6 G0 x1 N( e8 Q6 x8 \1 y" x6 L* V+ l
A2 P1 Z: Z9 Q4 c4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
$ @9 {: I; C! h
* E$ V& g5 M" y! u1 d0 P8 EA.MVC模式
3 ~% Y2 t3 ]" p. c% C1 t xB.抽象工厂模式(Abstract factory)5 m% m' Z* |3 v K+ }" C
C.单件模式(Singleton): U5 T. t# W8 M
D.代理模式(Proxy)% _4 d2 u4 H& F/ s( `4 n" y( ~
E.状态模式(State)1 I# m# C5 _7 ?% Q* y2 V/ z& m
) I: Q2 v J% W& J3 B1 W u+ R: s" F6 v2 c9 o( f
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
: x. C1 S! F# o) h5 k+ T. r7 ~* D1 K9 C0 b% m8 s8 l
A.1个
! C$ R/ C* V! Q, \- qB.2个. B) J. u8 `* {: k. f
C.取决于系统资源
9 X8 b) h6 P/ X: P( E0 |D.3个2 y# R( f3 t( E8 q+ Q
E.想要几个有几个
4 u# s! G& B( U7 T* ]/ T
* {! ~9 k1 Q" k! U* }" B$ W
/ P: x9 [: I: U3 S1 C9 [6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承$ [( P9 k* T% p* V9 F& w8 w1 e
B.接口1 x& \( m6 u* @: Y5 ]- p, Q
C.抽象方法9 x* L5 A) x. @- b5 d4 P
D.Private方法 W5 Q' r, ~; h3 I$ @# }
E.函数重载(function overloading) v! J$ i5 P: |6 u
3 H! I6 A& a1 R, s# K
, i( y- s5 W; u% o7.假设定义了一个testclass类,它的构造函数的函数名是什么?8 P q- k' V3 S5 {' L: x
3 s+ }. E: E7 Z4 `& S: U
A.__construct" a! B& \( v* R
B.initialize! ~5 T/ {4 C @5 B4 n. L/ O
C.testclass1 {1 b5 v' D" \& y, W/ m
D.__testclass
1 j [0 Y( I% J7 X ^E.只有PHP5才支持构造函数2 i3 g/ k; ~+ i6 S
; `6 W6 M6 p4 L; b# ^% G# _1 a
- D4 T5 a2 `5 Z- V2 f+ a r$ w
8.一个类如何覆盖默认的序列化机制?
. e% }$ y3 F. _" s. h& R: N6 @
3 H5 n; e. A+ ?7 YA.使用__shutdown和__startup方法' P2 b( L! @0 l7 V# w* Y! j
B.调用register_shutdown_function()函数
: K& Y" K( ?/ Y! TC.使用__sleep()和__wakeup()方法# R( |8 X5 T; z) ?
D.无法覆盖默认序列化机制
2 I7 N z9 ]1 t1 s: l3 o' e- l$ w8 fE.使用ob_start()将类放入输出缓冲中
1 j: y+ }5 m# E; _' C) C- y+ j/ K+ E! a$ S8 Q( o& U# J# E4 B: D
$ \: [# C# k: F9 w9.以下哪些面向对象的概念无法在PHP4中实现?
8 V+ W" b: o+ w# d8 T
6 l) B* f4 Y/ z) P! m& B* J' E/ d@抽象类! |7 k8 W% B0 ]+ M) O) c
@Final类1 Z0 A' `; V; X" W) s( I
@Public、private、protected(PPP)方法
( i4 o$ l' V, f& C@接口& `, z$ N" r7 q" a
/ r" |: {; t9 f; `6 R8 d% D0 }A.抽象类/ _; ` ?3 T$ I6 }. X' ^
B.PPP方法- l3 x8 J4 T- a
C.PPP方法和接口7 i3 u m1 Z# T& k8 q) e
D.以上所有都不可用
: R; y Q% s' H' u3 x5 IE.以上所有都可用2 d2 r8 t8 a/ p6 h5 A9 w
- U$ m7 f0 q2 v6 K. K: Z' h; P, H, g
10.如何在类的内部调用mymethod方法?, V' d0 j+ z3 a7 }: Z; x
. |& v: l& p1 K, W* nA.$self=>mymethod();
* F# l7 p3 g9 G+ aB.$this->mymethod();
! R* Z: y$ H0 f8 M7 cC.$current->mymethod();. \' u% {$ i2 ?9 `7 l# h
D.$this::mymethod()
m- p5 \$ K7 k6 v6 r) ^# mE.以上都不对. f7 v- e' O2 f
; b- L9 F) c& y" g' I
8 J# E) v% |% v8 O9 Z
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.107 H- h P) K8 ~0 X) \3 e! w
B.Null7 I$ z, @4 f+ p- |3 m( v
C.Empty
) `1 f' @1 I& A. ]7 \: v2 N) V2 {D.什么都没有
m" b- l' e4 H* E: t/ tE.一个错误7 p Y6 X' d& Y8 f. T p
" W7 ]" E$ }) F1 |
! q9 W) F) g' z$ d% u4 y6 }6 y
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/ ?" k: R) p' u8 y& _& H& R( k% @5 w
B.5
- ~2 P+ _) a/ P. V! V- ]9 RC.2! M/ f& X& z( ?, [
D.Null
/ o- i7 e/ Z; Z/ lE.什么都没有- X( G! f& Y* H7 Y5 Z3 ]! R+ d
" C5 {* \) |3 y; X, p. m1 {9 u
4 V( l, Z* T$ o9 f! k6 k6 M$ Z2 _
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
% T5 M. W; i2 f0 ~: b# \* cB.10
2 O- u% c9 {7 L4 s- I, z2 RC.什么都没有
+ ~& S9 k2 f2 h/ [- JD.构造函数将报错
: b9 I3 H# Y& ~1 LE.510, _9 H) N$ h; r2 W1 D2 d" t V
T1 ], m; ~& G2 S$ p, h7 w. r) d
3 i/ O S9 j, P7 [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函数必须返回一个值
/ b- q2 G D9 k E; d6 H0 tB.reduce_fraction函数必须接受一个整型值
3 I2 K6 A: q* w' C" D! DC.gcd函数有问题
+ m2 H2 w* ]( M7 ?, Y1 p9 g, fD.必须通过引用的方式传递$eight_tenths对象7 o9 A3 h6 G. a! f6 E
E.对象的实例不能传递给方法以外的其他结构。
: o9 Z* j0 k, _# l
1 r" I9 }, n6 z
4 K- c# E( x3 |$ D5 z4 k& ^, j15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
1 j+ L: G& V% Z+ Q) \2 v. eB.生成myclass的实例并调用mymethod方法
6 H4 r# a: \, `8 g o- O" [C.产生一个语法错误
0 n! D$ p4 X8 j) V2 ?D.默认myclass类最后被创建出的实例并调用mymethod()0 O# Z7 ?: T1 Q2 J5 q& y9 \; s
E.调用名为myclass::mymethod()的函数3 y! t; P6 V6 |
1 e1 u' [" \( N' a1 |0 _- P" H
0 {: W- s! o& l& J- m' K R5 f0 k5 G16.PHP中有静态类变量吗?$ [ i1 P+ D" U( N9 l' W
7 [& @+ m' q& @0 f+ \, F. X r5 a, Q7 vA.有5 g8 v( g+ f& m- r @7 I& U
B.没有1 [0 A! ?9 ]& F# Y8 J9 z
! H1 M* d4 p% C/ ?) @" `+ O) i
% m- ?: a( g5 I7 k- b5 r17.以下脚本输出什么?-
- <?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! i/ h8 D1 G, Z& r5 `( `
B.27 r* h, e( i7 ^7 s
C.一个错误,因为没有定义a::$myvar& G, e3 w1 {' E; q+ ]4 b" _
D.一个警告,因为没有定义a::$myvar
0 \: Z4 j8 \' J6 Q) X4 @' BE.什么都没有* Y! p4 \) N1 N
7 U: a. P: \, Y' ?3 |6 [7 o: }8 l
0 w7 \$ b7 {3 `1 c9 p/ x. Y. W18.如何即时加载一个类?5 H1 u9 f; q* q6 e# s
! S, ^9 d6 r) B( y2 P! u9 tA.使用__autoload魔术函数& s0 @& u: S/ g# W1 X* \) ?
B.把它们定义为forward类
( Y/ `1 {1 ^# y( |+ }7 OC.实现一个特殊的错误处理手段
# ?2 y7 @! e: u9 M, D9 OD.不可能
2 G+ }% i' c& H3 }! e* ^E.用有条件限制的include来包含它们# t. c7 Y; j% z0 e
8 h; ~% c* [3 ~2 d$ X, ~/ P, `
; ?" H5 t/ B* D6 {7 p19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
t! w( j5 B# f; Z4 F0 a* }6 J( X' @* g
答案:__________
' n0 i: E3 f5 h
+ u7 Q$ o6 {6 v: l0 V7 D- H3 m+ g2 ~' J+ W% M3 C
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
2 Q/ h8 h" ~1 vB.一个错误1 ~+ o" a. @8 d& k8 h! q h
C.一个警告
1 u! |7 }+ l9 J0 i5 r0 mD.什么都没有
5 t4 e. X* |" J! F7 [ h8 X" |3 L
4 f* u4 \! b+ h3 `5 r9 w* P5 B$ x# z% \
. F# L" _+ t5 E0 e9 Z
答案速查
( n- t! h: U/ v+ ~# w \3 C$ t1.类
8 a2 Y1 i* P/ o! J+ v' o2.BCD. w( f) ]5 v9 \5 c, s& n
3.C7 F4 N5 O1 o- }' w. `
4.C- f9 Z$ x( h/ Q# R' W5 H% c
5.A: |0 Q4 [0 v1 J. X
6.C# i+ k7 j( C) \7 v9 f# Y6 P9 p
7.C
7 n' P- s% G* v- C, y8.C- m0 w2 p: g5 M
9.D
1 n% v+ A# K, R- G" |10.B, A( M: k* g2 j5 ~& v
11.D- r5 U. l: a& Q4 B. z
12.B
7 {5 Q( y/ I% U( T7 X2 S8 u. T& ^13.A
; p1 h6 B: B! Y- D) a14.D
' F$ Y! S8 A$ @9 d1 M, v15.A! Q' S) v0 X& s7 F* t
16.B
/ q: B9 v- A6 m- r, Y5 J17.A
# ^& k5 W1 Z, Q% b- {! d: ]6 A; L18.D ?. h+ i6 c- q9 q' L Z& G
19.设计模式
/ C9 j/ c+ f1 M! t4 P$ [20.D
7 Q; a" A0 d3 r( C$ z/ a
. H$ p4 M; O5 b& g# J
. H9 C" f, ^9 y4 Q- s) Q x7 U& I
% o) Q; `% A' F' S) ~, ? w( b答案详解5 a0 I! ]6 k+ l1 ?8 k" c
. k' U+ F# `$ g5 V! D$ _; b. M1.类是对象的蓝图(对象是类的实例)。
/ Z) G- h, w, c# W% B: V, C* l2 E- v+ ]
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
9 y# f/ r; h7 j" f3 J
, \: I9 u% b8 {# q9 h2 Y3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。+ C. o& v5 X2 t$ V; f5 S; b* K
; d4 r- s6 k( v, f- _6 L# z' s! t
4.单件模式可以限制一个类被实例化的次数。
! K% C, A1 ]) t# o$ h: P
4 W5 G+ n: J9 X& E5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
Q$ \5 ?" s# S' z7 o& S C6 l8 s" B7 N' B0 R) ~! P- ]7 x z
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。- m* @: v) w) n4 w, V" w
4 u. M* D* Z3 r% C7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
5 G+ \+ H7 w5 ^. `, e' C) a$ O# T, A5 ^; ~' w' ~
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。1 Q$ _1 e! M1 Z Q& l0 U/ L8 u) `+ ~
: L Z. H# n% ]9 d
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
+ ]% ?9 o. A h
6 q& r1 M+ y5 T% }0 k+ m l10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。. ]) }6 @, V2 ]
& A/ E. M( z, Q9 u, o11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。* O( D' R8 j* v, n2 D- ~& G4 r* O
; |+ ^+ R! k" z6 B12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。4 E# H+ D3 O$ @) |# Q
2 ^1 o: v0 v2 ~# B& b \" J13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。+ S3 K/ N1 t% d( x
& l1 |. b7 c- V14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
3 k: E8 w4 r- W! s回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
, y2 T3 Q$ S1 n6 c; f4 J; i' N2 G function reduce_fraction(&$fraction)
1 D$ F& r# N2 S! Y1 R答案是D。$ h1 _; }) s9 K; r* Z3 \
. m8 z9 |+ ~& F# X" b+ g15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。; F% x, {) B( _; l$ @, a+ Z8 ?
m9 |* L3 j% R# Q16.没有。PHP4只允许声明静态函数变量,没有静态类变量。7 e7 \: l. c( t1 |4 ^" j
( e/ F4 T- g- h- m" T6 l
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
7 t$ `/ p5 `( `! k; ^1 W# ~, M1 p/ R; P
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
# Q) `% S& {2 G b9 H7 s) X- U5 x# K: o. t9 F, i
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
7 c- Y9 C9 W7 | }7 u# ]) i' k. ?( {
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|