  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14191
- 金币
- 2386
- 威望
- 1647
- 贡献
- 1334
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
5 `# P) y9 j$ A: T5 {! V: ]PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
( [+ a8 W0 Y. V0 u: J4 ]7 b0 a本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。+ L6 A& r w* e
/ _7 p0 a8 d& P' s3 u
问题3 r* u* q% f# v! V9 R' {; ^
: K' r# m- I' b5 v9 `8 |: I
1.对象的蓝图是什么?5 v+ n- e7 P( u9 g8 J
4 H, {6 {+ }8 e0 \/ a% W
答案:____________
8 m" H2 v8 ` z8 I4 |, J+ p' J" H4 d% J3 o6 V6 f& y. r* b
# ^4 V, X; H6 u$ F0 y2.以下代码执行后,数组$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" ^* [2 r4 ]2 X' b* {* |
B.b7 t( i% v4 r" j1 z, V% l5 D5 X. w0 l
C.a
6 v) D) _ n" e# r4 dD.d
( x. G9 `# z5 qE.e
3 h; J$ H/ A& _; J- d) v9 f
% |3 p5 R$ ~1 \8 D$ R5 ^: `& D7 ?1 r% H. ~2 Y; m
3.如何让类中的某些方法无法在类的外部被访问?
! m8 J9 {: y0 H( Z. X4 }
$ P+ }2 ] e( A. @ L- g* iA.把类声明为private# U, e3 u. o* v5 ]$ ?, X; |
B.把方法声明为private
: E9 r! @5 e% p( B" [C.无法实现) u/ u+ e: F9 a j* V3 s- r0 ?( B
D.编写合适的重载方法(overloading method)# H" P* D+ U. K9 g1 J4 h' S6 y
4 \! U% y$ {. P. u4 F/ L7 c4 _5 ?6 q0 Y1 E" ^5 D8 _
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?, W1 d% W6 z* V
2 S7 H3 t* {# R8 a7 V" }- b2 AA.MVC模式
, v: f i. Q+ LB.抽象工厂模式(Abstract factory)
9 R2 t3 r; N1 M8 DC.单件模式(Singleton)
# x& m V- Q( r' TD.代理模式(Proxy)5 S3 r: h f" J
E.状态模式(State); y" E1 r& V$ d' X% c& V+ Y- Y
/ I! l8 l! G, _; E: d
6 R9 k M* K6 j& b5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
/ b% }9 C0 [" E& d, D: e9 m0 V4 I9 ? L% y7 H
A.1个3 {. I. I8 V/ K6 s3 m- m9 r
B.2个' ?' _4 v1 v6 G. W2 U
C.取决于系统资源2 B4 i3 o/ y5 t. d& f
D.3个3 g5 _0 Q$ E* `) i& e( o2 {1 e
E.想要几个有几个% u" G# a4 C' ]# z o. g
. {, e" H% L5 M3 V" Y" W
$ Y/ P" R( F, v! m6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承- }# t" q6 O, W. m$ O# W! r4 L
B.接口+ \' j8 |3 s2 k- B+ h5 i0 o
C.抽象方法8 k C! \& R, Q* Q
D.Private方法
$ N& K, J2 c5 E) n$ R4 m; z( WE.函数重载(function overloading)
/ r2 U5 w8 E& D. n) f
1 ~0 ~' n; U3 ?1 @8 S/ \2 s3 E$ F7 D1 m% K
7.假设定义了一个testclass类,它的构造函数的函数名是什么?; @% q0 L) m' P9 ^* ?9 a2 [6 l6 {
+ i0 i) Y0 v& d) z! q7 {" }
A.__construct+ y% W6 p( g) [
B.initialize. `( h' {6 T% m1 H, r# r( t, I2 t
C.testclass
$ ]9 k- C& K, Y: u, YD.__testclass
5 D; A8 Q; i# `: QE.只有PHP5才支持构造函数; S @0 v' m3 V# x7 Z8 s
8 o1 b4 O7 z% h: n. A7 q( v4 Y/ E- e o9 X5 t5 H# E( R
8.一个类如何覆盖默认的序列化机制?, }6 q2 K7 P9 C' W
5 d& l; D5 Z/ k. [/ cA.使用__shutdown和__startup方法
; I, Q( m; C- g% H8 z7 tB.调用register_shutdown_function()函数
4 a: h# v, L! _9 hC.使用__sleep()和__wakeup()方法
+ a# \5 ]! d# t2 n5 M; OD.无法覆盖默认序列化机制# e4 }2 Z3 G9 Q' C7 H M" ^+ w7 w
E.使用ob_start()将类放入输出缓冲中
0 I0 h' T c) S* H" C
% U+ y% R C* `, h; u! V& U5 C5 [2 O! [
9.以下哪些面向对象的概念无法在PHP4中实现?
9 w: R$ V% ]# l/ X- A- W. z) Z% ]9 C- Q6 z2 B! _
@抽象类
1 U- Y2 z- w4 ?, e+ h@Final类3 z: z" M, G `
@Public、private、protected(PPP)方法7 A3 m, ]) I0 S( t1 i9 o
@接口
1 e, z z( m$ ]) _% O1 U% |1 Z5 S4 f. Z7 l& Z% _1 f% m% x4 l: B
A.抽象类 o0 c4 o. w7 j8 f$ |$ g7 v
B.PPP方法8 O2 j# a$ a# k d
C.PPP方法和接口' z- K3 i- `: s+ X2 ?5 }. B
D.以上所有都不可用
- J$ z* `8 _) Q7 w0 Q1 e, _' }E.以上所有都可用
+ i1 e- E* j7 j/ x
N8 ]% n3 X1 j+ h0 T: s# d1 u+ e# a$ U9 L6 L% z! E& G! g: `
10.如何在类的内部调用mymethod方法?6 B/ @6 y, q4 k1 T4 }! E/ u k
' N1 Q( K# e G, p4 i( W: j
A.$self=>mymethod();
% m- l& g4 D: a0 S* T: S: \/ I; XB.$this->mymethod(); s' G' A" r) i: Z) U; l0 I
C.$current->mymethod();7 J7 k( s$ y0 v/ y& {6 C
D.$this::mymethod(): h4 A7 W6 u& T1 F0 e1 ~. w% D5 {
E.以上都不对7 z4 q( } W/ q: H
% _; [+ V g9 l E% T' f, c7 L) W. q* A: A2 @2 D
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
4 z& `; y! G1 S" @B.Null
% E, q$ b6 m' W& x* FC.Empty2 C, d4 u+ ~8 O3 H
D.什么都没有' M! E1 x+ U, p* p$ p. ]0 X7 M" V
E.一个错误& i& l* A0 V% c8 _+ t5 X: _
5 B$ B! t" C+ J0 b( q% [
! S1 A' S: \5 K, A4 u12.以下脚本输出什么?-
- <?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
/ L. \: Z: Q" Y3 A5 i& V+ dB.5
9 p4 |# g0 O, d! YC.2# ^% u2 n7 H7 ], v& s, K1 I
D.Null
9 O: R; }, Y K/ zE.什么都没有7 ]* ]- ^ ?' }% t# l }- i. P5 j
* i7 X) }' M) Q( U$ R- ?" b
: f$ J8 l ]+ |4 U& B4 Y5 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.5
( f0 V* T" o& F) h& [1 [B.10
) m6 a( y. J& J4 J+ eC.什么都没有! i5 [, m; u% @" c+ q
D.构造函数将报错* z, p7 Q' |* Z; i j
E.510
C0 ~' o' B' m% V% ~
% ?7 D; [- O% {0 `+ ?" z% S* O" W0 b3 k
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函数必须返回一个值
6 ]' C* n" ~# J) R9 ZB.reduce_fraction函数必须接受一个整型值+ K: I; ^/ g N. I: h. h0 O
C.gcd函数有问题
* Z! g- s# C6 [1 o# E3 M( g! \D.必须通过引用的方式传递$eight_tenths对象
5 k6 G/ [ K3 ?! Q( ^E.对象的实例不能传递给方法以外的其他结构。
' }& H+ Z5 N9 e8 h$ f2 V& q( O" W
! {& o$ u( Y( X1 ~+ m15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
) U, b$ p# d7 G# v1 \" OB.生成myclass的实例并调用mymethod方法
, Q/ W+ S/ W/ p, Y* u1 H$ gC.产生一个语法错误
" e( U4 W2 z+ f1 }( O! A: j DD.默认myclass类最后被创建出的实例并调用mymethod()$ m+ S! |. E$ ?
E.调用名为myclass::mymethod()的函数
7 z ~8 c- u- g4 J% c8 c2 }. G$ [! m5 J9 Q, c8 _
; D, V: Y. m8 t$ x1 q; \% Y% r16.PHP中有静态类变量吗?
* b+ F: j$ @# ?' c8 n9 x8 s& G: E0 A8 L0 I6 o* ?
A.有
. e+ J( V& o! n: R9 h5 F. R2 UB.没有- J5 c$ W6 j' v2 r
6 A7 |$ Z6 ~# v- _* X- |3 r, @2 m; d' z9 F
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
. l: [+ L! M* J# J6 }6 d0 iB.2% B6 Y# `: g* X0 }4 Y' f1 e
C.一个错误,因为没有定义a::$myvar8 P0 a1 o3 Y, j
D.一个警告,因为没有定义a::$myvar! I8 J( `8 l6 s% f
E.什么都没有6 y! g' j& d" s7 W4 B
8 w$ g( u7 p3 z+ q: A$ v' x
( L& T: h; F+ g8 t% z18.如何即时加载一个类?7 D, f5 x/ s' R9 @/ D0 W
3 v q0 h: ~; j; B- H. h
A.使用__autoload魔术函数' {$ [9 _) k. Y+ g: q1 u2 X
B.把它们定义为forward类* Y2 B1 i& A( U) w) \( O
C.实现一个特殊的错误处理手段
: B1 s. W; L. y4 s0 VD.不可能
7 }* m5 N1 ~2 QE.用有条件限制的include来包含它们. H1 z, M% ~% o
" f) e- O; c! F% t5 {$ b
& q& `4 h/ Z. |9 l; q2 h
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?* U# u, h! b- p0 M6 M! F1 [% F
1 Q( b t2 ?( z4 J
答案:__________
2 E/ m' {5 B- M4 H9 v- b! Y) s, x- ^/ U2 E! {, A
: }* P6 `2 f% w' @) T
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called0 q+ h4 l$ h; r& q7 [; _5 Z; o
B.一个错误
- u0 K# P$ l4 Z+ Y5 bC.一个警告
& b7 A; v2 K2 k! ND.什么都没有
R) _+ g; V& O2 d& ] k" B0 p9 e+ o# N9 ~
) _6 a7 t, }* X6 ]4 k2 g6 K# ~+ X& S. K& C5 E' b
答案速查+ |! g, D7 j& e& f3 z4 H, \
1.类
: b7 N# ^# S% ~% [. h2.BCD$ r/ q3 z; b5 j& d8 S
3.C2 ] a+ g$ ]! X% [1 [9 h5 F
4.C9 P5 I' F: U2 }6 {. L3 G6 Y& L
5.A% \( C( b/ q( K4 y5 H- D
6.C
- o. |+ T3 H$ l( @& R7.C
$ r+ K4 h* u U+ U' R& O8.C
' @' h* C: k* m$ s0 Y. i1 H/ S* D9.D) U: [" u* F) E6 {( ]/ {& k) q
10.B. V9 ^) u5 n; K+ F, B7 W( ]" W- [
11.D' a$ c% _+ v. W2 p- q- b" }0 z
12.B. I/ q6 L V7 o& `
13.A
9 {* Z m1 X9 g14.D
) I) ~- M* p I( Q" y$ W' {15.A
2 {4 Y: C# I( B( L16.B
! S3 ~: t/ N6 m7 ^6 b- P% T* u17.A' |) n% I9 v( K* S- @! x6 U2 o
18.D3 r( E! P: o" l. s/ n7 x
19.设计模式 z2 b7 V- D. E4 V5 L+ o
20.D
1 D9 b& r, p% P- `. l( F
% a0 Q* a2 Z j& `7 W7 H+ _3 _% k! F0 a0 N0 Y6 A: P' b4 \
8 V$ D& x" w, f7 a4 m& g
答案详解/ V6 D- p$ g( a, G- |
$ j4 x9 K7 b. W$ v8 {' E% z/ R' x1.类是对象的蓝图(对象是类的实例)。% Y: p3 X* M7 F" H, H
; Y6 e5 r+ Q( d$ F# j2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。 ^1 o# ^/ X* q
0 I' _" W, B8 c" R6 o/ E; Z3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
6 P! j2 ]: x. {! R" f5 F+ ^0 O" s; O& E+ Y, J: m; C
4.单件模式可以限制一个类被实例化的次数。9 d& F- e$ E8 n, B2 X8 q. V- {! C
& e4 [) j' \+ S5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。- l8 I" v: c1 W5 b& B& ]& k1 G7 L
1 ^6 w( N3 Y; [9 ]% e6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。 c4 x* e4 b& o* j% C
) W/ v; a& j; a8 V1 \! I7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。3 _. R7 M) _( E6 d5 N
$ b6 {6 [1 r, \; `5 _8 ?8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
) k, x6 s K" L. Y, E5 q
* A4 |3 o) V- T: a8 P: J9.PHP4中没有题目选项里所列的任何一个概念。答案是D。3 t% P* @4 F' g7 H2 ^
8 z6 ]0 g+ _0 A8 |- s
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
7 I: ^+ q/ {- C) Q! b& [* F) x+ \& s" Y- d9 J2 q5 m6 U7 d6 [" j/ {
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。) w! ] B0 A( u2 o" b4 t" N5 p
: ~! o7 l; e& _1 L( m7 v
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
+ X; j6 `$ d: G. ]# Y b- X& q5 t
+ g% _( \! T9 X6 c13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。8 g7 X3 A2 L" k+ P( X
7 @) | p5 u9 v1 p! Y' \9 _: e8 D
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。5 d( y% G7 ^% r4 o9 @+ J
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
+ x+ O' K1 S5 x* A' I# F function reduce_fraction(&$fraction)
8 Y+ A5 b$ n" N; U& I答案是D。, U5 S U4 g. e
/ E! K- r1 ?9 v) E- W
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。9 g( d% ~# z: C9 O
- W: K" L5 D" O7 D) v# ~16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
: `# N! N( ]# _2 F- q" _! j) R* ^7 v4 Y" D$ Q2 |* P
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。8 k9 }* y& Y+ P4 \8 o( v
2 o9 C- b* d: g* A8 V0 _' A" K9 `
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
0 ]9 `: A5 ^+ m8 y
+ p" `% ^" D9 H1 \8 t! o2 Z. s# O19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。* e. a7 u; S! F% N+ ~; E1 W
: J0 G6 ?! O* c7 \' Q2 A
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|