  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14249
- 金币
- 2415
- 威望
- 1647
- 贡献
- 1363
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。6 n2 c! F1 y% ^$ l2 j+ {
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。$ @! A6 a2 w: V0 F7 `% b
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
& K7 y; ]- e1 p& N, @7 m. f+ o' g/ }6 O* C7 N( C% Z
问题/ w* }4 X K; m& y
- A0 ~6 F3 o' M
1.对象的蓝图是什么?
& V1 p1 U; t+ y- N
$ n( D& i9 B, e$ G- `答案:____________
3 O b6 X# F" {9 T3 w( z5 Q( T
) C( H6 A3 C: e, ]7 ~, N% Y& K8 B k& z! Q5 r, f Q" s
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
* ^- ^5 O$ h5 {& O" s0 c9 ?- kB.b
: Y f5 n( {( i9 R" EC.a
& b+ ?! c, l6 @# M) C1 ID.d
! d/ A$ W/ ^% `( P7 I# C9 p7 @E.e
- C3 p' B# j2 {3 ^9 Z5 {" A/ v) n6 k( g
/ H, S% U3 S1 }8 @/ p% P3.如何让类中的某些方法无法在类的外部被访问?
E F2 L0 s: l) A; m# t, a: ?5 r8 }) ]5 O& P: r* i) [' A
A.把类声明为private
, G! ?2 @- I' o- L6 w8 wB.把方法声明为private
: w& Y+ A! }* p iC.无法实现
' L0 q. O' B" S, Y; E) LD.编写合适的重载方法(overloading method)8 \, p n. m( K n' M9 ^
: W( d# E7 [/ t9 l3 I0 O! h5 u }8 I* k! x
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
' O8 F. G; M: v" h* |- {/ F+ P* H6 O$ v2 y
A.MVC模式
4 Y0 U* J d7 p# B2 e- eB.抽象工厂模式(Abstract factory)
$ a) m0 _. u" [0 ~. l9 \) AC.单件模式(Singleton)8 Q4 s0 @! V9 n. t9 T
D.代理模式(Proxy)
- _) U8 Q. d- T; m/ [2 \: B1 HE.状态模式(State)( U) r7 m5 \9 r o' B9 R
- f( q! h9 L: @
0 s! t& n& p3 e D, X6 u5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类? l' L$ q6 h+ R" C7 \) o
2 [: j! v5 Q" g: w+ F! p5 s5 iA.1个% B# [4 n) K& d9 h5 i- N: ^5 c
B.2个( e7 t7 J. C* |+ U5 W
C.取决于系统资源, ]: l3 m; c6 z( u9 c
D.3个3 a; c4 Z8 j& v8 I7 \+ d
E.想要几个有几个
0 z' ~3 T7 I9 y1 _+ R5 M6 p, a& i! l1 g# h) e) I# I
) }1 [) A1 h# c9 N$ f- m6 u7 N
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
3 K! C: R6 M3 s5 L- s$ @B.接口- o6 V3 |7 M: V6 L6 X
C.抽象方法
$ n: U4 ^3 @3 RD.Private方法
7 j- s' J4 \7 q4 E: k. O. OE.函数重载(function overloading)* j" \, W% ?* m: y7 j" L) ~( L
* v; T$ ]# {/ o: {. D
- I5 }. k% h2 V5 t7.假设定义了一个testclass类,它的构造函数的函数名是什么?& S4 ]& a3 A- i, H$ ^- I6 z
/ B0 B7 i1 v* @+ B# cA.__construct# V: U' y/ A, A% y5 h3 c
B.initialize
, }' n1 ]4 j! G- M9 i |' A# mC.testclass3 t$ Z- v2 X2 p- B5 }- x
D.__testclass
% R# p6 p! a8 m; U( LE.只有PHP5才支持构造函数
4 Q) W" L+ s4 b1 e* c$ ]) b
0 T6 L- R' y7 U1 U% S$ v1 k% W Y+ _$ |5 I3 \- f
8.一个类如何覆盖默认的序列化机制?- S( [' m: u# v: C( }2 H, J" O7 g
3 x, @, m# l0 N4 GA.使用__shutdown和__startup方法& [- Y6 L, x, @9 G9 `+ E& Q
B.调用register_shutdown_function()函数
! F% n4 v e9 t, x& e, KC.使用__sleep()和__wakeup()方法
5 i6 v2 s* f) H$ P8 hD.无法覆盖默认序列化机制4 r9 h# L T, b3 ^* R% a! v
E.使用ob_start()将类放入输出缓冲中
g6 y: H6 f$ x* N1 u8 l9 _3 K) Q4 Y; N) a, G1 G
+ E& M: D' U' e4 l4 w$ j. ^( q
9.以下哪些面向对象的概念无法在PHP4中实现?
1 A* X9 h5 O# x$ i8 N4 _' R! h8 Z: I1 K. _. r+ c
@抽象类
5 K0 | b- t& v# {0 _' ~@Final类5 L: K+ F* I! F- `2 }% U# m
@Public、private、protected(PPP)方法& K2 y9 u# `& C4 w
@接口
* n% `5 j a: R8 g: t# d5 f
0 [& J- O3 f5 z9 uA.抽象类/ W W3 q$ @. X# {1 G# H
B.PPP方法
; R8 I: g. A" @1 o/ x5 m( N5 {C.PPP方法和接口
, N0 m, w% l" {2 y9 Z) pD.以上所有都不可用) M$ [8 O7 i, v N4 O* N$ I! W P3 y
E.以上所有都可用# o/ B- A& A' e# g, q
7 M+ o+ c' {0 W8 G# f& h* g& P2 @! I# G
10.如何在类的内部调用mymethod方法?
0 J! O& u K1 l8 E3 T! O& o' J. Q. o; I( O2 ]5 s6 f$ x
A.$self=>mymethod();1 i ~& i" }6 A/ q8 ?
B.$this->mymethod();
% g8 |( z; h: jC.$current->mymethod();: ]# R6 M3 }% m, {4 [! X+ }
D.$this::mymethod()2 y' c, D5 j5 e& H p$ K+ x
E.以上都不对: u2 `+ Z' Z+ h4 a9 b" e# Z9 g
& _% A4 \2 T& g/ _
6 v; G4 _1 w) }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
, I2 v1 k6 u/ P% f1 gB.Null
/ x- A+ z* n1 F3 }C.Empty& N9 Q V l, Y9 M2 L
D.什么都没有& r' P; S( j9 D$ \, J, w& p
E.一个错误
0 R' ^5 Q1 O4 V% Q. h) R
! z: s: U% {8 a2 B7 I0 F4 v; w9 ]
' e2 u H& E: ~7 F: W12.以下脚本输出什么?-
- <?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, W- ]# O" H# p: L' A; T' g* M. s/ t
B.5$ ^: r2 U- g+ P$ R, k) H4 @
C.27 Z% o$ {0 O6 g1 `% W- c) }
D.Null" L0 d' j7 ^, |/ ]6 O2 f
E.什么都没有/ z# Y {( n4 r: R# M
, C: ]6 L0 N& j3 O# d( t% ]: t
& ~" C5 O7 n2 M$ ~
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
& _( h/ W2 [! BB.10
2 p1 N- |" v1 MC.什么都没有
2 v& \ _* [% {7 kD.构造函数将报错
& q% l5 y: P3 Y" HE.510
' C9 ?# U; Z+ W. u5 o7 l" \0 }7 k \6 G y+ a
7 M4 i% H: ?% n( e; A; a1 a v. q d14.考虑如下一段代码,执行时,$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函数必须返回一个值- @9 b5 l7 _/ @. E K, Y7 n) ~
B.reduce_fraction函数必须接受一个整型值* }# b. D/ B V8 z( T9 W& c
C.gcd函数有问题7 n" |9 n' q- W# C' O' c
D.必须通过引用的方式传递$eight_tenths对象
9 _% v0 w+ R2 lE.对象的实例不能传递给方法以外的其他结构。4 C+ F; f, `! R5 A
7 ~$ q. a1 X; K
5 a% U& M( T! _! F6 I
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
b4 f1 C* a% I c i+ d+ uB.生成myclass的实例并调用mymethod方法1 Y* _4 A/ H+ a% n- U
C.产生一个语法错误' t3 }6 {( L4 E
D.默认myclass类最后被创建出的实例并调用mymethod()8 {$ o* ~" x& ~, T, T4 u& A
E.调用名为myclass::mymethod()的函数
2 M q- D5 s. h2 Y, u* F8 l, x: r: K% x; b( a, z- O( E
/ Z) D4 Z, V: v* ?. |( d
16.PHP中有静态类变量吗?, c5 _! ?0 R0 J. V1 [
) l; F" y2 J2 W) g
A.有
: u, Q( C7 C2 m$ \6 e) |) jB.没有
, J7 I& W# z8 U
5 U8 P3 r% Q, y g; Y8 D# `# ]4 d! U$ G1 w( {, o- q9 L
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
% d; ^( \9 d" S: U9 f: F) XB.2
& P: P3 V5 N% |' J' K: R# MC.一个错误,因为没有定义a::$myvar
; v; d8 b; f+ s: b; }! QD.一个警告,因为没有定义a::$myvar" V, [8 |' \* `; p
E.什么都没有
. o& n8 t1 q1 ~# Z t- d! ^- Y
8 N( _6 k, X& g& }: x# m: q, ?" Q$ Z
18.如何即时加载一个类?7 u% _3 y- H; s7 V. @! L$ @1 O
}- z w; k* f0 Q! uA.使用__autoload魔术函数 a# \# G, P+ P! z1 d- A* U! ]( n, s
B.把它们定义为forward类
) G% E a4 g& yC.实现一个特殊的错误处理手段
; X: K9 O3 c6 |5 FD.不可能* A z& `& [( F! y9 I, E
E.用有条件限制的include来包含它们! ^' M+ G E4 p1 A# m
6 W8 v$ b n2 C3 y8 s8 ~7 Q
/ ~3 \ |1 g, }* s' h
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?$ O! {( d/ y1 { P
1 r R2 i1 U1 y& N# U% j6 C 答案:__________7 s, @ d% m8 v. `
1 l `/ z! z2 X7 D5 U
4 D0 a8 F8 Z, j( G0 p& v20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called, A4 r) [5 G: H8 x' ?
B.一个错误
6 A0 a8 l# _; Z/ Y6 C7 a+ NC.一个警告# }9 S, ?4 H% ^3 G) q
D.什么都没有
. \- D# E! _* U2 d* y7 J5 T% ~" y- y, K7 k
2 {; u/ Y* L3 z; ?8 O
! ~4 e" }, b' Z; j2 s答案速查
) C% k) x* U- Z7 J0 ^5 S8 T1.类
4 _( k$ i A @' k" Y$ T) [+ p7 C0 u2.BCD
) \1 g& x8 w' K% z6 |; ^* X3.C
- Z6 X$ K/ v( z4.C
9 ]# R0 I' M' ^% I* }" Q5.A
- x$ y" i7 j# U' X4 J) ^9 n6.C
- K$ o" M9 F- I2 ^8 v7 x7.C' d" T# Q; I2 Q3 ]
8.C
. K8 E% E7 F! j! }5 T% E* t9.D7 Z0 r2 J, c6 B' j; l
10.B
; \4 l, y5 o! j1 U) R# a11.D7 ~/ H4 Y( h7 V
12.B3 K) l* b. X8 }5 p; j
13.A
' h4 M! e" F' L: v* s5 I14.D5 T" G- Z2 X9 d0 T
15.A
$ X8 |1 P4 O: t# \2 ]1 M16.B: M2 R J& M& @, K) M
17.A& h2 ]7 N( |* m8 d( R# h
18.D0 n1 [7 K: @: A( i' F; X U6 V" G
19.设计模式
# t! g( R5 a2 t, P20.D
8 X3 Y, P; P: v5 n( J: K! } n2 S, l! H" \4 O' n2 U% y# `/ z, I- |
% I: E! B$ \& X1 {/ K
0 L \! i5 y/ i. g, b答案详解
3 ~" \+ I5 O8 }$ W- ]4 ]" M
. j r! g# u$ X# M! j7 n) G) I& J1.类是对象的蓝图(对象是类的实例)。
- J/ l+ b d, P1 D. c4 U7 g$ P, S, c1 U7 |! E7 v+ D( R5 L
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
$ ?0 ^. e; p, u) m; M! k3 w# B
' V) I# Y2 K. J4 Y; N9 P3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
5 X! z3 }1 Z/ Y' ^' H) S' Y
K5 f$ F( J S9 j( K4.单件模式可以限制一个类被实例化的次数。
8 V' U1 ^$ }8 \7 u- n
4 H( Z: u& s0 {0 b! U7 z, V5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
8 w: J) n" n$ D5 x% c4 Y
# z _9 g7 b: `6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
) S& f0 E7 b2 f: k' V2 ?: b! b3 z0 v5 b8 _/ j
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。) n' U, H ]9 r1 u, U+ e
3 H' @; t* k+ S" r; S- M
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。$ {! j3 E4 ?" S W/ t% p0 d
8 v! c" x. U5 @
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
- O, T9 Z, d. \# w8 T; R+ E: D' ?- I. U! Y
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。' \4 V/ K3 u6 S: J/ Y
, d1 K; A7 G, F( w
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
' M( x, l2 b" j
I8 n" X5 i6 N5 Z/ u12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。9 V/ |5 ?' P& \6 K2 R5 {
7 ]7 c" w) \4 q
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
1 l @ I! m- w
* s1 A/ a y) V4 F14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。+ ^$ t3 }0 l$ x
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:7 o# j2 A! P! {3 |! x) e
function reduce_fraction(&$fraction)0 Q8 X& [( ~1 q
答案是D。
/ ~/ w" F: H) P6 K
. v% l1 z3 ?& b7 f15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
# s: y/ v0 A4 x4 s: A( d9 o S. p8 e2 h( H9 ~% [
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。% T4 G/ {: h& m; \- ]
s6 o, l4 L9 k
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 A! V4 C, J2 K9 \
" z0 e/ ~1 F) m* [$ _- q18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。7 s$ w) {5 j( V4 e+ d$ r
8 V8 L! k! i1 {; X/ w/ V# X19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。6 a$ _( }: V2 S1 {
* Y; T v2 f, g ?8 q4 a4 ]) i; y20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|