  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14171
- 金币
- 2376
- 威望
- 1647
- 贡献
- 1324
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
5 _. ?" `' s, e/ E- oPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。$ Q8 [0 Y% ?/ D% b/ r6 n4 P. u
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
) S: X z ^$ r0 z4 j
9 N- j4 F- F$ C. o6 A问题0 _/ X2 l0 S# R) U' J# f
- t; B) s, _8 N: l% q6 P1.对象的蓝图是什么?
; Z( ?$ ^5 `- R* R/ Z+ l5 O. s% F! N/ e; n# B+ C+ U& M
答案:____________
( F& {% p3 g) P& U) M7 q8 r* N% j# r6 C3 P
' o* J3 k, U, t2 ^$ b( G0 w
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.c2 l8 g5 M& ~& g( G* f: P5 T
B.b
% {) E) g; d, k* _C.a. Y i! b8 j6 K7 _: X+ Q2 u, l
D.d
6 x' F- c/ i) n8 G1 IE.e
0 g% P8 E- d8 Z- _( e, S [, Z; p2 K
1 Z; C9 `, @( j/ Q
3.如何让类中的某些方法无法在类的外部被访问?
4 q8 a1 s6 Q0 n, ^) K( F, T1 b; k! W4 y" Y) _; g
A.把类声明为private# ]5 U* l* l9 x% c1 j
B.把方法声明为private
9 t8 p; G, T( E! r" o9 p: gC.无法实现
- Y* c/ h$ I) E/ n; s$ n3 M( ~D.编写合适的重载方法(overloading method)
$ K! Z, e; i' ]( f M V8 \ r1 x9 M1 v+ v- S0 f
5 [3 q6 h M3 N/ @
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?) L; E1 E5 d. h9 ^0 Z: P
/ b. c: J. f* h* {4 _A.MVC模式
1 b) z* I' Z6 C* b) C. T) k2 `5 AB.抽象工厂模式(Abstract factory), F( W% T8 l6 k- Z5 y* t
C.单件模式(Singleton): g1 }9 K5 f! v
D.代理模式(Proxy)6 @4 A( F0 z; @/ V
E.状态模式(State)
! `* I0 T7 ^% e' ?* O
. O4 v. s+ A, Y+ P8 s
5 M, ~- t6 x, W. B/ v3 l5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?3 `3 I4 D% {& a* U3 ?2 `
" E$ P1 M# J1 UA.1个* u& a+ I2 ?; d2 Z7 O+ Z" [, k
B.2个
2 C9 S* a3 A. IC.取决于系统资源
7 H/ v v. A G: i7 ^/ T3 S# Y6 N0 |D.3个
( ^! M0 t5 e* ^; l% Q' a1 {! |E.想要几个有几个
( j6 I( f& N1 x- N% T8 ]* m/ M0 E/ k: I% `9 g
2 ? O' g3 L" u- q6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
9 S4 j5 n2 h. A2 B3 U8 pB.接口, y% ]: X \8 c) E! J# D
C.抽象方法. I0 ^5 S6 b: h1 A$ T
D.Private方法
( D3 B5 ~7 D6 c) I# N6 A1 A# ]E.函数重载(function overloading)
2 o9 j# C ?$ [" [, X% h1 m" H8 C/ k0 x
4 F0 o [- O8 W1 w1 k
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
' Y' i5 p+ @% d: `% ^9 n
: v% A% `/ I& E5 q$ WA.__construct
$ V2 D' F& t! D, {' y! n7 YB.initialize
]! Q) M. g0 \) ^( kC.testclass
0 \/ H8 u0 w- ~/ V/ ~) nD.__testclass
. ?; x2 Z `$ x' aE.只有PHP5才支持构造函数
( x. c& e' W6 k5 N
7 m! u! q$ b, Y$ b9 T- t- a, l1 A) ] V
8.一个类如何覆盖默认的序列化机制? M* c C; S6 N4 Y+ S7 {
g/ p5 O7 I% O& B/ rA.使用__shutdown和__startup方法4 n$ S1 m; q8 ]+ v# n8 k% z
B.调用register_shutdown_function()函数
' q( F; ?; ~# A3 U1 {C.使用__sleep()和__wakeup()方法
, E, O, ?1 X" P5 p$ h8 gD.无法覆盖默认序列化机制
, ~; o. S2 o7 Q4 M) E' X* ^! `; wE.使用ob_start()将类放入输出缓冲中
' ^& s1 g3 X5 ^3 E% L
- i- }8 [7 u' t5 j* ?: [. y7 l9 Z( `/ }% D
9.以下哪些面向对象的概念无法在PHP4中实现?) z( J& p- H4 h }) a& u- ^, `
' O' P: f' }7 `& E% g
@抽象类( n' h% D6 o8 T0 q1 `5 }2 H5 ]
@Final类0 W0 k* _' ^7 s' ?& N8 Q# M
@Public、private、protected(PPP)方法8 C5 l( |, H5 H
@接口; o4 {4 \8 S8 V) L
4 ?$ @6 _3 D5 d) ~A.抽象类* i$ k' f- e* P4 M7 k- W& Y
B.PPP方法9 L! ]5 m3 s1 T# G, p" f5 X7 {
C.PPP方法和接口* L1 `' y: q- y. G
D.以上所有都不可用
, o. _* V' C' p0 vE.以上所有都可用5 b" |+ E/ |) O7 Y
/ W" f: e! h5 E+ c5 E: y- | y" k
3 \$ r! E7 X4 |0 D' h* j10.如何在类的内部调用mymethod方法?- y$ y/ K+ W9 C/ |- Q6 R
, V5 s/ E6 [2 n, f. lA.$self=>mymethod();( z. j7 d `) I* `1 E" Y5 G( K
B.$this->mymethod();
' Q$ a" @. v* h! G: MC.$current->mymethod();! g k6 c' B5 _/ T2 q: P: f
D.$this::mymethod()
# l9 t Y6 p0 q$ Y8 m3 `E.以上都不对+ q$ k, |1 f2 x4 l/ Z8 y; \
$ s& j3 W. @6 `& P1 f3 {% }& r/ c. v8 m0 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
3 K7 k0 A" Y: Q/ a0 PB.Null3 U/ q5 S% x4 C1 w% P
C.Empty
8 l5 T7 t; m3 Q m3 B$ gD.什么都没有( c7 S. Y% ~- S& s% R: M B
E.一个错误; s- \( l) L: [2 t8 a
4 Q1 _/ F- d& W& T9 A
9 I+ \, U" I' B9 p1 t- A: z( l12.以下脚本输出什么?-
- <?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
5 n' {5 V3 n' ]$ ?9 UB.5
7 P& W# v: F9 L0 Q5 Z* }C.25 u; A2 V5 ?& C( u
D.Null
" H8 J% D) J' Q8 L3 E6 ~E.什么都没有
/ Q8 ]" H- W0 C+ z# Y2 [; I( ?( `- O+ R* C9 |8 y
: K ~9 J$ k" N
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) w+ E: q9 O% s4 {# ^' A h" z
B.107 o8 s; h7 M% J
C.什么都没有2 u* v! W! Z3 Y/ p$ n* K4 s
D.构造函数将报错0 P0 F" \ x9 _) c* s: ]
E.510 O. o- `( w+ d6 x7 M
H8 ^" e7 l3 F
1 r6 f, \ v0 a0 U; U14.考虑如下一段代码,执行时,$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函数必须返回一个值
, V+ U/ A/ p: }B.reduce_fraction函数必须接受一个整型值 a# ] ]" z0 _' v0 i: | G
C.gcd函数有问题
/ B' D/ w6 u2 s1 zD.必须通过引用的方式传递$eight_tenths对象2 O, I6 s. n! c, S0 B: s
E.对象的实例不能传递给方法以外的其他结构。
$ b$ p4 p' G8 `# H
* A# ]+ W7 U8 J |: Y0 X. K1 V/ _3 u8 T3 ~9 O8 ~$ I9 o, B* N$ E
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
4 q( C' l# [# `& @) H$ BB.生成myclass的实例并调用mymethod方法# D) |% Q. w* o* }! E* p
C.产生一个语法错误
5 F% [/ i5 I+ `5 p& o5 ~D.默认myclass类最后被创建出的实例并调用mymethod()
' ?/ H, x8 a+ R# y2 {/ \5 m& [E.调用名为myclass::mymethod()的函数! }3 k9 M# S( L) Y; h
' v4 Q" m( y L- c: f1 v& m
0 e6 g2 U6 Z% k2 n( j" L) U16.PHP中有静态类变量吗?
6 }; f6 D. n$ E) N! D0 h9 v6 P, L: P4 B6 t8 P
A.有5 }4 r$ {) X7 o9 w/ ]
B.没有* X( Z* i2 A9 K9 U( Z' L
0 N. `6 y8 l8 i7 u: t/ k! ?
+ Y9 u* [7 ?( f, x( t* P
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/ W m# f! F( Y2 l7 F- }
B.2
7 ]' |/ d( e8 Q, ~. w7 Z- DC.一个错误,因为没有定义a::$myvar8 ~0 C6 x* O4 |
D.一个警告,因为没有定义a::$myvar
; u9 W3 r& {$ }4 m) |$ I: |( e" \7 ]E.什么都没有+ ~+ @; {/ ]# h( D8 `
2 N" H* ?" o7 t- w% P+ K$ y) T& w% L S/ s7 ]" t+ z5 H6 d
18.如何即时加载一个类?
& `1 G2 M0 w/ {$ Q7 Z: u7 o1 e) A( T6 { } R s; C u
A.使用__autoload魔术函数
5 ~0 H4 u) d( c7 _ tB.把它们定义为forward类
. M5 B1 O* e" E& `% \) z( @C.实现一个特殊的错误处理手段
1 Y: n" U0 h% e" F6 e- tD.不可能* I9 `! f. G" f+ w! f. }
E.用有条件限制的include来包含它们$ B5 k, ?1 ]! Q: Y2 ~% m. q
! b- x% K, X# [ l' C n" h
* w) D3 p2 h7 S2 z" J0 n19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
, ]0 |: ]3 p; b' ~) G1 f; z! ]6 G7 \6 K# y
答案:__________
" J" ]$ H# D) k) K9 h# g. K2 Y% u+ C/ \. `9 _% d# T3 P; r
# i1 V2 I: x2 X1 D X$ d, i20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
$ g% z* R8 x, CB.一个错误: }# r! U! c @, T
C.一个警告
5 g! Y4 e1 Q0 ] ?. _D.什么都没有3 ?4 G& ?8 i+ v" q$ c) \
" Y% j5 N1 N. Q7 E9 N2 L$ n4 Y3 `2 S
( X" J8 h. E7 o+ k答案速查
0 \3 m N! p! m; L+ s1.类
. d: R' X" ~* L3 K2.BCD, W# `5 {5 E( @" m
3.C2 h. q5 D6 t5 L( m w0 D' u
4.C0 x- Z- g5 {& z
5.A
2 G, `0 l2 |0 d: E1 ]6.C
" o+ ]5 u" Q3 ]0 @$ I7.C
3 N! i( @$ w) _6 k5 C4 q, s6 r8.C5 [) M" [" t8 y, t- A6 W: H/ @, O
9.D
) R6 Q# Q5 s' I5 X+ V: Z10.B* Y# a v G% ^( ?" t
11.D+ r! x l) _/ r
12.B
! |# ~- \! A! m& k' L* y5 z! f/ y- M5 h13.A
7 }6 U h0 @% Y* Q14.D8 |# k# j8 w4 `
15.A
2 l; F* Y) R( }0 _16.B
M: q8 d5 G3 P- e4 ?17.A
4 ?! }8 A: S/ {/ {5 d8 O; n- u18.D
V9 `/ J' f4 x' @. {4 Z19.设计模式
8 T2 s0 o) @6 W7 p5 f1 c0 M20.D
* U9 E7 f3 q5 M4 \# d! Y+ A# i4 h
* J$ t' o; `+ E1 `$ d
$ U9 \5 H$ _4 K: m5 ~3 A# T3 t) Q
0 @) J3 I; q5 Y# M; S答案详解 \' F. q% d% q$ W, x/ v) M
3 P- u/ A7 M; H1.类是对象的蓝图(对象是类的实例)。
) R% G0 Z4 F% R* ~9 S$ H% e
. O8 T Z/ p& Q2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。4 J3 M0 w8 L; o3 c3 u5 q
6 b9 B$ p3 B8 l# O2 l3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。7 @8 | y1 D* h
1 A. @* `' l9 T: E0 l4.单件模式可以限制一个类被实例化的次数。
- U' [" \3 o) j; N" ~
1 W' i8 W3 j0 C- {- B$ r5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
$ @% L S+ q' V! n( o m \5 ]) c, ^+ x" w& ^% W; f; V) l% G
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。) A( o, j) |! K1 K# q
& R0 O" T! _- x2 U/ I( [/ h
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。% k4 p- P/ u* ~, g) x
/ m: E; A8 t. \ T4 a
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
. ^# n7 d* p$ r- l' n* Y( E+ ?; B! r0 t" ], q
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。7 P2 f3 m. Z3 c! H% M; y' F! M$ E
: ` X# u' A- R& A A( S4 N& `- y: P10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
4 |, ^' E; M: a, w
& D+ `+ _7 r2 j t* ~1 K2 m( b11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。8 b. q9 { g7 X
/ m: E6 t" t$ R4 z) T6 v
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
9 |5 I9 J" P0 {4 }7 N* ?) C5 C4 O& F* G
8 W5 Y+ n3 K- m# W13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
+ e. s8 }7 v/ h
4 w! w9 p* c9 ?# T14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。; A C8 U6 [2 U! v
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
* ], I6 W+ f0 y4 F6 o function reduce_fraction(&$fraction)
9 r; m5 W. |0 \答案是D。4 o4 S. ^# @* i6 I* C9 I
0 ^. d) g$ c& _) s) c8 J15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。% q0 ]5 A$ z3 i* X( b( D
_; `% L% X9 |' z3 h
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。: }1 R1 F" H0 }( u
5 D+ p2 e1 [5 n! f+ R6 y2 d
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。& l: Z7 b- z1 I5 O) r
8 {$ \' V- s2 Y& Y# e# r, q
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 z6 j: m$ L" M5 z
0 H: h$ l- _$ ?! v19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。' N: L% E, {& S2 m8 y% Q# D7 L
+ _2 u4 `! ^# E9 d: j5 a. V; \6 H
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|