  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14249
- 金币
- 2415
- 威望
- 1647
- 贡献
- 1363
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。* N! T. C9 j! e6 k) m
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。( }, e1 g* p* C* l! E1 L: u0 p; F
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
( _4 y) i( r1 h0 I0 v1 F! Z3 w/ c: T8 S0 B+ G2 c* l
问题9 a, P7 j9 o0 C
, [% ?- \8 M' M' f1.对象的蓝图是什么?. A0 ^3 E: y! S- p
% u- a# j- G5 ?
答案:____________
, }6 r6 n( E+ v6 i: s( h4 n* Q6 {! i O P, }3 t
* h2 _4 j; i6 z( a5 g5 l/ ]) U' o2.以下代码执行后,数组$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
4 a& P7 J$ }. v' l4 `B.b: F! ?: B! w; b* C3 C0 k( `
C.a9 Y- Z3 ^; o4 \! N# ]1 Z1 e& f
D.d
7 `" x* K3 c, R& a# AE.e
& G9 S1 I7 u" U% o) H2 y5 j6 ~3 N7 r5 b
9 L! N8 B8 }( w% `! N K U3.如何让类中的某些方法无法在类的外部被访问?
" ~3 k( |1 d% F8 ]; F: |/ S! J6 c C' A: ?6 X! D3 [
A.把类声明为private# v- N9 {5 E ^( c) g0 b5 _
B.把方法声明为private
5 {' b& K$ s: b+ zC.无法实现
5 n2 y: S5 x7 ZD.编写合适的重载方法(overloading method)2 y6 W& t1 D& w5 N0 Z: C- i
2 Y! ?2 u& j; p1 l: b! O3 b0 T" J
/ l& l D9 z7 ^! M0 g4 `4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
* e9 m( D' c! m3 z# V5 [. `; R! n( X* ^, x$ ~
A.MVC模式/ d- N- ?% p5 \0 B4 g
B.抽象工厂模式(Abstract factory)
9 n6 G4 y" e% fC.单件模式(Singleton)
6 Q& E7 ~; G: c& N3 w4 yD.代理模式(Proxy)
5 J% j9 z/ ^5 H% R, @E.状态模式(State)' S6 S. Q& p+ @$ |7 u( H
9 [0 t5 A" l$ {. V1 w8 Q1 ]( o' Z, j( Q) S7 q9 O
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
$ G, B7 a* S" k' F- ?8 I; q" w
/ n7 ?( L7 Z& j) G# U7 c- f O4 d# DA.1个
. L1 P- @1 K! s$ T. b! DB.2个
* s$ N/ J3 `3 |" cC.取决于系统资源
) S0 R' S! D' ?% s4 ND.3个
, ^+ K+ t2 [+ Z" {E.想要几个有几个
, M- t6 y% |: W) J# F* |/ [% {9 K* H1 z: R# Q
5 j; Z' ]- {% k4 X
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
' A4 U0 o6 }7 R. C6 C5 C1 e* |3 TB.接口7 f, p* D6 F" J# n" Y: _# T
C.抽象方法
3 ~1 Q; j- p( Y" \0 d: s" WD.Private方法9 Z. ]$ _ j1 |& f& x) _
E.函数重载(function overloading)5 ^+ m9 @1 T1 ^
- E3 G" F i, f0 h9 W; c1 b
+ I2 R7 O* \7 p
7.假设定义了一个testclass类,它的构造函数的函数名是什么?: u3 `/ f9 g @/ F1 u
1 g& d, ~+ C9 e7 c Y
A.__construct
: `1 f* E1 N1 d4 _B.initialize. G* R: ?' t; E; X
C.testclass$ i1 ~, `8 a7 ]# X. p
D.__testclass
0 U0 u8 F: n5 Q& i" |: e/ ?- VE.只有PHP5才支持构造函数
* p u4 C" ]/ O1 q, C6 S( f0 t6 T Q
$ z: ]* w) N* }
8.一个类如何覆盖默认的序列化机制?
4 q& H( K" @0 V/ q; {2 s5 h6 s
. @: w/ E; v; tA.使用__shutdown和__startup方法
% c' i& \) r3 R; MB.调用register_shutdown_function()函数
# g; X. V9 O* P3 [3 R- J1 b$ D7 fC.使用__sleep()和__wakeup()方法
- H% o6 ^: ?- @+ B* @D.无法覆盖默认序列化机制6 M) \$ ?0 B% r* e! r
E.使用ob_start()将类放入输出缓冲中8 H/ O$ E9 I2 E9 Q3 W$ x
* a# B$ R( J* B) Z, G9 N2 G M* @( X6 G% B7 p0 b
9.以下哪些面向对象的概念无法在PHP4中实现?7 r( Y$ _: v1 `; S
) i, p( M7 n6 _! [/ Z8 `@抽象类( S: z+ I9 E" M# y0 m; m2 `
@Final类
4 p, s# V& W1 H' ^# d, w@Public、private、protected(PPP)方法* B/ Q- A, B# i! L( K
@接口8 w2 Y, z/ n4 V* [% [* F
E x6 X. C. |. N5 L% o& h* y! s
A.抽象类
$ u+ c& E, ?6 q0 {2 T, z* AB.PPP方法
% Q' i0 C3 ]' e7 F2 W1 t% fC.PPP方法和接口
' l5 y& [: x! nD.以上所有都不可用; E& |+ u$ Z' m' b
E.以上所有都可用
2 S0 D0 D% r8 P! U7 J0 D6 f( |9 _( x* [* R
% b- O" A. _& ~; r1 P* @7 i
10.如何在类的内部调用mymethod方法?
0 w- }2 m8 ~5 ]$ o% Z z
P Q3 [5 x& `4 l6 xA.$self=>mymethod();7 o7 w1 B F# m0 x4 @
B.$this->mymethod();
9 W% V, t- |* w" K6 S0 r. \C.$current->mymethod();2 V2 k3 r8 V8 y6 a
D.$this::mymethod()
. ~* ^0 w, E: k2 gE.以上都不对$ P/ w r9 A, @/ U' R
* |# g8 Y; `% {) `/ I% N1 C
5 U% S! v& Z3 J
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
* w; ?7 z0 A" d) V# PB.Null
0 M1 N9 T6 K( {" S& h0 y+ U. ZC.Empty3 r8 m6 b$ r N0 r. v3 b
D.什么都没有
4 w/ {$ p$ H. q9 g1 N3 \E.一个错误) }5 J4 N6 H! Y0 j9 C8 Q
; ]6 a0 f6 z* |" M" m5 w( [' i$ f7 V
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% [( A) G7 I) q; f2 ~
B.5
- f) B0 l4 z0 ~/ ? XC.25 @/ p. C& q0 I: ?; o
D.Null; a) ^, S2 Q, ]
E.什么都没有3 r+ b) C3 Q% ]8 C3 C
q. X! d0 x$ i+ n
/ [2 P3 v4 m& {; m13.以下脚本输出什么?-
- <?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
" l# o- k4 S, e7 V3 ?B.103 I, t7 ]# z) w1 j
C.什么都没有
/ V$ c1 u; r% a+ h' z, ]D.构造函数将报错& f; O& S. ]8 i/ M1 M, v
E.510
4 D& ?5 c4 N! m9 ^$ a( {' z! x& l/ N# y" Q6 M# R
( k( _: ^: c* \; k% 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函数必须返回一个值
$ d9 v5 t# K& w; Y/ BB.reduce_fraction函数必须接受一个整型值' ?5 L# |; I8 y- L5 Z/ S/ W0 @
C.gcd函数有问题2 o, s/ N2 T3 r$ ~3 y- Y
D.必须通过引用的方式传递$eight_tenths对象. z3 P9 n& y @% A( p
E.对象的实例不能传递给方法以外的其他结构。
, ~( M" {7 W7 g; E9 X- X
: z5 [- ?( P" U- c: x: ]/ o2 f+ v
2 s& v3 _) {8 v5 I15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法* u+ N' n' _1 v" E
B.生成myclass的实例并调用mymethod方法
( _' a4 p! O, n' W. IC.产生一个语法错误
# N7 G- x/ ^6 J9 S* a$ J2 CD.默认myclass类最后被创建出的实例并调用mymethod(); B% y) a% s0 `, G
E.调用名为myclass::mymethod()的函数
8 Y* O5 o( p& `% k/ C
; W2 c4 ^1 ?3 O8 T! W9 V% Q: Q+ R' V% W0 O2 s, U3 ]; ^1 r
16.PHP中有静态类变量吗?- C' P* O: u" K4 W9 |5 f7 S: W
$ b( a$ r* X+ f7 r$ |A.有 a0 C4 E& L. H1 ]1 o9 j. P# J3 b0 c
B.没有% X, T1 x6 [0 D8 _' z4 {+ i
8 B& `7 o; }4 G. Z/ D
) }8 _- k5 n& W6 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
+ c: |5 S2 Q/ [B.2
: G W. R4 M/ [9 a- R/ LC.一个错误,因为没有定义a::$myvar
+ x& {( h# j( ]* Z: c8 C [+ CD.一个警告,因为没有定义a::$myvar
8 M' e0 i w. ~) y0 w( _E.什么都没有) H5 M% S+ ]$ K/ g# F( m
b5 a- v9 K( p3 H; K# W* @- k# C/ J& D" d) c8 {* V2 H/ j
18.如何即时加载一个类?
5 u- }9 t: @1 i# n
: i$ L. W: T1 B QA.使用__autoload魔术函数
- x/ w% { S! B+ n- W0 \. o; OB.把它们定义为forward类9 t4 ^) d$ _9 R2 r3 X
C.实现一个特殊的错误处理手段& b) `2 i0 Y3 p' }( @; X, C) k
D.不可能
- o( v; R* B0 y( j- ~2 _* w9 D- G$ BE.用有条件限制的include来包含它们
% t z" p' C1 y0 E/ I: A% p3 {; N" N
# u( u9 s% T0 O0 @6 |( C
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
# q4 F/ \. w' F0 |
( x5 B( g) C+ v* x8 a" ? 答案:__________
) g' P$ I3 f7 H: T% C5 s2 c8 x. }4 D- t. I: G1 R4 H: ]' p- ]
, h: S0 f5 Q- D; v2 U* ~) |5 g20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called- E4 B i6 z: c3 |" {
B.一个错误# C# O. V# z! T: \& J! l
C.一个警告
$ g3 v/ I1 |$ R) q( w/ d/ z, SD.什么都没有
" Q+ J+ u- m5 Q( M
9 x! i# x ?) Z0 F8 u2 @0 k2 L# L( o, G( `% u1 o
4 Y( K) c- ?1 Z0 F. @7 d/ ~ ^% m
答案速查: A! i) l7 q4 m: i2 f2 t: \' F, c
1.类
2 y. S' i* J1 d. ?% b2.BCD# F" k! p5 B+ U9 q" t. H, l
3.C' Z& f, t* U0 o& r) K+ Q
4.C! Q: E0 C) X, l1 Z5 M3 w3 v
5.A
( P- U. C v# f" ~) n/ i7 |- [6.C
/ ?" W7 Z" C9 y: c4 L- z" L. T7.C
8 t" M' e: o" V0 ^! I8.C
9 M( F, u, x1 ^9.D2 C1 Z6 j e5 |% I5 F
10.B
- ^4 Z0 L/ i# r* h- U11.D( m) R; F7 v3 g. J0 O* e
12.B
: N# _$ C/ g2 O: T13.A
: s' @6 t3 O$ v: n; P, v3 {14.D4 P' E. y j6 X
15.A+ v8 T) n5 s9 B) P" ^
16.B
* i% @: e/ M/ h x4 O. Y17.A! w% d/ N- R( X1 n
18.D0 D# f# [8 r" H; L
19.设计模式
" s" n0 k* J9 j2 z$ o O4 Y20.D
' a- E: F/ F) h ?6 s2 R* N. @! Y" V( c# k3 c/ E0 A2 n) E/ Q9 E I& h/ p
9 [' s0 i1 W' F; V' y' b
1 Z' o( l% ~ ]+ q( d答案详解
& b) T0 y9 U, `0 F' B: D
3 [' [1 J* o2 X1 S: L1.类是对象的蓝图(对象是类的实例)。
" C- Z. X0 e( o0 _" [2 T) D% k4 ~4 q1 @1 M$ K/ l O) |
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。6 }, a" a. D" p& N9 t8 l1 b- O
) K& t9 N" a" k: b9 O, F: T% \3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
! @, z ?! @5 R! M9 Y! {1 ?$ h5 J) O9 A5 o4 G* s. a) N- d- J9 ?, k2 f
4.单件模式可以限制一个类被实例化的次数。
. l8 {- k" a5 a# Y2 R+ }) d# a! O( O$ ~0 u
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。. [: [5 z7 g. X C1 q6 q g
+ p/ Y$ {- {+ d0 T
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。) U% k6 f2 @+ K! V. m. N: \# G! I( {
% n$ U$ u+ B1 U: l) k9 T! d7 K8 L( ?
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。; t7 r! f& T5 ]* ]
$ `% J6 o0 o, D- W/ P# x
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。! t* H# S+ g" N7 |" }/ b$ W
/ g- D1 j$ } O* c! U. |; c9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
' ?8 X! R& t" J* F. h. G) J f
3 w& X( i0 e: U+ D10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。% z, l% u( Z; F
6 F+ J- T) O5 K; g3 d* {' z( w/ {4 _2 T11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。* T2 b% j. m9 U |
! _; P- ~: s1 V* d/ j: W- G12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
/ y6 d$ k% F6 q5 L
1 w4 y' B0 W( J& `2 i13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。+ b# k5 l1 s/ y8 h# q5 A
! G; q. f9 { F( g9 U14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: T/ S% C4 L8 ]1 X7 ]5 H
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:* [) b4 C2 o$ _& k7 T
function reduce_fraction(&$fraction): }/ i- m- B) A7 m
答案是D。
4 t& `7 \3 J6 a2 p8 T
. v6 T3 p" u. m, n5 V2 }* H15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
- {2 r3 M) ` J6 \* g7 n5 K. B7 s. ~# G0 g5 p1 M9 z
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
: |0 e( F6 G, Q0 @
$ e$ o, H" e5 l9 X17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。' Y! d7 u6 u ? r' Y4 D7 h7 P# A
n5 O& _- V$ {18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 [+ U. o. ], y
3 A! Y- U9 G: G. k5 K4 l19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。1 v/ ~$ N6 Q( l& G! U+ y
! c( A0 f3 L! p; n20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|