|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14349
- 金币
- 2460
- 威望
- 1647
- 贡献
- 1408
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
% D* i; {7 Q. u+ m1 XPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
' d1 @' D7 R% e) c! o% z8 u" z0 i& Z本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。! t9 B- C8 S% U3 B. T
$ Y! ?* ~ d6 b5 w% H; o问题
$ x# } M2 C ~ b. |
h! Z7 @9 C# W6 w# ?1.对象的蓝图是什么?: x. h* M3 B, W) a
( {0 I4 K; |( P9 [
答案:____________9 d3 u# ]% S L2 t! M( s( X/ z% m
2 l0 t* ]: e( B
. W3 d" f% y" T: I' l( S, w! R: c
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# H. @5 M7 n+ C" h
B.b2 S+ c4 k# ^/ _) X; t
C.a
7 U! I0 N/ z4 _0 V0 o9 {' c" _2 PD.d
# N ~5 Y0 l% _# I( JE.e
( P) j; n7 p8 N& ^) |. |6 U) \& C
* g* k1 W# `& a; Z- j
6 `$ \! B3 O, l/ g+ O" M3.如何让类中的某些方法无法在类的外部被访问?$ B b: G3 Z- k* s& i
5 h2 N. b8 R. M
A.把类声明为private
& Q. b- M3 e# c1 t% RB.把方法声明为private" h0 k/ ^. r9 k" s) f( M+ b
C.无法实现
( C! q4 B# N$ {2 HD.编写合适的重载方法(overloading method)
8 S! R4 x# n8 ]8 @: q# f
/ W d% a. \3 F! ~3 ^" E4 N
0 C- W- S% n: w! p& ]# r: ?5 b4.哪种OOP设计模式能让类在整个脚本里只实例化一次?1 m+ w p3 O" a! P2 P$ M d# m; d, A
) P) [/ L" H# g; g# b5 ~% x# aA.MVC模式
, j6 v8 f3 U0 _1 p( S- mB.抽象工厂模式(Abstract factory)
8 r* w. F. P8 S/ @% Z2 g! \C.单件模式(Singleton)9 C$ ]; i: p3 J, L+ N; @4 q
D.代理模式(Proxy)
/ j& N0 d* h, {' y4 R" iE.状态模式(State)) U) I1 c; ?. l" _
8 f# H7 R6 Z9 `/ p/ x
! i% x! f* ]* K4 @$ d/ |! }. y5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?' _$ [" P4 l' k
2 u1 R/ J, f" Z; n# U! _) J
A.1个; S+ D7 U9 y) [; f$ Z: t$ \) `
B.2个( d- e+ B. d9 n L! H4 x
C.取决于系统资源7 o2 k, S( v5 L* ^+ q/ g
D.3个$ Y; Q& q: `! ^
E.想要几个有几个5 D+ k/ B" r# _9 h
' C% `, T% E7 \. f1 Z7 R
6 D( U: `' n+ d J5 a4 R1 c B
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承% H/ \5 K8 S k; ^: r. a( k# D
B.接口
. c6 p( d( r* z$ y8 j8 kC.抽象方法6 q+ Q# G. t% k( p( \
D.Private方法
5 Z6 R- k; B! w" j9 d% H) F: C+ jE.函数重载(function overloading)
2 s3 e' \ L2 C: U
) H( u `9 q% w5 C& O! c7 f+ j4 A' H7 w$ B: C
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
- k. F3 H- X- `1 b- w: U7 ~, p( M f0 q
A.__construct! J. g, q% m# {: u R
B.initialize* U; x* }2 Y0 d: K+ R. \' M, w
C.testclass
0 \$ t/ o6 U9 P9 Y3 l% p$ i! wD.__testclass
. p7 f& K% T H2 ^: {E.只有PHP5才支持构造函数
( j) Q! _" ?1 g: F2 y3 P9 z7 D* {: ^$ B1 G
0 b- I- F. G- J! `# G
8.一个类如何覆盖默认的序列化机制?/ ]" R% e8 M' _' [
' W; R1 X" p6 k% \( o
A.使用__shutdown和__startup方法
$ L' g- E8 N- [& EB.调用register_shutdown_function()函数
' e; F% d+ }4 r& [) wC.使用__sleep()和__wakeup()方法/ h$ Z+ ?8 t4 b3 K# X1 L; i9 Y' `. b
D.无法覆盖默认序列化机制0 } X& r0 E& V& ] a; h0 i" X
E.使用ob_start()将类放入输出缓冲中
6 V9 b" Z' V2 T% B p% m7 \) U7 W7 P3 @
* m E6 i6 w' O9 z! w
9.以下哪些面向对象的概念无法在PHP4中实现?9 {, N2 S7 B3 [7 y; e/ b3 f6 I
& _; h4 t+ M8 u2 {& h: a@抽象类
# H3 O- y$ e& z8 M2 Q" b+ {@Final类
2 d$ n. K3 `0 F' J3 U@Public、private、protected(PPP)方法
' |# h( d, M( ^@接口
! g7 @, z# L$ G f, ^! k+ c/ r3 w, u
6 J. h( l: b+ ?- EA.抽象类* j7 P4 W% F+ {0 T$ ^0 W
B.PPP方法/ X5 u! z; E8 {
C.PPP方法和接口/ u8 m; f/ j& }
D.以上所有都不可用
9 P; Z& H9 i( UE.以上所有都可用6 H* |- e2 }& g/ Y0 B) s0 C
8 X1 X9 B8 v4 C! y D' X
# \ f2 a/ _7 Q+ k$ h! Y10.如何在类的内部调用mymethod方法?
. K8 ^ H, G3 t' `1 u2 o5 D" ~$ y' ]) S4 Z
A.$self=>mymethod();0 t" [9 x! o: n
B.$this->mymethod();: m: S& i: ^4 u5 x" }) D
C.$current->mymethod();
0 O8 v; \) ~8 W0 G4 uD.$this::mymethod()0 s, T: Z- }7 d, p
E.以上都不对
* g- O0 q; H! g6 E( g
2 ]( }# }( s$ x8 m) D
: M9 T9 [/ @+ q11.以下脚本输出什么?-
- <?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
f/ w" e/ O. I$ lB.Null9 j: K+ E# B: [6 P% @ l
C.Empty
3 |* V1 q2 M% C) mD.什么都没有
; A" G- P( ]7 U- @, KE.一个错误( A$ J+ r! z$ j K7 Z* z: T8 h% o& Q
4 E0 \- _! m( g% f! Q. N$ e
7 H' R$ O) Q+ b3 a* K$ f9 l
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
% y: l8 R/ `" XB.5
, ~7 `7 W; e1 b8 y; rC.2
8 k# {& s$ v4 M: O' T, kD.Null- v# S6 M: t' L8 F1 f1 K
E.什么都没有
( l2 b5 d# M& A7 f2 i' i5 h1 T3 X0 r- d. {$ C
3 E0 D1 f/ T" q1 C0 }3 l
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
$ g) N; }9 p) w( vB.10, D8 \0 C' A2 d6 s
C.什么都没有
) ]2 v/ q( r. CD.构造函数将报错
# q( Q9 ~: B) a0 R4 y% ?# RE.510
% u8 c# n$ e) F/ W9 `9 t a$ _
5 M2 A. T8 G# O s8 O3 x. K
! B% q V0 h8 i5 r t _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 l5 c- S6 ~( f% M. ]
B.reduce_fraction函数必须接受一个整型值
2 H0 Z: K6 {! L/ p9 VC.gcd函数有问题
8 H* T( j5 e/ v) a4 ]' aD.必须通过引用的方式传递$eight_tenths对象. R* x/ ?# z- J, h% u5 [ i4 f
E.对象的实例不能传递给方法以外的其他结构。
9 d% @6 j. r: k% q
. r! e" J8 o% ?
. i5 m% t+ {& r5 D s; c15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
$ m7 \3 A/ Y8 b/ o: MB.生成myclass的实例并调用mymethod方法
% Z8 O/ R) Y- ^: f, aC.产生一个语法错误
* A/ ^0 |. H) b( [D.默认myclass类最后被创建出的实例并调用mymethod()* D* c+ K+ D0 U3 x
E.调用名为myclass::mymethod()的函数. g" y* O* I$ A! V
' f( R" ] L3 s. c2 p9 \" v: I, | ?
2 g. }& i( p5 C* f+ f16.PHP中有静态类变量吗?$ U/ p7 U% v" Y3 i! Z# G' j
+ Z+ j/ H+ j4 kA.有
( N5 @( s; M6 F% U( |2 u, mB.没有 m5 _8 Z: w. w* w" g; U% l
' H% W8 k# s; L9 h$ h6 ^9 }0 s* _& H- C# @6 j8 J# \
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
( j7 C, O2 C M) Y( F6 {0 TB.2+ T8 l2 Y {6 P" W% K
C.一个错误,因为没有定义a::$myvar
1 U# F" i; @# v' |. d5 XD.一个警告,因为没有定义a::$myvar
6 i; F% o6 i( |: A u! X2 mE.什么都没有
" a5 k1 k9 F1 }' z- F, F- M# x, r1 q
8 i$ v5 R* p2 g1 y. I4 V8 E18.如何即时加载一个类?/ q& E" G. Q) d
6 Y! w" w& g; JA.使用__autoload魔术函数; D* y7 H+ N: _6 |4 f. z: i: ]
B.把它们定义为forward类
+ D' Y% m! z F) R) B" m4 LC.实现一个特殊的错误处理手段
, @( ]& n& X" E8 G, GD.不可能1 H( h% l9 |& n5 k" f, B, r
E.用有条件限制的include来包含它们
6 m9 S* [" C! `( M3 o6 y6 P2 Z5 h
7 p; P8 ], z! r' M1 ]1 m" @& k* g# |5 G2 b/ W
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?: y$ r# I. v& w3 ^% F9 n
# o8 ~6 p; Q: t* X. ]1 X 答案:__________0 c0 h: X; ?) p. a& d
9 b2 B$ P1 r( B/ g) t/ z7 c! \0 M; X" ?/ p5 i/ z
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
- l9 V& {* C' g: IB.一个错误1 J8 L% U: J4 \
C.一个警告& e- n( S1 o/ G. c' U
D.什么都没有 A! O. f3 E+ ?
7 l! n; I0 h5 \& y( D" I& |' I9 g' w" X; h% {
: q- k" Q% `, y v @& a答案速查
* R* i: J1 w7 P# B! |1.类
5 K: ^5 A! p. m7 g/ t i2.BCD
" t @7 f$ T1 `8 b8 t. U( v3.C$ t% u8 G8 ^$ ~) G
4.C' v! P s0 ~* \6 x8 M% W
5.A$ ~( e& }" F/ c7 j6 c7 U6 @
6.C
* Y, i# z; m8 a x2 T2 I" l8 {7.C9 X& i% h& D" s
8.C8 G/ c* d: S1 C+ p. h
9.D
4 t+ ]/ n+ G* n t% [10.B
7 K: d+ _/ a4 v& M0 t4 X7 p5 J11.D
- C. n% }1 m) U12.B
2 R1 K- J% y R3 Z1 ^1 y13.A) }4 B! M- p. {9 z( ]8 C" Y
14.D
3 O, c; v# U8 q- n+ ?* l, r15.A8 r) K3 ]3 j* \( K
16.B
' r K" ~4 q$ D# n) P17.A7 v" S; f+ F O0 M& u( V, ^6 R
18.D0 |5 s! N1 x- J( @
19.设计模式0 g3 f" h; U; ^2 u; X/ W
20.D
. ?" m* _2 y. _% b' J- [6 O+ H6 a O3 i8 T
T; l$ O% N: {3 c4 b
7 v4 |( f" x: v7 } Y/ H& p答案详解
% T! ~* b; L b* f. D: b5 }5 o
! W) c, `) O- n. C- t1.类是对象的蓝图(对象是类的实例)。
" l5 I2 p3 x) @2 G! ?9 P5 X: P3 Y2 c" X: O7 w4 S! g
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
k+ V0 _- @# M* p
3 A. c' Q2 \' s3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
5 B$ b0 F% d& ~* a C) |3 k5 @& V, h+ D. {
4.单件模式可以限制一个类被实例化的次数。
4 V) W" J" i1 i! o/ p& g6 X
0 K! H) o c1 Y6 L: j, u: h5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
6 Q# `1 {; q& P7 n) q
/ o, c4 P* d; ?. O) z% b6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。* k5 k. A6 \8 A" {5 c
1 ]$ q9 |) g% z' x- @7 z
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。1 q1 O' R3 @2 h) ?$ b' N
; g! A) L# R; I# S# x4 F) ~8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
l$ z0 U0 ?# t3 x2 k0 H# `3 }7 c5 q# ~! V
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。6 l, \% q# Q! x2 c2 A( w
6 ^& D) B! P9 S/ U2 u
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
$ G/ Z; L9 e- P- K( i. i" P0 U
* N' z3 a; K8 d5 {) ~0 m2 t8 H I11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。% p/ j' |. D! r: s% ?, g
& N9 t+ `- o, R# B: a2 _. i2 f# b9 S
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。0 m3 h( h1 A" ?
~/ ~2 q- P; k# o( y/ W13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
- F) M' t6 J/ [+ O6 z% Z' b
2 S1 w+ ^* r5 A/ j14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。* t* c7 W. I( D! [0 T& i0 b
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:! B) w1 J r F7 ^& p% K1 |& g
function reduce_fraction(&$fraction)
) H5 u& q: H. O: u" _" ]/ m答案是D。
. ^9 {2 c t* r: W$ e3 J. @+ a9 e- \2 H1 S6 ]- W5 U, [
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。9 c/ E. @: [& k/ H, N9 C/ T
9 _, I m6 m* b/ \
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。) X9 L7 t7 @3 p. R! p
# Y3 u0 i) j9 _. Q" |0 e17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
2 g9 S5 }; {- {6 N
d. C& _. ]0 V+ `18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
# w3 U* A0 a/ b5 l, t
' V3 H3 W$ s& ^ u$ k, v19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
3 }+ s) S- e1 Z1 Z! K3 a0 r. {" w4 P6 I1 a5 w+ z, |) r
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|