|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
- b' l% r: X- W, u3 v FPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
2 V$ r6 @5 ]; v+ B5 ` [本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
7 O$ o$ F% L9 R! L: n' A! ]/ H+ ^5 _: H& d
问题
2 h6 {7 D3 {& h# H& s; B3 k, l" h# D) E! A, b' O( O5 P
1.对象的蓝图是什么?& c! c6 f5 ~6 I0 Z1 a
7 C$ ]9 m3 ]$ p) F& B- c/ ]答案:____________
. _" X; l, [. O: \6 ] Q4 }% e; T% o3 L
4 {$ e' G& D* 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
0 H2 K! f. S( E4 AB.b" u: B# d4 J! a
C.a
, ~1 S; m6 l1 h6 l9 jD.d
! @, T9 n8 F" n3 y5 u3 `6 ~E.e J$ e) u- W: i! X* E1 q
# D1 g N. X* a5 O( W) g7 t3 o3 k* T1 o- X- J
3.如何让类中的某些方法无法在类的外部被访问?2 T1 U F' N8 n7 j2 G5 P
! j$ P# f( R _: S& c/ {
A.把类声明为private' U! T4 E7 V( L$ c- @
B.把方法声明为private
+ x7 Y0 M7 r, x0 r$ PC.无法实现3 h: Y" n( F/ ?5 {) r6 U
D.编写合适的重载方法(overloading method): V6 b7 L K) W, ?! \7 ?
* u- c" F1 d/ ?2 M6 e! n
+ f, C$ G0 T3 [4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
0 V5 K2 t1 D0 j) J5 X2 [/ _1 F7 V( D! {6 v9 ?% [2 Q& x
A.MVC模式- l t7 V7 A6 L
B.抽象工厂模式(Abstract factory)- Y# \" U# j! m# H
C.单件模式(Singleton)8 B2 E9 W. y3 p( |
D.代理模式(Proxy)3 B! R) Y0 Y& Z8 O! y8 n, ^
E.状态模式(State)
) y' [- V& V5 h! _' z" U" o- D/ e' Z0 p' W( k; Z% y
+ p3 n( d! {: W1 ?0 D& v X
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
- s0 N; ~5 d* E Y
9 N, p) {0 I- b/ n3 P2 m/ IA.1个& i/ j8 V$ W2 |
B.2个
% f1 g4 D& C# I0 F, [/ LC.取决于系统资源
- z5 G# L7 D! H$ l4 Y% q3 UD.3个& U: t i0 c3 ^3 ?) {) D
E.想要几个有几个
& @: X( e) Z3 s. c. g# e5 B( a5 @) Y7 g6 r/ r3 q7 }
7 N) n+ ^9 [& p, E, r! [7 s# V
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
4 l0 i% E9 k8 N B5 P( ^* vB.接口
; L( j/ g$ g% d! W" j, }C.抽象方法
5 s( V5 d; ^1 R% p% I( p$ k: jD.Private方法4 w) _+ A/ j- q
E.函数重载(function overloading), e9 ]. J+ w9 h6 d& W* }
/ _- F. j* { y% N/ _
; L B1 D9 W: v: F* G/ G7.假设定义了一个testclass类,它的构造函数的函数名是什么?
1 Q4 d0 d4 x' N
; m- _' I3 F `5 JA.__construct9 s/ x* i+ B% z. n. k* K% l% _0 y
B.initialize
: o" ~; a% I# N$ T) y5 f( bC.testclass& U1 H6 e$ V5 g/ _
D.__testclass
( s+ S% h0 {- [. h! \5 }E.只有PHP5才支持构造函数
: H) o5 s& Z4 R) d" m
' H! Z% @4 h0 v' [5 ]" O% F9 b
$ Z l5 O# Y9 O$ ?8.一个类如何覆盖默认的序列化机制?# ?% W2 o* C9 u6 [
3 Z* C+ e" l' y7 m& v
A.使用__shutdown和__startup方法0 Y! B* F# c; Q# N4 q) Q O) P
B.调用register_shutdown_function()函数1 a1 C h, q6 i/ b" s" R0 G
C.使用__sleep()和__wakeup()方法& @. s$ X# b8 k5 \
D.无法覆盖默认序列化机制/ L3 c% \" e ^7 I' c
E.使用ob_start()将类放入输出缓冲中
$ L$ s( f$ ]9 Z1 g6 Y
5 T0 A' W( i& E3 c3 x+ {- |( Q0 Y' p6 j- F2 v* ^6 f
9.以下哪些面向对象的概念无法在PHP4中实现?& K* N. m: W" ~/ ]
9 Y1 G4 l3 g! h3 L; y8 X@抽象类; U; l$ w+ @% y' U: Y8 x, X
@Final类( J1 p# @% ~4 l/ ?$ x: x
@Public、private、protected(PPP)方法
5 A: t& M3 f* X( c. m0 M@接口/ i$ H8 V, X# x M( K
. ]% ?2 x& Y* ^, O1 Q, b
A.抽象类0 ~ r. |9 I7 I, q
B.PPP方法0 O4 V/ L4 C9 E9 J
C.PPP方法和接口1 r$ P+ J7 g, K5 a# p
D.以上所有都不可用. d9 [/ L2 Y3 @& ~& P2 ?
E.以上所有都可用& l+ l& K2 N* d' J4 h. G( C/ N- h
) U# J: X- K1 n: u
) J" ^' F- ~5 U) A. A7 b4 i; r10.如何在类的内部调用mymethod方法?" |* ?- `6 i. o* G; k/ F3 }
+ K( k; G+ [3 D7 ?, \1 w( j
A.$self=>mymethod();4 m+ `- O+ }+ [9 d
B.$this->mymethod();
( \0 N5 ~5 A, i. F$ [C.$current->mymethod();
; u D2 y, `9 b9 r& ~D.$this::mymethod()/ U7 b: ?2 @3 m4 m" w
E.以上都不对
7 ?: w1 m! I$ u$ {0 p! n2 \! K5 q
9 [0 c( P4 v% T. O' B
% ]" n# C2 H. s9 J/ n+ H# y0 K11.以下脚本输出什么?-
- <?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 w6 _3 D2 J4 O& q
B.Null
6 e: r s" J# aC.Empty
' b: @/ N( m. n3 t+ l+ M$ h" aD.什么都没有: B; ~9 n2 \4 Z& ?
E.一个错误$ c6 e( [" w) M1 N6 H4 N$ x
* a8 p$ E- ~' D7 |+ u# B+ D" y! V2 s: @- H9 n0 E
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
) z2 U1 r2 ~$ x' V$ [B.5, O+ l5 _: [5 g9 U% m4 V
C.2
3 b8 O) |- E% R% JD.Null
. k. P2 P/ N& Z. CE.什么都没有
% _$ e! F& J6 @, J- V( w% N }& A* A* X/ ` L$ l
. l4 a3 Q6 K) V" W
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' ~ \2 g8 F5 r! Z
B.10- w8 t! R' t- ? R: l$ c
C.什么都没有6 n8 P. P3 Z) Q' T" h0 @7 ^
D.构造函数将报错
1 M4 O+ @3 q6 B8 L" G: pE.510 N+ ]$ ?' b2 E: ~
- R3 ^( o# ?, R( `
8 `% x$ a9 q2 r2 C. x% ^# B1 B$ 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函数必须返回一个值
! V8 @1 g2 }0 Z/ dB.reduce_fraction函数必须接受一个整型值
$ B6 |6 \+ u6 U C6 LC.gcd函数有问题
6 i# @/ c f- y: _3 WD.必须通过引用的方式传递$eight_tenths对象
A6 i0 U% V9 O" g# |E.对象的实例不能传递给方法以外的其他结构。
$ i9 P8 s0 o4 X5 S
5 q, r4 t4 E4 D1 y, K
# k+ J1 [/ J# G- m# P' G' n/ p15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
' h; Y7 g- L; K+ @, Y! ?B.生成myclass的实例并调用mymethod方法
1 B2 A$ g6 j$ d) b, U. p( I: J- V& |" |C.产生一个语法错误/ [. V8 X3 ]- S! X% ~: r/ ] i
D.默认myclass类最后被创建出的实例并调用mymethod()
+ k3 I- H7 K' k% q. nE.调用名为myclass::mymethod()的函数
% o( P2 R' T* b, C+ Y) b: h7 \+ t1 \. j! W, Z+ _3 l7 i2 d, i
; Y/ C# j9 w9 d: ^2 ^16.PHP中有静态类变量吗?/ h' L" n! w A% V
$ ~4 u& a* ]; i/ SA.有5 a4 K* U5 V9 D: a5 Q
B.没有
0 j0 \, `, N, G2 h7 n* L+ c% I& P( j4 X
1 U/ l0 Y0 h# o! ^% o; ~6 o17.以下脚本输出什么?-
- <?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.16 v4 P9 a6 l8 ?
B.2% K8 i/ F) Y# q3 B: N
C.一个错误,因为没有定义a::$myvar. b: ]& n' p4 T
D.一个警告,因为没有定义a::$myvar, a$ q1 R/ m9 G) O; {+ M8 L s3 ~
E.什么都没有0 q% B" D. |+ n* o# D8 G
/ Z b4 o2 `" l2 ^( |
5 M1 }0 {1 O1 s
18.如何即时加载一个类?
* H1 L1 Y; B& y! ~1 J0 l: ~9 K. n' O7 i4 M. d
A.使用__autoload魔术函数
( E" p- [7 P7 |- M! FB.把它们定义为forward类5 w! x, e7 x' q% {; M, u
C.实现一个特殊的错误处理手段
7 [( \) l& H; n( t' ID.不可能
. }. F1 B9 u1 y; z3 jE.用有条件限制的include来包含它们
" [* P8 g) L9 ~$ Q
" O5 k) Q* F! i G. ~8 E
% s4 X$ t4 s( B" z19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
; \8 v! Z- K1 {* w" ?1 Q9 `/ l2 k- L5 o
答案:__________1 {% X/ [! P5 {: e
/ u% E3 L0 C5 _: V$ K* _2 G
4 q7 E' i( F2 h4 q# o20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
& l5 z3 y R0 c, PB.一个错误' s8 B5 V: C. w
C.一个警告
5 o6 a+ `8 b; ]D.什么都没有
/ o" H" F9 K$ ~# ?! c
8 ?. Y1 z9 e0 g! Q; n
# ?9 x0 C3 C; ^! F
; }- F. T5 H. S" }7 T1 K* W答案速查4 D {1 N% F& ~+ W. ~6 `
1.类% `3 B7 R5 k% {9 x: o# z
2.BCD1 c( E) l9 z) Z
3.C5 {4 b: Q7 P$ z
4.C
. x$ l1 |2 L& N" z& H5.A
* }; q' Z; x& x7 Q" ]& y; Q2 a6.C
( Y( K6 n8 g" s0 L2 w% v7.C( J# D! }; Q$ z
8.C
$ u1 Q' F% e/ Q& B/ }2 R; A9.D
, K& @$ F( C+ t7 R7 J10.B% X- I* }$ m: K8 }' U' r1 |* f! P
11.D
- s1 W* M9 M% J4 }: Y# s) u$ ^12.B, A$ t2 Z- }5 C t3 ]
13.A
8 b8 [: d& S8 n" \/ [# s14.D
: g) Y. s) U! Y8 t% ~$ n. x$ ]1 G15.A
: y- a: z2 R3 W/ x16.B% @5 k' ^' \2 }% E y3 H: Q
17.A
! V- X+ d( P1 t& g+ u6 o18.D
, `' P* R: [ }! ]& w3 @19.设计模式; I6 V! v$ x3 ]' t
20.D" o6 @* M: x7 w3 }5 I# `
- S: E3 k* w ]/ K5 v0 G7 A7 ^) u# ]' m
0 B. o1 J' m j( F( y: O答案详解
. v0 ]- }1 v( ^7 B+ u7 b2 J& V6 U1 C$ o6 T
1.类是对象的蓝图(对象是类的实例)。+ z8 x; d! R# O7 N1 R
( r: P3 Y& L! u2 B6 E( D1 Z2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。 I$ v& n$ }+ E' T* W) ?5 R) Y: p" V
- R/ i5 T# g. f6 F: G
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。+ R2 n2 y% I9 p/ H
O1 a) u2 _ R1 C+ V# }3 h/ b
4.单件模式可以限制一个类被实例化的次数。
: o; W; L: q0 D, \" p9 n- i
. a! j( z9 M: D7 M( O* m: F5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。6 _3 c& R( U, s; }0 J
X$ Z+ l, n2 D: h4 Y+ A
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
* s) q3 b2 ^' x4 h0 Z5 S
5 D/ y# V' ]+ b+ l$ q& \7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
+ U: m5 c, ~" I# e" a8 T5 @$ j# ^2 o7 u- h; s0 M4 ?9 ?
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
# G* E' e5 l8 Y* w& m% B" S
9 c$ I9 f Z7 u' @1 R* b6 b9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
/ e. t k; f% A9 u) T7 Q4 j$ F. A; }# t* `
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。$ ^) s( N, Y, X. |$ p4 v* h
. ?8 [) _6 H( t) r2 |11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。( n# _4 ?+ n3 K4 s
z* U( b, j9 a9 ~
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。) m" _! o/ b3 Q1 u3 i
- {) y6 L; C7 B5 z13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。 X. E7 ~1 G2 |* r ?+ `
& s5 U0 Z: X6 [0 ^# `6 A' v6 \* ?
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: c2 `5 s( F6 v% m8 W5 U2 u
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
1 o7 D) u; g7 O function reduce_fraction(&$fraction)
2 F. L0 O/ ]5 q G. U7 {答案是D。0 L) U5 ^; w. v }/ M5 M4 o0 o- B
; R' w* R% C% X& A6 D
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
* [& ]6 z! Y. A! U+ W7 s
" C' M k# ~/ z# w- R& X8 d! t16.没有。PHP4只允许声明静态函数变量,没有静态类变量。* e7 w; b6 M% t" C# i1 `
* Q! k/ ~" h8 C- P% w17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
S% s, |' K0 k }% h* _. p% c4 {1 c$ S, H: U
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。' t, i- X8 I6 `" R
F, D1 o3 J$ j19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。) w$ r/ y! F# L; B0 f2 j9 X
! k( \$ j" D: M R- n6 d0 Z" R
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|