  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14161
- 金币
- 2371
- 威望
- 1647
- 贡献
- 1319
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
- a& n9 ~& n2 X' _PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
, @" V3 q3 j& h& S: N本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
. X" V2 z3 [" c; g, J2 S- s9 J: s6 S! g' t$ R) L
问题
( B5 k4 p k& \& s ` x) d
_6 y+ Q% I" @& m1.对象的蓝图是什么?, h R( t- U' F2 a; f; h3 _ G
; z& ~' Y' v- a/ s/ e5 Z答案:____________
; T6 A9 n7 X1 `: F* C- H0 r" j# H6 H0 R
' ?/ z q( M8 L" }* _+ j S+ E2.以下代码执行后,数组$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.c3 P" E1 }" C1 q* a2 e& u
B.b$ V0 d6 c9 A/ O5 e" p# v7 @3 L0 ]* O2 @
C.a( _8 M( D( A1 b0 X( B; }2 f
D.d: q) \7 i% ]/ d+ \8 K- q: w' ~! q
E.e; L: f3 m. H4 W4 w( f" ?& q
: O4 J# P9 _* |4 Q( J8 Y
, ~; E: C; E& \$ h$ e3.如何让类中的某些方法无法在类的外部被访问?; k& h) \# T: A8 j0 F
6 _6 o. H% I. l S: J. k. k
A.把类声明为private
1 E* \+ J5 q( y7 @& H2 [6 PB.把方法声明为private
) j3 k" ]/ }, Y& A" n4 w3 GC.无法实现
6 \; y, g0 j+ R1 Z; E) }9 mD.编写合适的重载方法(overloading method)
5 a' w- f' T) U9 G1 |
j; Z: J4 S* B9 E( R9 a3 y% ]( A: q7 S( c/ L$ T
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?: K+ Z5 S: Z& m$ A
% S b5 b( S. m6 Y4 X/ `# m2 v
A.MVC模式7 V7 B3 x9 Z5 K/ d* C [# Z
B.抽象工厂模式(Abstract factory)" y; D C. ~ K' _+ }
C.单件模式(Singleton)
. D1 i4 o* U. n* b6 z5 b- t9 ?D.代理模式(Proxy)7 W4 o5 p- W6 } {# s- M- n
E.状态模式(State)
* @ n; V: K2 c+ \$ l
; w4 ?/ b# o4 ]4 @* X2 T
1 x- }6 M5 ?9 A" O7 I0 @* D- f. u5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?" C9 H8 l8 |/ T1 R. {+ b/ X
) L% ~# g. g4 D; FA.1个4 r* p/ v+ H, L, J3 y! Y' Q/ c
B.2个2 t+ R _& u# R2 a' C& ^0 i
C.取决于系统资源: ]# ^0 G" E! w2 E7 {. i: m
D.3个2 D5 I0 Z4 W7 o: m ^4 X
E.想要几个有几个
7 ]+ ~8 M- p4 T# Y. U3 V+ K$ Z; i" {; I i+ q7 B" N
3 R D" y3 I' h2 r
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
$ r9 N: C' w4 j: OB.接口" g# ], N, n; t) y* a. }3 d
C.抽象方法
$ \6 s. w7 p4 G6 z, E/ d9 vD.Private方法
1 ]* s9 }5 m5 x4 u: OE.函数重载(function overloading)7 }; V) c3 I, Y# r
4 V% o* G0 n: M8 h" v$ ^
% h1 }( h" B+ J# q. T z
7.假设定义了一个testclass类,它的构造函数的函数名是什么?9 x5 j* A$ [1 u6 n3 X' A1 a: o
}+ q# u0 W& X5 r% {! L
A.__construct! [ G; H9 a, j+ u
B.initialize" X0 |0 J* x6 g; `
C.testclass
; \- L. U" I2 @" t1 }D.__testclass
2 c/ \. [# \+ U E, y% wE.只有PHP5才支持构造函数9 c" P, f* N' a, E7 [# C( i
4 d X g/ Z% V8 A4 A+ g( B
/ ?% v9 H. q+ s* c% H8 L+ t! k8.一个类如何覆盖默认的序列化机制?3 [/ L3 Y; l1 F# [
# \; T/ V: N* J5 I
A.使用__shutdown和__startup方法$ |) T$ a& U4 r8 V7 W% b, v, {
B.调用register_shutdown_function()函数8 ^) Z1 V2 E$ g9 \7 b' w
C.使用__sleep()和__wakeup()方法$ Z1 W* B |( N" s9 m) f. M3 r9 c9 r
D.无法覆盖默认序列化机制; s f q3 g. N, [8 J6 ]
E.使用ob_start()将类放入输出缓冲中' L7 y1 H& i4 u- n% R. X
# g! j5 l0 {# u7 i
! ?6 U8 R' r9 W0 `) T' X2 U9.以下哪些面向对象的概念无法在PHP4中实现?
/ E) z+ i: ?( b6 N1 z2 j5 F( q% K" w+ T! A6 r) T
@抽象类( b) w- v9 d$ I6 @+ d# ~. Z
@Final类
/ s i" f- A0 T2 k* k8 r@Public、private、protected(PPP)方法# I; { Z2 x. u6 ^
@接口& a& k1 ~1 s4 q7 Z
( r# n, Y4 V! NA.抽象类' J& E- k [ A. F2 b
B.PPP方法
0 g1 Q% b p: h5 f0 y' RC.PPP方法和接口
& Q5 b% q9 P# E! a+ yD.以上所有都不可用3 p* [" T, Z: }& I/ \
E.以上所有都可用
1 C6 V6 U) l" G4 a# `5 l0 j0 P9 p6 C. o
! l. w( N8 ^! b; \2 E
10.如何在类的内部调用mymethod方法?
$ k' F8 t7 O0 e2 I2 F+ C5 v- M+ S) N
A.$self=>mymethod();
4 m+ r7 D" Z0 c& v, D6 }5 {3 zB.$this->mymethod();
( ]9 A/ k# \* ]! ^3 U$ _C.$current->mymethod();
6 Q( S8 h4 I8 _3 c$ ND.$this::mymethod()
, J/ {( i3 i0 y5 }2 V2 |E.以上都不对
) B5 W% h2 H5 r" u4 w9 _! K5 K* A7 |1 O5 ~1 Y
+ C8 [5 s( \! l! v. U5 l11.以下脚本输出什么?-
- <?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.101 Y |; P* @: d; P
B.Null9 i% `, u# M' q& ]9 ^* S& [
C.Empty
5 W2 F9 b2 H7 ]1 i) cD.什么都没有9 I# ~5 z; O/ w9 @: r- O& r
E.一个错误
) _+ E1 A& }8 a% k8 u! B
^+ ^ x9 f/ s6 T# P+ b; Y
) X7 W/ `8 V6 ~2 h8 ]2 z12.以下脚本输出什么?-
- <?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
6 R/ f2 `6 K& Y! kB.5
' `1 P5 i) O+ U; yC.2
+ e8 ^* ]) u1 Q: ?4 S d6 g6 XD.Null, P: c5 { P+ T) c1 q* \7 a( ~8 ]
E.什么都没有
9 e( u j5 R, [6 H7 |, `# y+ ~/ X% R6 Z% \( v! c% _
$ t$ ?0 ^0 L, }! h9 p
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.51 x6 ?& f- I( w7 y
B.10# d& r5 c9 H, D9 z! |1 q4 \
C.什么都没有# p2 k: V k/ C) S0 I0 m o; E
D.构造函数将报错
+ p5 a! _+ s! f9 yE.5104 R3 l- ^$ b2 L% k$ W4 X5 [
; }* F. K2 J6 L& G& _, [' b8 a+ j5 A# O
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函数必须返回一个值/ Y( |1 u' \. Z" A& {0 _- V
B.reduce_fraction函数必须接受一个整型值
' q Q! G5 K) S) ~: `C.gcd函数有问题
, U. I$ X. y+ j E* u* g* bD.必须通过引用的方式传递$eight_tenths对象; M/ A. Y7 \6 J$ a# y9 k b( [, Z; J3 R
E.对象的实例不能传递给方法以外的其他结构。
6 }8 l1 A: _- z
% ]4 s' V( u% g3 p- G" B4 v4 Q3 |5 m! }6 b m
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法4 X' `7 Q; V6 m/ k, r
B.生成myclass的实例并调用mymethod方法' `6 ?7 M, ?0 z# }, C
C.产生一个语法错误
+ j2 M; ^7 c' k; Y/ VD.默认myclass类最后被创建出的实例并调用mymethod()
# P- y) j0 G: |$ [) kE.调用名为myclass::mymethod()的函数
) w/ S9 V# b/ L* {
4 M9 V* i( G, L- V! B
$ V: N2 I5 m/ r$ M: t( ?; n Y16.PHP中有静态类变量吗?
- `) H5 l( O. m( J6 N/ n" ?0 v. `1 B R( X- d8 g6 d6 ~4 X
A.有
3 n& `: C5 V8 V, U& A7 x) g, d- t" dB.没有$ f7 M) v# O, i9 ]
' y$ |0 w' u1 \4 t( O
& g* N$ P% O$ X' V* 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
0 }0 `/ g, d$ X: x$ OB.2/ O5 |# u# A" k' I9 R+ I1 }
C.一个错误,因为没有定义a::$myvar
8 Z T6 d# y5 d( ?( i1 J0 q9 a$ ~$ HD.一个警告,因为没有定义a::$myvar
8 W6 }( a& ], ~* V! |E.什么都没有8 q, J1 F: g; s. I1 c3 Z6 ~
; q# F+ i* L6 \- d9 z- \
& G3 x: c, s I, j! ], Z b" M1 s9 [18.如何即时加载一个类?
9 M6 c' ?3 x8 p z
" K: V' V9 M' C9 EA.使用__autoload魔术函数6 h( {. D: q5 A) W& C
B.把它们定义为forward类
$ F, v. R/ {& R) |C.实现一个特殊的错误处理手段. v8 ~3 q$ j% W) O. F
D.不可能
/ x2 e9 L" H0 I& [- LE.用有条件限制的include来包含它们
3 {' t3 R: h; d1 ~3 A7 e8 r6 B- j7 N8 t; I! i' q* V& ]: v
% I4 M; V1 D9 }! y$ Z G5 A# c) z' ?# y
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?1 F9 s+ S1 O# @
m3 I0 P$ _+ y% x% p3 Q7 J 答案:__________
. _* t7 r6 w1 B. N4 K) I' P. F. d' j
2 S/ J& X" ~4 g) c& N6 c3 I
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called5 _7 R* H; S; Y6 v) M# O r
B.一个错误
7 G3 u' f# a5 U& lC.一个警告3 G) g- D* b" t8 p: ]9 D- a
D.什么都没有! m7 b( p Z: C! d* y
' v, ^) t' k7 u
' @( v( p6 k/ g; S
1 Q( O2 g4 n" I3 T& G& q& L3 }答案速查- ?- I8 ]! m2 V5 Y
1.类( n% U6 B% s& W" K0 _5 {
2.BCD
' B7 H% A7 I0 {8 c3.C
, h8 n: V H- |' d) \4.C
2 F/ R5 W7 g+ M4 s# \" \5.A
3 z$ p6 ^" T; r5 h3 ^3 F/ u5 h6.C
) S; U$ ~& v2 `3 p7.C" i \0 f8 U7 J* A |) n
8.C: w3 T8 o4 w* p& s/ a2 v
9.D1 h: H) R( R1 l. b; N& ~2 }
10.B0 D" T. a: Z" y% i. U* h2 e
11.D( ?. E* k3 e, |: _
12.B7 W$ O9 | P; z3 W" W8 C" B
13.A
1 J8 ~+ w# }) C* C14.D
' `& W. H* K- f( @: n! A6 u! Y15.A7 Y8 w% n( F" V# [8 T
16.B' |6 v4 v( m# l
17.A
' C/ a4 D- U& ?# G18.D9 W1 r+ D5 N% P# [3 E! x( `1 g
19.设计模式
) a" Z" Y/ Y& V! f6 \8 t, U20.D9 U8 N, y; @1 x$ z' U
1 R3 z: l& N9 F1 `2 E4 @
* D. c K2 W+ B2 y$ {6 ?
, c/ U5 ^' }0 O
答案详解
. X- N- C, l% M" g9 Z$ B6 k$ Q. t9 }
1.类是对象的蓝图(对象是类的实例)。
, {/ [ F. T3 R& R8 \: E& `" e* o7 r+ s. |+ v- c h
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。& L8 Z- E \2 t6 k
6 j; L# G' w6 u5 c& U4 x' q3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
# u5 ^' Y' ^# ?$ N# k* J, W' M7 h, L5 t9 q
4.单件模式可以限制一个类被实例化的次数。
1 x: i/ i" S- H7 G. c5 G4 L1 l- b3 i
( ?% e0 N+ v+ ?8 O# q) X5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
1 e, @; X1 j4 G1 ^ y2 S0 U" R/ C8 }1 P p7 M
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。6 {8 ]7 h: k7 h& n7 H
2 ~, H" p+ Z, n, r8 i9 o0 G" v
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。+ v0 u% }. ?! }0 A. h: D
% W+ }" [% @7 Z9 b8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
7 ]" b) q4 U3 F; u A1 f* }; U" r% q9 j3 p- y2 F0 _ Y
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
- \; e# {. E' h- A) Z! C( |4 ]
- e5 M) W- n8 X& ^6 P; a$ v& `10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
' M- s$ o4 p9 f, @; S1 A
: g, c- y9 e1 Q$ u11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。, T8 @* e) k4 O6 k4 p+ c5 ~
; q: `' W. w4 m R- D12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。) J- O: Y/ U) B, J2 E
2 Y" u, _$ z* U
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。9 u/ q3 O/ @6 p1 V- W7 C& z
" d. H) e2 Z2 |6 f3 d& i7 \14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。2 L+ ^# J1 V6 w2 ~, j3 B
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:$ v- W' p$ w; I$ w; b+ g
function reduce_fraction(&$fraction)
7 n) p# Q/ \$ \, r' k9 q. \答案是D。
* e+ G% ]) f3 k, X$ u$ ~' @# n% ~( a! q, Q& f" _, J1 E" `; O; P7 M
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
% d* Y. @% e$ z. L2 R3 M$ Q
; P: r+ f& [) S/ N* M$ f16.没有。PHP4只允许声明静态函数变量,没有静态类变量。9 E( k1 \( p& d! ]+ i9 k: v0 h* s
0 E; ?6 ]" a% R17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。: F+ a" @) W3 C. F) k2 f3 p2 \2 z
+ z' o5 r O. ]18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
' W# t) B' X0 f. _. m' }3 }( _" ]
2 ]% p, m2 I: u0 W4 K7 r- A19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。9 H# W6 r4 i% f) @
( V, O3 ?3 w4 j% r% ]9 I1 B7 ~* e) W20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|