  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14191
- 金币
- 2386
- 威望
- 1647
- 贡献
- 1334
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
$ h& |9 h7 C% K ? ^PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。/ f$ V3 O5 B/ ^+ j! B0 x
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。( R9 `4 ~' r& B& Z0 V0 {; _8 ^
8 J* J0 K/ _# t1 F3 P问题
* E' Z7 |- s; R) z& ` F: G. k% C+ N& `* y# Y& l \
1.对象的蓝图是什么?
$ I- S( C q( D N' G. Q k. [1 j
" z2 ?0 O: N: H答案:____________7 w, `7 `) r9 S- e
) l0 \2 H" v9 k2 ^, ^: v( i+ i( C1 z) d
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
+ e0 X' q6 w% E' Q: s) h7 [" {B.b" \9 G: D6 p- V* K0 z
C.a
$ ]2 {& k5 {1 d6 l, JD.d6 N, w2 W( V {1 U2 w
E.e
; M5 {% ^+ J8 b% {# J: d- ` g0 O- [! d" c: b; K+ p; \
- L+ j" V7 A Y/ r. [
3.如何让类中的某些方法无法在类的外部被访问?
4 c+ a- {/ ~0 \7 }. J D1 E* V A
8 t- A, B) A! Y$ K" T( H ]8 TA.把类声明为private
9 I; t- ]& P" i6 m$ t- x, wB.把方法声明为private
8 P# I& u& d9 H2 n* @- w" AC.无法实现7 n# }7 \. X c: F" h# K
D.编写合适的重载方法(overloading method)
. K: a2 ?8 |! M6 H. f- y0 Z' L/ N6 m* }0 q" A
/ Y+ o1 [6 D. |3 Y' v) l) O
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?8 t# E, s/ J; g
/ w, |" W2 s l" Q6 g2 g
A.MVC模式
& {. F6 {: a. JB.抽象工厂模式(Abstract factory)
) ^$ `6 H$ n; v( X3 g! rC.单件模式(Singleton)' F0 u7 G6 r6 m+ n2 R" o/ z4 T" P5 N
D.代理模式(Proxy)
/ D: \% Y& p7 B$ Z: KE.状态模式(State)
/ L1 `. {& g1 }$ C# P% n5 n' Q' z3 k1 |& _2 u% ~! l
5 k4 B+ U) S. E) U4 f' ]. q6 \! A5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
4 Z9 V2 ^3 D& N% W8 o- J% s- y3 I) q5 D3 K6 K
A.1个
- f' g c/ D# q6 qB.2个3 F( Q3 _4 r' v1 I# i0 s
C.取决于系统资源
, L$ l4 ^, p e# vD.3个- Q3 H& d% y* l) {
E.想要几个有几个
}& r( R- K: n4 P1 W; S
: _3 I% t* ]2 C. i2 m4 a# s1 V2 ^5 y4 Y2 S8 \! j. y
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承. q6 U' q- S8 |8 ]0 r
B.接口
, C0 w/ s9 h; [; }, ]C.抽象方法+ D9 ^# d+ o) |; S, }8 g
D.Private方法
/ D; |4 p& B. V. Q* E; `6 SE.函数重载(function overloading)3 e3 f, e0 I0 b! e" `7 M3 z$ `
4 m1 `7 ~: J* G i1 G
6 S5 n7 m r9 V
7.假设定义了一个testclass类,它的构造函数的函数名是什么?1 G: W/ b" X& U0 o$ G1 ?) I
2 N V& Z+ C" Y& V6 V' k- SA.__construct ], j1 O% ?8 S$ _5 \3 k6 }
B.initialize
/ c8 O& Y1 u: m- Z3 i9 c0 R8 h f, `C.testclass
$ ]' K7 J* p+ F, N6 J5 ND.__testclass( S' G8 O3 D* c1 ^" r9 k! c" X
E.只有PHP5才支持构造函数/ w0 r0 D. l6 z- x* C$ O [
: D% }. o2 Z; K( I
1 C* S7 H! ?4 l4 Y1 c8 d0 s
8.一个类如何覆盖默认的序列化机制?
, F( i/ M3 U$ H% ]1 n- V; B, t0 }8 o
A.使用__shutdown和__startup方法( D7 J( z9 e& D9 W
B.调用register_shutdown_function()函数
! h' O+ c1 C2 c' a9 O% K9 q* NC.使用__sleep()和__wakeup()方法( ^" b W5 y$ i
D.无法覆盖默认序列化机制) o$ n8 _3 ~. x* ~2 S: `
E.使用ob_start()将类放入输出缓冲中
; C* e( |& H/ @" r+ y
1 h: k6 }! L7 d. g: d; |( Y- c
4 |8 D% T4 ^) r9 J" ^; ~9.以下哪些面向对象的概念无法在PHP4中实现?8 F, r2 t$ l: d( O o9 g
6 Z3 H, X! y# S+ d% J@抽象类
% Z- e$ p- T9 F0 d2 g$ p. B K5 K! O@Final类! @6 d/ d1 {2 Z# R% G, g
@Public、private、protected(PPP)方法 I; {" Y# W& r
@接口: r$ N% }% ~4 }4 n( t) l
9 D2 e& O. Q+ s. t% X+ R2 O4 NA.抽象类
9 N6 O0 g+ Z4 l: u1 G7 \. ?B.PPP方法
, f! b* C8 @3 U" @( EC.PPP方法和接口
4 ~' D) Y% O* b& @- G* OD.以上所有都不可用8 ^1 e0 W4 T. E+ y8 @3 r
E.以上所有都可用
; Y$ F. ]- T' I3 x) e
9 H6 d# k. \3 `* B: K2 Z" I5 Q$ b" m+ a/ K
10.如何在类的内部调用mymethod方法?/ Y& n) s1 e& ~2 Z1 Q0 O+ v0 w
# l5 O% J2 p' x& A
A.$self=>mymethod();
4 s, ^2 K% z& q- S! a6 v) i& sB.$this->mymethod();9 y5 M+ i5 A6 ~3 s. P t# J8 T
C.$current->mymethod();
c8 w2 D) H2 L1 l" v* \. QD.$this::mymethod()& p3 s- \- H5 r- Q( d- i/ P
E.以上都不对5 N1 [9 l$ E$ G
3 Q. n" }1 r( ~9 @ ^
4 @& D4 g+ ^ V7 n8 n11.以下脚本输出什么?-
- <?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: N% P: L! l$ H: P5 @( }* I
B.Null
# _/ W" b! p S# d% ?# F, yC.Empty$ D [" C! P; S3 \
D.什么都没有; \. Y8 R5 }5 ]2 E' t
E.一个错误
7 i! i2 I( Z1 i0 [" C4 q" [& i' _6 L3 }& S1 g" N
7 _- a q" l' {0 M7 p# n6 f
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
/ n( | A3 \ r; s2 x1 L# K" c6 rB.5# x/ v" a" V" \! E
C.2
% V8 d, Y; L2 B! X- E% N- N4 ED.Null
: I+ w/ Y! a, z& p7 L8 h3 _3 xE.什么都没有/ m/ ]% G( m# F% H. D7 M
, o( K* L, p$ p: o& `3 ^. r/ a
0 |1 O: `3 U, g5 ~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
: D7 [ C( Y9 t/ y$ CB.10
. ~4 _' Q! c6 P* b- c& i! zC.什么都没有! M3 O {8 { V( n
D.构造函数将报错0 e7 r6 u4 g& _8 C
E.5104 l7 [: P" I. F/ ]) T# {, ?! j; N) O
$ m7 U# B# p, q5 W: s4 f U+ {$ B9 R0 { S8 z% u7 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函数必须返回一个值
0 |: v( h& W& |9 i2 QB.reduce_fraction函数必须接受一个整型值
- r- F5 g/ L2 Z/ V+ w* ~ [C.gcd函数有问题
& n0 O1 Q. x- }8 v1 Q! F5 xD.必须通过引用的方式传递$eight_tenths对象
; k _0 A# e; H+ p2 t( U. tE.对象的实例不能传递给方法以外的其他结构。$ ^; Q) c; q5 l1 _8 C- u V
* {/ T. l, R2 R6 K ?& w& x
8 [, W9 K5 R3 b: k" d8 s
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
0 q! L) A" T* }$ }4 dB.生成myclass的实例并调用mymethod方法
. e/ v0 a0 P" t) l' E& u0 yC.产生一个语法错误' I4 F! i v: O% h
D.默认myclass类最后被创建出的实例并调用mymethod()
) ~" {6 v7 j. _; x+ O8 I" PE.调用名为myclass::mymethod()的函数
) s) L! s* E9 p* }
' _ C( \% |4 l- c; M, E) K o6 F
( \ x! h3 F6 U% B9 Q* [16.PHP中有静态类变量吗?2 z5 A" T% ?. E2 M/ ~
+ `9 I6 r' A+ @: Y3 K |
A.有/ r) h% F) g6 N3 [) Q' @0 \0 @
B.没有9 g9 X! V# V3 l/ Q7 y
3 Z" u( m. _! A/ I) R$ U, G
7 Z |% E* y3 I3 Y17.以下脚本输出什么?-
- <?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/ i k4 L2 I K% NB.2
- h+ c) V. k7 N5 {C.一个错误,因为没有定义a::$myvar
7 q! {/ ]# I* yD.一个警告,因为没有定义a::$myvar
- l0 v/ C$ J7 XE.什么都没有* ?* q! X4 I' z* O9 q
8 x- h! a9 ^# t8 Q/ _9 I
8 G* H" G8 Q6 z, O7 x/ c18.如何即时加载一个类?3 K7 n" N+ Y L# s. U
4 P& Y' n. W/ ^+ Y$ O; N5 z) s
A.使用__autoload魔术函数
! D1 v$ n1 ]6 R/ J1 _* AB.把它们定义为forward类7 _' y5 i( q$ R' w) O- b; H
C.实现一个特殊的错误处理手段
5 A" I9 ] E! w3 r+ ~* gD.不可能6 \5 B+ `/ J X' H U. ~) T
E.用有条件限制的include来包含它们
7 |0 g) S0 J! v5 W" c$ M& {4 C0 ~! W) ]0 s6 `9 S, @
' K4 Q; G' h K }6 S19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
0 V3 q7 T" i9 I' \$ r# a; ?" v1 e5 E1 ]
答案:__________
9 R( j6 g( } e; B, x0 Q6 z" U z1 X5 |# V: D7 T
( K, `6 H6 D3 ~0 f# \" z5 w" e+ z
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
! H# S1 f5 n# I! P" w- o# GB.一个错误3 M6 ?3 z. L1 S0 ] T
C.一个警告- L& b i" S! [5 z8 o7 f7 N1 U
D.什么都没有" U" D; }! P) C% ]
) }. e, n" Z6 ]. {
, \5 K, s, g7 g/ q" i/ e2 R- x* e& O! Y/ V/ _3 ^* G
答案速查; T$ R* @5 J* ^
1.类4 X% Y! {; f7 O
2.BCD
( Z/ N0 g6 i, |+ {$ N3.C4 [& Z W. u# `! |9 Q+ }
4.C0 j9 p4 L% ~$ z( T! \$ j; _
5.A
$ X: L: |! n# p3 s$ b- U6.C
; \9 h. Q1 V8 K- W5 i1 D7.C2 B# Y! o+ d# R, r- Q2 x
8.C
. R5 ]! h0 t0 [6 t5 z# k9.D
7 Z" ]( ?; k- Z5 Q3 h" D10.B% g" q& `7 v* ^! F D# I' o
11.D
2 U( U! e. g: i8 r12.B1 H5 I) s3 p3 J
13.A* X0 y# @. v, d# ~7 h: w+ h
14.D
; B* f# w" p9 v" u% ]15.A6 ^* \( C x$ z' {
16.B, N0 X7 B) P- F q( C
17.A+ ]" c$ }* q: N: K" A# W
18.D5 m# k% Q X; G( T" x1 U. y6 O
19.设计模式
$ J0 b8 o5 D9 s' o/ I1 s3 O20.D
7 a, J/ U$ m* R% e1 b' i% E2 ~' |# t( o% ^/ t% c
K- S) l$ |( ^, O3 e9 m$ z6 }
5 A. F/ W: v, E: g4 H答案详解! J$ s |) X; v$ R- R1 g9 `1 r3 Y
4 O3 b1 t: F7 F8 T/ O9 W1.类是对象的蓝图(对象是类的实例)。
5 _4 Z7 q( w2 S$ ?! B7 Q% Q+ B* z; P6 Z/ V) \
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! e$ {% v; v- B6 o
! X/ Y; M0 o/ z& G ?% o( `8 ]
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。" c' ]0 |+ i* O9 W0 {' B
4 z- x( P0 A# L1 _- g: |* Y" M4.单件模式可以限制一个类被实例化的次数。
, p% T) Z2 R W$ G4 ^
1 ` F! F1 M; X" J% S V0 r5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
" | D7 O* D/ Y
I2 x: d/ X- Y1 p( x; _6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
! l% U0 c1 a7 ^3 n) d7 v% y2 }( a2 P8 s5 C
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
( I$ R' Y! X- Q5 F( A4 Q) i3 c& T1 n& P: z# o; s: c
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
; ^6 X( h3 c J# Y! K' @- S+ `/ G
" N; T+ t5 S0 x' j9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
" y- T% n9 v3 Q8 j% A6 d) O
& L# w$ X, a. B% r1 R10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。3 C+ N' c! k) X4 L1 o, F
- {4 A( j t2 |# }. t11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
8 ?, _ A; w% b2 h5 j
: M" @3 X# b6 [8 c' G12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。3 H5 Z/ G- v; m! @3 ^
& a' _- x Q' C' N1 i. o13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
/ A5 ]6 S ^! t# f% b' m+ l, O6 [! z2 U+ l! I( k
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: Y' X$ i: a/ H! B2 g7 @
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:/ N0 p# o6 _7 ^$ ]. A. Y. ~' ]9 X1 ]
function reduce_fraction(&$fraction), C; L& o/ h$ ?* u& Z6 E
答案是D。6 W& s6 S* o' C k+ x
: Q4 A1 _) @! h2 b0 q( }3 R' p' y
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
4 j) P9 h6 W; j5 j1 r) O1 g) @* T$ j H8 H1 Y- J3 m0 A; S4 r3 G
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
% W7 x. L% }/ z& h W# O
3 ^1 S3 Q* g2 ?# b17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。4 ]# K2 x! d0 V: T$ C* c: g
1 X s& x- C$ V$ E& V, i4 j2 N18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。5 Q5 d8 m( y3 \6 ^/ a* C" p
. I5 B, S6 u9 h; U/ v
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
2 d _, a5 T" O- e/ q, G. W$ U" F! L
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|