|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14433
- 金币
- 2502
- 威望
- 1647
- 贡献
- 1450
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。5 X! z# I% ]3 I& u7 H# x f7 g
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。: i f, m! \9 P: Z' @& V: N! V
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
" t- n+ P/ G+ Q2 n$ M( q+ _& ~: y" z9 F3 S" l
问题
( `4 E9 P6 q: n
: I, [5 P' R% T, ]1.对象的蓝图是什么?
; B$ A) u4 H! A' F4 |( a- {- n5 C) ^0 D } C4 s& E
答案:____________
8 V% p: m, l( \2 G$ F
) r2 @$ G& A* c. C1 Z3 H( B1 B7 x, [& H* j0 G7 v4 {6 I
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# c4 g" n. d! I9 j& M$ V z/ V
B.b
) [6 d: ?6 r) D( ~: A$ |2 DC.a
! v% {' o* h6 s6 n) d. }* j7 }D.d
( x8 W, N$ X8 v P" T3 S' ^E.e! W: ?0 a& r; g! q9 ]! X
4 Y! _% _8 m% F2 g: q% D
5 {: A( T# \) ?+ _/ ^3 ^8 Z. t7 W3 w3.如何让类中的某些方法无法在类的外部被访问?2 Y5 q: Z5 z% {4 @8 X; e
2 J! Y0 g, a9 A' x5 r# ~A.把类声明为private
9 q0 P$ N. | o+ Z& d- mB.把方法声明为private
# u2 Z% v9 T6 d) |% O' }7 iC.无法实现4 n1 U. \5 k, }& y, G. w4 ?
D.编写合适的重载方法(overloading method)
" I h7 U. p6 |# b/ e# ?: h8 D2 [' V! { z' S3 Y5 N3 \
+ s9 |4 S3 v9 q0 b% z7 x% y/ P
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
/ m7 j% ~& R( h; f+ K# y
( f' o# j+ ^4 g' k0 a" oA.MVC模式
* v' ]7 l. X u3 w3 @$ L, u5 SB.抽象工厂模式(Abstract factory)
/ S2 q; ?; f( U& z7 O, |C.单件模式(Singleton)
+ P( z. e7 ~0 |9 w: p4 q5 lD.代理模式(Proxy)
3 P1 H7 I6 b7 S4 v* x/ lE.状态模式(State)
( l/ Z; i+ G0 u% B: e
; t( q( O! B1 V3 @* `: k+ q0 `% J! m, A2 \9 ]8 r$ ?; `9 M0 B, \
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
4 o9 q# h6 O) o( T. }; c; I
9 a6 z8 v1 b+ _6 ?) K2 T% FA.1个
1 K4 |* P1 r$ iB.2个3 |! U. G3 e6 S
C.取决于系统资源* m/ M/ X% W" s! l$ e' `4 O
D.3个
9 |3 h" |7 J7 h% [( @5 l. n: o0 ^E.想要几个有几个
1 }7 o, c: F4 J/ Z
! c5 T7 z0 \& ^* C1 ]
7 \5 F% d% M# k z' T6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
, Y7 S& Z- j8 I3 Y, W) `; o. aB.接口+ h# R% F1 K: H* E; f
C.抽象方法% G7 }; i5 m% `) }
D.Private方法3 ]0 H" `3 W8 |+ t. e& ]8 X
E.函数重载(function overloading)3 g! n& e# G1 h9 o; N3 G
3 Y# y, Y4 K% H) H9 A; f
}) }6 F# O2 s! d g/ T& b
7.假设定义了一个testclass类,它的构造函数的函数名是什么?& ?* i) m: [% X' ]8 X( t
. K- u* F- ]9 |# n, cA.__construct
" P- _. x+ }9 `: i8 lB.initialize7 p5 h' w! r8 P, h# c* I
C.testclass
+ V" i/ x) ~' j0 C0 T4 }+ B* G& V; xD.__testclass
) @& E2 u; L9 k+ cE.只有PHP5才支持构造函数. n, `& Q; O" q4 s: N$ \4 d! M
. {' l8 u/ R% ^2 v& U" d' s4 O
2 ~( P" D P4 W* n( ?
8.一个类如何覆盖默认的序列化机制?
6 g9 r" D L% l' t% ?; {: a- |
0 e5 V1 j( q7 ~( D# yA.使用__shutdown和__startup方法
8 M1 G; d% M2 S7 ^B.调用register_shutdown_function()函数
8 B/ Y! q4 \! ]3 B3 B7 i; nC.使用__sleep()和__wakeup()方法# R% P% _2 l9 T2 [( B
D.无法覆盖默认序列化机制
1 C) j i1 `. A g5 P" gE.使用ob_start()将类放入输出缓冲中& t" I6 Y* n4 H: d' I7 F
- q, h' B% Y& l3 m1 R* |
9 i- O2 t# w+ [# L3 ^
9.以下哪些面向对象的概念无法在PHP4中实现? ^ ^2 [$ z! u" y6 G8 B0 o
8 [& J4 W7 E9 k2 `0 m" ]
@抽象类6 x" B( n" f7 h/ H7 i; n
@Final类0 K; h: C0 S) @+ Y
@Public、private、protected(PPP)方法
' o7 `" o9 x/ x/ ?7 ^9 C5 f@接口- @4 F2 O0 Y# L5 h
7 R$ Z4 R1 ^. l: S, h: c9 `A.抽象类
# o3 d6 P7 v- H. R3 I3 S4 F: h( wB.PPP方法. J( [6 u t# z
C.PPP方法和接口
& l' C0 w! A/ t9 }; sD.以上所有都不可用
) A7 C4 r% a$ q; ?' O. rE.以上所有都可用) d, ~8 V8 p. g/ ~ _
7 @2 K/ E! h/ D% d+ h8 x4 Z2 a
- \. q3 a; _4 c, h7 c' e# _2 B10.如何在类的内部调用mymethod方法?! a' q$ U) F; w& M7 c; x, ~
, l. H5 y. z/ C! ]* D- }A.$self=>mymethod();
3 G5 y' N! e6 V4 DB.$this->mymethod();( E4 X4 h+ {- w
C.$current->mymethod();/ r4 @. d- A- s, \
D.$this::mymethod(). L2 ^* D" D0 n* ~ g
E.以上都不对
: _% @, E2 C& a e8 p
3 b% U+ o" J3 G( t5 r, z: K+ i4 G
1 [# a: f/ w$ f8 b11.以下脚本输出什么?-
- <?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.102 l! y& Q- P. _
B.Null$ l! o: b$ c, i' J
C.Empty
2 y; h8 V8 ?, M, { j$ ?! A HD.什么都没有& R. n2 P. N. v' t
E.一个错误0 R! r& f# @7 |4 ?2 v2 H
4 X4 i. f) U4 U2 T+ E9 P" v6 U7 l/ G: d6 ?# z
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
8 y, `7 _ ~- y; @B.54 a8 v A. O' G. _2 W$ b
C.2
9 O1 U3 G7 S/ n4 x0 A7 J( ]$ GD.Null
! j0 h/ j4 D' wE.什么都没有
0 Q" e# \ |% u. `7 H& B8 h. d; |) W0 D# \3 @6 P
0 e _7 F1 x1 k4 X: f
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
( ]; A9 u3 l" |) k) \B.10
+ t& c& h y* z: x8 l7 k# RC.什么都没有
$ f$ d4 q; }- l! O* s9 G% G. wD.构造函数将报错/ ~' R2 Z+ S8 y# \; C* F
E.510
* B+ r3 d% r$ K
5 n6 O3 j) P4 q5 P" }% ]3 `" l5 | K& l
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 O1 R9 t$ V6 ?; ?
B.reduce_fraction函数必须接受一个整型值
! v9 J5 N: S0 h3 SC.gcd函数有问题; {7 Q2 o& i" M7 @
D.必须通过引用的方式传递$eight_tenths对象
+ m) }4 \. l2 }E.对象的实例不能传递给方法以外的其他结构。1 w. t% S; _0 I% R
' U3 | s7 }9 r5 Y
+ v8 }- {, x% s2 ^15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法1 P. M$ p* }8 Y& A* ^8 ^
B.生成myclass的实例并调用mymethod方法
7 G1 E8 s1 ?! T/ Z2 t2 ZC.产生一个语法错误
. |9 k+ J5 E: f5 C' z% g9 ?D.默认myclass类最后被创建出的实例并调用mymethod()
6 Y, k1 \ R+ z# j0 C @) DE.调用名为myclass::mymethod()的函数
+ n7 S2 n0 G3 @/ }* W) u& n
. ^# C# N: M6 q) Q3 e: a
8 _5 D% |$ Z! r7 F" ~16.PHP中有静态类变量吗?( X. @3 p6 Y1 |9 H7 g3 ^
4 B' |2 _2 `2 p9 tA.有' k6 K/ I7 A* h# s
B.没有5 n: {2 S# O* C. U; T+ u# T
* d/ A$ F8 T) I9 ?
4 m- p3 _/ S3 {" k) p1 x- `: t17.以下脚本输出什么?-
- <?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 w- n# P, u6 q! J2 zB.2: C$ O1 j7 B7 y5 M, N# [3 w
C.一个错误,因为没有定义a::$myvar
9 f) z1 P t; R1 v6 ^# p3 @9 SD.一个警告,因为没有定义a::$myvar
m6 Y9 [1 ?8 `/ ?E.什么都没有
) [- T# H2 r. Z+ l3 [ E( k$ p. B! i' ]+ E$ E" N0 J" U: L% e
$ l% ~; a0 c9 o; e2 o1 Y1 G18.如何即时加载一个类?1 i% @* V. c0 _9 X8 G4 p8 a
5 g" t2 f9 \5 B6 v, s% UA.使用__autoload魔术函数( l& R! s( w0 w* T l
B.把它们定义为forward类
7 B9 J" l- S5 m" d& m4 f6 hC.实现一个特殊的错误处理手段
% Z- r8 @: `1 h! q' R6 sD.不可能
9 t" J. {+ Z3 i4 \E.用有条件限制的include来包含它们
! Q c$ A: I& Q9 n- o2 }8 g" V6 i- g- A# P+ [( L
* v6 K: y* z* d7 Z+ h4 Q8 q' r19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
, Z- J9 E. Q7 v W: R1 h6 [, _. G$ E$ ^8 h6 d: a6 k
答案:__________
/ z) | r- J5 E1 {
' ^0 O( Y0 l8 x! ~1 K$ R7 y/ k* W
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
1 w* O. H! T2 t" z' |B.一个错误! n5 `* y! {# I5 Y& V
C.一个警告- T; E! v2 n) f3 J- l, R2 b3 A
D.什么都没有
2 K( L! ~. T) |( P& c; C+ b4 o0 E. v+ I6 ?0 Y) B$ p; Q. x
! H* K2 c+ p' S& Q6 Q0 C
! T- J) u( D+ x; Q( r" ?答案速查
0 C* O' g$ ^* Y, m1 m2 i$ }) ^1.类% Q! @; V$ f8 E6 c3 }& k
2.BCD- t. G0 U9 i( t
3.C: a. n4 P$ r2 g5 F! w7 T) z {
4.C& j4 Z- A2 X5 ]# n; o+ D4 \0 K O
5.A
' l: Q/ j& v2 P) h8 l: a6.C6 S v0 }/ d; ] e
7.C
' j+ ~! C# u: J9 Z& {8.C8 U. K z- ]* h0 u ]' W
9.D7 t1 h( E7 Y3 Y: E- l9 k+ g s) d
10.B
) g7 j/ A. K( S, a, b/ Z" ~5 a4 E11.D% }8 a% z) }7 V Y
12.B+ ?3 V# d, X; h: q! R1 I
13.A8 H" D6 i2 J; s" [6 I3 K# m0 U
14.D: l* d. l4 ~- d3 Y6 V- Y
15.A8 ]1 h( t5 t* M( h3 ^
16.B5 z0 H9 w2 G# Q9 O# T/ j; h1 X4 T* V* t# ~
17.A
% O2 i; d2 f k* O18.D
# ~- l G: V; C19.设计模式# O/ Z9 a+ d1 H' Q5 F: i7 F
20.D
) p% D- V" I; f% j' n) q; [. p% I7 n0 f( x
" z$ W2 W( f$ ~, C) s
+ A& Y9 D3 H( ~, a9 |( C
答案详解
$ W7 x( W0 A6 ?" T$ I- U2 ^) V4 g, O% R
1.类是对象的蓝图(对象是类的实例)。
6 v- G0 K: G7 M' F1 M" J3 ]' u& d$ a' {+ {
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
9 p4 r! ~( u- ?' a* f v" m3 M5 P( J* i: K1 e9 ]
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。4 ^/ Y X8 s, W, X9 ~* }, R, } @
& i. a$ a9 W/ K1 ]) U0 A3 U# u+ u
4.单件模式可以限制一个类被实例化的次数。5 }9 `" n9 L' b6 `6 A6 J4 A# ^* @* e
* f- ~, X8 M" M) t7 W5 \& P- H/ m3 `5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
, ^: R. Z1 j. B: a, ^
& R$ ~2 H1 N* z- O6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
+ z: Z- T9 i' |9 X, N
7 o r' B0 d G# ?& m; |- x3 \7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。( p, I/ u* b3 J, Q; V
. ~3 b# r: S: E9 }' O. \7 A
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
$ I1 l* f' r0 h' R8 z. a8 [% M+ Q3 ~1 B
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
$ Y) x& |6 J/ w# a9 L+ z8 V& k; o
9 i% Z$ E0 e# w10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
% p% B; }# m5 J6 K+ s3 f x) x9 k& A& Y" @
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
2 x$ g6 \$ ?( F( _" h2 |2 ~/ Z8 J9 c$ S7 t: F# n |9 E
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
9 H0 k0 Q# g$ M: H3 h; h+ ^2 m( ~. j I$ `" O; ~2 X
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。' ?$ G% i5 ?9 u/ R0 @5 v& e
8 a2 N" g1 ?, b% ^: ?5 \/ u9 h4 P
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。0 X( o. B$ E# _: U9 c l) p$ ]; R
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
; g8 l% Q- z9 i4 \% W function reduce_fraction(&$fraction)
5 a( p* w2 Z0 w! I; U7 w答案是D。
* K4 M* Q2 ~8 X6 t: j- t/ k( G
, d1 i5 e( e! A' Q% A A Z% J/ O15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。* d, I7 @- n u* V
- U6 X0 w. w: \( k: U1 E4 d
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
$ w \. H" Q8 `( f: @) o/ t7 m9 M+ a! A8 F
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。$ a, _# J% E2 Y/ C& b
7 t9 n5 V& q) I* J3 X& ^: c- S18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。6 M7 k+ `* X' w' n8 E
! I* c) U8 T% B0 n/ H19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。 p9 B# n# ]/ [9 P- T
1 _2 Z5 U( w- [- }1 C
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|