  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。4 l, t- E+ a( C4 P
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。5 r) @: F1 g% N( D) V6 W
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。$ ~/ Q, D9 l# t, u1 u
4 J8 x# M! k1 W5 h+ a问题
$ D( G, U& p v7 H5 g' o8 O" x* ~5 z# Q$ k/ X' J, h8 K+ Z
1.对象的蓝图是什么?! S1 x7 C0 @1 W) l
: z$ _5 @: g: p6 U" k$ ^
答案:____________
6 I8 A6 G* F& R4 ^/ D: S4 c7 i7 l
+ g" _% }) b( x8 I' S& |! y: ]% C5 j6 g! I( H
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$ L8 r- K1 V; Y) @5 G, s e% R
B.b5 y* f1 n7 _; z: y' B" ]' I
C.a
# _4 x8 N0 c% k( tD.d
; R- R& s/ m r/ k: u" ]7 \/ |3 PE.e) ], v" |8 F6 a2 u; J5 I5 e
8 F0 K* H9 R8 c7 e3 s) R
6 K: V2 _! Z( D- T& ?( j5 ~+ U3.如何让类中的某些方法无法在类的外部被访问?
, ^; x0 R; q( K6 c, o! A+ F5 D" |6 K' \. N! D
A.把类声明为private
& V9 Q& @, a. S1 s) e! ]B.把方法声明为private
; G- h- n9 K4 v* m/ e+ f9 \; uC.无法实现
3 v7 m2 J2 O0 q. y4 M! ^D.编写合适的重载方法(overloading method)
0 S* ^) N' Y2 k1 B k: t1 w# G) ?; T b2 d6 f- S# ?
4 ^$ m. T; F4 ^8 a) Z# C4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
* I3 C$ R% C8 D- X3 y7 h
}* O' c' | b% \- l3 rA.MVC模式- t3 O3 B: C3 y: B* s+ s- f9 b) j
B.抽象工厂模式(Abstract factory)
: ]8 }" {1 a! B g. RC.单件模式(Singleton)5 A0 C- o6 w" D
D.代理模式(Proxy)
& u( d9 I0 r$ X1 F' PE.状态模式(State)" ^. Y3 L" F8 V0 N* x
~8 Z7 {4 R) \9 [5 W+ c6 A% s* x6 B
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?2 J3 ?7 e% K! c$ a# o/ ]7 Z
2 Y. L1 R/ C5 Q, m3 X# hA.1个* r7 Q( Y4 n7 b1 N2 i) f
B.2个6 u4 ~5 A6 ?- e# q6 R0 p2 z" W
C.取决于系统资源
3 @6 E; L' a! l0 Z$ gD.3个( u) Y# H d# f l6 x2 E
E.想要几个有几个
; `& h; \9 `: ~# Z
1 C' ^7 I& Z3 @6 A; d3 B& j: p9 G0 T S: M9 o
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
U; s& y8 {2 I9 H6 q/ w/ g+ ^B.接口
3 E/ m6 Q9 E4 f3 K+ U [4 t ?C.抽象方法
% B( a( T% X2 ]$ x8 wD.Private方法
& z6 b# m1 i: [) S3 _E.函数重载(function overloading)
; i# T: Y+ ~7 `8 {0 G0 h
: g: Q9 J) ^( D4 p7 x) T
: f5 x9 k7 R3 Y$ j R9 G7.假设定义了一个testclass类,它的构造函数的函数名是什么?
) e' |% G+ Q1 ]/ V# P
& B6 [# u% }8 k/ N9 ?. z$ E6 @A.__construct
6 _! {- f. L" a# v6 kB.initialize8 v: a( ?/ e9 V6 _- r
C.testclass3 t$ {' Y% q! ^# D, O7 v
D.__testclass9 {& J: m6 L7 o1 b2 X, R# R0 v
E.只有PHP5才支持构造函数
& Z, u# b$ k! i" G# T" B
# U; u5 \" i9 K1 O
, q* m9 i- J: t# J: N8.一个类如何覆盖默认的序列化机制?6 e& J2 |/ E/ _. B, i/ e
3 i6 `4 n4 ?# D# X4 q( |
A.使用__shutdown和__startup方法" c3 Y4 J" q! I) k9 y
B.调用register_shutdown_function()函数
, V' ?# X9 e- t1 o4 QC.使用__sleep()和__wakeup()方法
8 m+ ]- i8 X5 l8 ?, _% {2 X( ZD.无法覆盖默认序列化机制& F% J9 `" Z7 X+ U1 `+ l4 x
E.使用ob_start()将类放入输出缓冲中8 b4 e/ K O1 ]
4 J' ^* A5 O* H6 s- ?
. y) v2 X# f4 r4 r
9.以下哪些面向对象的概念无法在PHP4中实现?4 T, r' m" z: p/ W3 l
" W* O3 s. d: @ T
@抽象类
/ m7 d8 p. g$ a5 {* l@Final类
: I- t9 u- _! q@Public、private、protected(PPP)方法! X- R0 w6 l' J+ ~
@接口. ?* m0 H2 z9 j2 j2 O% A8 j
2 x7 n, z; J) z1 l2 r+ D8 n7 ZA.抽象类1 q* r L8 Z7 ?$ _# A) b
B.PPP方法2 S3 k$ Q4 r8 J! b+ v N7 c
C.PPP方法和接口
5 h7 K* Z8 d$ R. ?2 n+ RD.以上所有都不可用/ m! J" u5 o4 e9 \" W
E.以上所有都可用
6 f- `% N+ e4 _4 T% l
5 U3 A) W3 o7 I) s; h+ y' Y/ F( N& u% R5 t
10.如何在类的内部调用mymethod方法?: a& `, H: V9 L
( |& ^+ _, _( h6 H' t& P
A.$self=>mymethod();: c% m5 {" B) [- L1 p
B.$this->mymethod();- g2 }( f; f" u0 N5 C
C.$current->mymethod(); u' r5 p& A- T7 [( i1 D
D.$this::mymethod()4 \/ h9 O k8 M% ~3 D$ c0 m
E.以上都不对
% \2 \$ F: h/ u0 i. p1 p$ Y0 n" G' W% A9 T' Y
/ F8 R. t! j) U. ]# M0 n
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
' e# _- y9 |8 _0 K U! UB.Null
3 \6 W' t8 L: n* Q. _% lC.Empty+ K" g$ b3 C' U2 F
D.什么都没有1 }5 X# y) E* Z, I4 }/ L$ E; g" w e
E.一个错误 O5 b& G& W/ w m2 @
+ v2 j) B2 X2 g7 V( o, e; P* K& `# G7 I. c; D: R3 [# b) N' [
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
' Q0 E+ R* G; R; WB.5: M" O$ I( J, _' E5 v
C.2; w7 i5 i/ j$ H, q% p2 e/ d
D.Null. p) _+ \$ Y) P1 g% f' f
E.什么都没有% k/ ]' h* X S4 Y# R9 x) I" J
5 \8 I) t, A9 B/ W: U3 ]( p- ~
1 h ~2 k( O4 B% y2 i& s
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: \2 ~3 A$ L+ I) F1 J7 ]6 z- T
B.10
, n3 {( K- v/ f# ?' uC.什么都没有3 p: P9 l9 |8 N
D.构造函数将报错- a2 B8 a) C G+ U( x1 R
E.510
9 ?9 @& j- u' \6 ]; h/ D: @) `: e3 M
3 V' ]2 y9 }( w0 ?* M
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函数必须返回一个值
, k! N. ?- R0 Z3 T$ w3 {B.reduce_fraction函数必须接受一个整型值6 M9 {5 U+ a3 X4 ^6 e
C.gcd函数有问题. ?# I' X% y4 W- W( d, N* Y: I1 X
D.必须通过引用的方式传递$eight_tenths对象2 c! f- D$ w6 H
E.对象的实例不能传递给方法以外的其他结构。! O9 p+ K& d" d7 @) K
' p2 p4 P6 |, d& P
2 e1 L) H1 K9 I" s# Q% F15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法' X! H: w# y, o9 g+ F
B.生成myclass的实例并调用mymethod方法
1 m1 |9 ~4 M" W O% R \C.产生一个语法错误8 W: @. N3 L; `' b" p9 {
D.默认myclass类最后被创建出的实例并调用mymethod()! H# ^7 [$ y8 b
E.调用名为myclass::mymethod()的函数
' |1 L2 I# N& O( h. w6 {$ K" e" {: L6 N X& P3 w) Y5 R
: q- U2 Q# E( w) M) K
16.PHP中有静态类变量吗?0 [& q! t7 U% b6 E
@' M' H: ^( x8 c
A.有
6 f" i5 J8 I b* {. k4 z' eB.没有
4 z# Y5 C }6 _6 J0 k! x8 Q" |/ A/ r; S$ H$ Q6 O) y! W! j6 f1 u
?( _" }, }/ E5 h# R4 n17.以下脚本输出什么?-
- <?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
$ t, I( C% f$ H% dB.2% T. h m2 \8 {- U: Z0 ~! T
C.一个错误,因为没有定义a::$myvar
6 p- b2 |* i% P2 RD.一个警告,因为没有定义a::$myvar
# ]" C x7 J" m1 I: gE.什么都没有
+ n) f5 M4 J8 a3 b; C/ M5 Y0 k
5 I7 [0 J$ }1 X! H% ^: m/ L, @5 P
: Z# A( U0 [, b* {! |8 U) m# [/ j/ M18.如何即时加载一个类?! S! g* s' ~* C) @$ C
! q+ X5 s0 V; Q
A.使用__autoload魔术函数6 j) c* @. n1 h4 B
B.把它们定义为forward类
5 \$ z5 W+ X1 e/ O0 V+ e0 ^6 ~C.实现一个特殊的错误处理手段
! a# h3 C2 l# o6 h7 i, o M1 M. ^D.不可能
" E) |3 ~+ j# r% w9 _: aE.用有条件限制的include来包含它们4 X& h% {0 [" |8 t$ V9 ]
+ s! \) ^* g5 ]# I, J" ?) Z7 A" y: D
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?$ K( H3 E: r' A) C D
* G4 r" q/ i8 t" C
答案:__________
~% W- t7 S! k5 T! r- d- Q' p# ~2 D W9 ^' q& I/ S9 p& V
4 L0 c7 t3 j% |* }3 K5 u p
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called2 n f& p% U; g1 t
B.一个错误
+ x- W0 m1 M$ D1 }1 o/ tC.一个警告
2 T. }5 h0 S7 c8 f( W' jD.什么都没有, `5 [+ ^6 x2 a
* _, Z9 A% B B$ e1 Z7 B
0 M" U0 y8 C) v: j6 Y- h& Z; W& ~
! o9 g" |9 v; A4 ` s0 G( h答案速查
f8 b2 H' b3 }8 M1.类
4 v. o6 r: x/ A" `. m4 I) E3 U6 I2.BCD! S7 w% @7 E/ c9 q$ }. E
3.C
! ?6 o9 t; t7 d& P4.C
6 G1 s4 T! M* D8 i( Q- s5.A
8 |0 S% H; Y8 L; D5 [; l9 x9 d6.C: v1 ^4 ~* a* p
7.C
9 [( L8 b- Q* h3 z! _, z8.C
* @ V7 n3 W+ H# M6 N; c9.D+ _8 ~5 W* ]- n( T
10.B) `3 [0 Z |7 v& e- a
11.D
- M. k4 a4 N$ L1 `! n$ x12.B
7 H+ `9 n* x9 l5 G$ {13.A
$ b6 V( R# r1 C5 Z. s5 |14.D+ s$ H2 k+ p7 k0 h# @4 b) O9 f0 e
15.A4 b7 Q" t1 |! y8 N6 E: ^' C/ Q
16.B, `! c' q6 [# N' h" J/ d8 ^
17.A% _% p# z; a, G$ h
18.D+ c/ Z0 y. I' l; \, J8 {
19.设计模式, r( B E! j# P# I! H& ^
20.D
: B) Z3 Y# n0 O- C; U. k+ Y; G) O& D0 }3 k/ S
2 u1 |. S% A+ t
+ _2 w# L- T& j n+ I0 @! j7 _8 k答案详解
' N0 M: r. @3 W5 g! M
/ l8 h# @; [: [- B1 ^1.类是对象的蓝图(对象是类的实例)。
- q5 f3 f; B1 Z' U& x2 q( j8 z6 H Q, i% Q
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
% ~% P0 A$ A& ?* j, B7 Q
& `. D l& z$ w3 c8 d3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
8 x( L3 X" s2 [+ J7 `1 _3 E! o8 p1 N" M
4.单件模式可以限制一个类被实例化的次数。) W9 f6 y1 w1 z
! I, x4 G# Y4 t1 m$ j/ E5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。: W' e# V8 [9 V/ C9 k+ D
; ?$ V0 G7 N4 e- N$ d/ h$ ~6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
4 h1 |( Z0 J$ }7 ^& D& ]: M: `4 W5 a
6 }' u: ?, {; h7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。2 a' b4 v2 G* V" j$ R+ q8 _ N
- i0 p7 Z' x" y% J, L( _) y
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
G1 e# _" `* g, j- p, @
; N- e7 g5 g. d# p* B- E: s9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
8 q4 P0 t1 i' i- u! v6 v5 B. ^' Z4 h6 H4 d" l7 H4 o7 O2 \0 o
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。4 K+ J$ f3 ^5 H: O* K8 L+ ^9 U
3 w9 {& P7 R+ j" C4 J2 b# A
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。5 X/ o7 T- o" l& k$ q; q
6 m& n# ^6 g; F1 T. W/ P. } e, |8 j5 ~& p12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。1 W1 \+ _0 Q+ c8 t n
* e% ~9 u$ I* @" l# D2 E5 \) p
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。5 ?% y; N( z, F" D" Z: }) {5 g- |
/ d4 F; D! {% b
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
N$ R( X- H( F1 A0 P回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:3 i6 V% G7 M1 i2 [. Y& I% r& w; k
function reduce_fraction(&$fraction)3 n' h' V% Y7 K: l8 D2 y
答案是D。: w( q o% ~! X) o4 F2 P N$ x* O
0 {% c* l% p( t( N7 j
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
! a: E& N3 h# k8 F. E3 D) ^. ]# E* z% g4 i6 y6 d2 ?) T# J& W
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。" v+ Y# m* W0 A) \7 i8 A* @. Q
$ w& p2 t& l1 ^) O17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
. t7 p: _$ `: z% U) X
I" c N- P$ a18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
+ v+ R$ J+ f, ?/ @5 \* x* P7 M5 n2 I
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
$ q' l6 ^7 p, D4 V. ]
3 ?/ \7 w5 h' m; m; `6 K( U1 k* k/ r, O r20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|