|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。2 i5 ~" f4 u( P0 c% B# e
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。+ f+ e* g% W5 N$ j5 a# S
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
4 s1 w" q y& y6 p& N4 }1 `: p }& |0 [7 X7 D: G
问题( V3 ^! s7 r0 ?! N9 l
( c" m$ f2 V: w6 u. x+ h
1.对象的蓝图是什么?
* q- x; h$ K8 [6 T# C( Q) z/ P
1 }/ t5 Z/ k( Q5 S, c" D% i答案:____________
0 P2 U- y) l' T0 ]' i- D# O2 f7 |. J* _5 s8 ~4 D
& w) f* L; S( p+ P5 p# C
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
9 w3 h' `5 J/ ^B.b6 Q. Y2 w q m* E- P* ^1 F. P* w
C.a
# E( Z! b( N, Q2 Y: ^6 R" SD.d# d: ~0 a: I- O5 v$ r6 c
E.e
- r, H' }7 S0 [7 `* {
7 A8 C1 {, @4 q' D3 f! ~" i. p' c9 E3 \) {! y
3.如何让类中的某些方法无法在类的外部被访问?, _4 N3 e! C. ?0 S! y6 e1 Q
5 N& P2 A4 l4 ]A.把类声明为private
) Q' P/ X; u. q Q8 x( _, Q' @B.把方法声明为private
! J# m( j* r& a6 Z9 D# GC.无法实现/ y* x( `. D( |8 b' E
D.编写合适的重载方法(overloading method)# k7 e+ ?' y, u3 c' g
; y! X# J% P5 U0 U# P$ |: f- |+ |+ ?( d1 p2 a: h" l7 J) }
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?( X7 ~& w9 A0 u$ y6 _- ]# W( }9 s# x
. ]# Q, e$ K6 w! S4 l3 e& R
A.MVC模式
& m) I H* s fB.抽象工厂模式(Abstract factory)2 T- Y7 N. S# P) E, ]
C.单件模式(Singleton) z' |' ^4 ]" L. p. O% r4 U
D.代理模式(Proxy); u( \6 f4 H8 @4 }( O2 A5 `8 F( }" h
E.状态模式(State)
: Q5 E0 T5 o' i5 i% r% Q0 F {$ F" \7 u
# z3 Z: o9 `3 ^; a
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?! I" O) O s+ y. V, K- C3 m& A
7 O! x* b: i3 Y! k. _
A.1个
/ t X/ M7 w4 {2 V4 \+ sB.2个
( w. U( s: c p; GC.取决于系统资源
5 a( s5 G( E3 y L( z6 s$ Z3 dD.3个' N# t% w& F! f
E.想要几个有几个4 W- y _$ `* P8 [6 [2 g5 b
5 ]9 s% M0 s# g% z1 W+ A/ ~% V" S" \9 _8 U
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
0 v) d3 _! Z0 Z( X4 b. ~B.接口8 X Q. E$ ? m: I* Q
C.抽象方法% \0 M! u8 `9 b: E, N% O
D.Private方法. s" D, f6 U6 j" u) N
E.函数重载(function overloading)
5 t( G& M( b9 D/ {/ t2 c& q& p( c f8 r6 Y: B1 v
2 H5 U K$ | {- }% T8 x
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
% C6 z4 \# r7 P1 z
# d0 }6 [8 q# W" M9 RA.__construct% \4 ?1 r% Z6 ~# t0 q* D
B.initialize$ ?3 D1 {& B* j2 E
C.testclass9 ?' C/ P o# C+ |6 i- a2 g
D.__testclass8 K4 v1 |& I. ?# `/ \
E.只有PHP5才支持构造函数) L9 k7 |: s* ~# n- w9 U4 s
- d/ y5 A- c) n; o+ u. r
3 L4 k0 I; e$ b5 o8 V; D' c8 f' s8.一个类如何覆盖默认的序列化机制?
% W! Z5 p7 q. H/ P U% j/ S) Y' e4 g
$ |) V9 n+ z3 _% Z" s2 P3 nA.使用__shutdown和__startup方法- h* H8 u- W! e$ v! D
B.调用register_shutdown_function()函数
: X! s! F/ F0 U2 p% ]2 QC.使用__sleep()和__wakeup()方法4 u- ]' d0 {' t0 s1 @" J- q
D.无法覆盖默认序列化机制, v: g& T, P: ^9 K+ ]* ~0 |
E.使用ob_start()将类放入输出缓冲中 ]* \( I7 w6 W# n
# ~" _. u3 |# p3 W2 k7 D2 T5 ` N
+ ~* d) V0 x0 |) w2 ~9.以下哪些面向对象的概念无法在PHP4中实现?
' p& Q; C( V! d" ?# z* O }( v7 \2 G1 _
@抽象类" U0 r: N4 ?* e* u" K# [* D9 ]
@Final类
9 L7 x. s4 T5 ?@Public、private、protected(PPP)方法# b0 \7 a# V. v# Z& N" K
@接口
! B4 D4 {: Y* n" f6 W7 B& f5 _/ U) z. p/ A1 r. W
A.抽象类; X) U% c( G8 F
B.PPP方法0 q9 h/ t, C8 {2 m/ l9 z: I) q
C.PPP方法和接口5 |) ]. ]* |+ o* ^
D.以上所有都不可用
8 i* ~4 h+ u' t& Q- _E.以上所有都可用. ^" \3 R9 H x1 j& h. M1 b
. K$ ^* |- y( ^7 P- a
; T! t' B) j! l/ `' ^7 W. I10.如何在类的内部调用mymethod方法?+ D( p- _4 D; C9 @! b, B
$ t; X! _- e) B7 a; P0 eA.$self=>mymethod();
- ?! x: S- I+ e0 g, m& {1 jB.$this->mymethod();
9 u, N/ _* `; p& m% W& ~" jC.$current->mymethod();1 b+ ?' u) |) b: G- K; k
D.$this::mymethod()
- H! x" _* Y- a* b2 K, bE.以上都不对
n6 `4 P( n7 v' s% q8 M, m1 v
$ i, }( T7 J8 W8 k$ `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( y4 m/ G8 ^; g2 }3 Q# l
B.Null+ A0 l: R" T* S5 K
C.Empty
8 x* D) h8 h, j7 UD.什么都没有 @' X9 X B! C, B% M+ H, R& e
E.一个错误& G) ?! i' ~: F* l3 ?; j
' R3 L% m) I0 x# O
* t" n* C5 P& Z1 X3 j12.以下脚本输出什么?-
- <?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.101 S1 }! v& w, w. L4 n' A' F& Y
B.55 p! \) @- d) `( v7 u3 l% s. e
C.2, w* h$ W5 g0 ^+ _$ q% U& H
D.Null
/ e! X8 L1 K* N* iE.什么都没有
# ^' {( e# U% d( \7 t* E% Y4 G; }( G; u2 B( V% x( M) S9 R- o
& J& G+ P" ]1 v, k2 `( a4 e. D
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
% A7 y0 Z+ O7 X+ m/ x* WB.10
) t, g1 c2 t5 O! D# UC.什么都没有
% {* f7 @5 I7 Y, B% V) y. N" VD.构造函数将报错4 V* |7 C& q7 Y" _; Y# E
E.510
6 e: v1 a. F. N" |& @
- B' y2 S' {! q5 r$ U8 V3 B/ E# a# T# k, w0 `
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函数必须返回一个值
" i, \2 Y/ B0 y2 Y6 X- ]B.reduce_fraction函数必须接受一个整型值
( S$ ^ D5 W8 x! o: kC.gcd函数有问题
0 }0 v( Z' ?- c9 w9 `' g1 n+ w8 k% SD.必须通过引用的方式传递$eight_tenths对象( S- d) m& \: ^2 \
E.对象的实例不能传递给方法以外的其他结构。$ r5 v# V# `6 L. D1 G
. K+ Z7 y- ^9 K3 z- m$ j0 w7 f5 H6 A. ]1 X) \; v0 ^( k4 T
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法" n. s4 I( B; n. n
B.生成myclass的实例并调用mymethod方法' v3 A* l" Z: q5 _
C.产生一个语法错误4 }( z" q; g2 S" \/ M5 V4 S; c9 m
D.默认myclass类最后被创建出的实例并调用mymethod()6 M; e( {* y' g
E.调用名为myclass::mymethod()的函数' k' o; ^% t+ M# O0 w; G
6 H3 j" w2 p& a; h2 ?" D
5 }" c9 I0 u1 z% D+ X# c16.PHP中有静态类变量吗?+ i, j, W5 ~; f+ p
' L u9 _* b! A5 Y* Y/ m9 Z
A.有
) T1 z+ y6 i. I* _/ M. _B.没有
2 K5 l, o) N3 Q/ g' y' |1 k1 J4 O2 @$ a% }( l! `' _
- G4 u8 v* g$ _& D) g
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.12 v2 |7 J1 A% b- q% n$ U( f
B.2
6 w9 |, Q ~; n6 }/ FC.一个错误,因为没有定义a::$myvar/ ^( S0 {+ j7 o$ f% y' s3 x& M
D.一个警告,因为没有定义a::$myvar5 {/ T0 r U& D$ j1 m
E.什么都没有
2 I; s3 [) b. D z9 ]) x3 [% }' P( H5 n
- H' m3 [8 A# v: r1 n18.如何即时加载一个类?
( [" X9 K1 ?- }! V6 u# R( x% y; Y) c
" E! r- `2 D1 j" u1 Y; r1 KA.使用__autoload魔术函数
/ D7 E! [# i' w+ p5 IB.把它们定义为forward类( [: v( K8 S: K, F
C.实现一个特殊的错误处理手段/ R- z+ L) z3 Z2 I+ L# f. b3 i
D.不可能
: [2 B, @0 T L: p) t% }" eE.用有条件限制的include来包含它们5 {# j9 g, q# p- _7 o( ^! C+ U
8 x6 r+ x# Y/ Q% L9 m" w
/ Y) I! s$ q; @3 C% k3 y
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
! ` \* ?* c1 f( G
( h" C9 v+ `1 Q: }% e 答案:__________; V# l1 q0 _# w: \! C2 ^5 B0 b; N
( U8 f% [: v) C
! Q6 P' N1 l/ o4 ^# R20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
. K" J' I4 i9 X- O; sB.一个错误
$ V2 {" Q: j, A N/ j' }& e. i, HC.一个警告
# V# w& u/ T. n# i% eD.什么都没有
( p: `$ h. @& }% {. x' ?! h6 ^2 E3 `' p) l( T9 _
# [- g4 J m9 j% z Q
: t6 s, n. o) a# f2 C& g( e答案速查$ \- E' m/ S: U0 ^5 I, O( c
1.类9 q1 F- w3 W4 o+ |
2.BCD1 o( z, |4 ^( g1 E e
3.C) x9 X4 L& g9 x6 m. g( I }
4.C9 B/ ^2 c {6 q1 @6 h
5.A+ a* ]1 b3 X4 N2 ?
6.C
( [3 F, n" ^6 J, P/ N. p7.C
/ N' y- p5 L; j. L/ x, F& Z8.C$ n T! _" F: W+ g
9.D
2 x7 y# [8 i/ n( ?1 t- {' H10.B
* T; }' O$ X; @% p7 i8 w+ C- y11.D6 ]6 h% i5 ~+ {# r" a4 k/ W. H
12.B: f. h2 E! `3 `/ _
13.A: F. W% \+ j Q" [8 K
14.D! s& Y$ A( x) l; C2 Q% ]/ h! b9 c% p
15.A" ^/ q6 p# H/ g8 _$ v E6 q9 _
16.B! K: D' V! d+ t5 M; x: _
17.A+ v- _3 R& @/ T; x( P% B3 Z
18.D
8 h# z% J" `3 O! a19.设计模式
% W* {$ K# l- B2 y$ g1 {20.D
3 W- G6 x: i% T' b5 D( I7 R' w' o! i8 r5 `. A5 ?
! \" V4 g9 G: r! c+ @ @
6 l( u- \ R8 L* i答案详解- t0 w% g2 |$ c) _. L/ x
9 T9 I+ q: r0 W
1.类是对象的蓝图(对象是类的实例)。$ k6 e* X3 z; }3 n8 }8 j/ y& B& |1 |
/ M1 J) Y$ `3 i' [$ F2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。. J3 S7 a0 @1 }1 t7 y5 J, |
`8 g# P1 b% {8 g) @3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。 X* d2 ?( X i; D7 m; ?
4 B4 u- ?: B# @# a- D4.单件模式可以限制一个类被实例化的次数。
" x4 V3 N7 H ^1 u( U2 x# C- n, ~4 y8 p6 X2 p
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。5 e( t7 v' Z" Q; M9 m
8 S f5 r! ^ {* l. I! E: S6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
; j# R$ l% i' a9 W+ z) P$ n: s$ V1 a3 l2 I6 t/ C3 \/ }
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
! ~# }5 h1 ` g+ A; T2 u+ v
/ Z5 N- ?( Q7 g; [8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
* n! w- N3 p& V6 t# v/ H# q" @0 O
3 K t' T) g$ C% }1 o" X- o9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
. K2 l* Z S) Z! O- L9 D9 ^2 c8 R: D* Y( e5 F/ _. w! j5 M
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
6 S A" v9 b6 I
v+ C1 H0 }1 X7 H11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
- X6 X. ~- Z3 ?! l& u2 F' L i I" h: D% g3 X$ a' k
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
& p0 x7 P3 w1 f" ?/ [3 t
9 m I0 r% i! b4 Z13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。( K+ E2 O3 H. E% q {
0 k- B1 T: @) R. i14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
+ f$ n9 ^) L- Q! R0 B) O1 U回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:* a9 m5 _$ Z1 J8 x& f" S
function reduce_fraction(&$fraction)
; e6 X% ]/ d0 |" L1 e- j答案是D。2 M1 z! D! D# p7 Z& x" M
0 k0 ~* F& H, D# g0 S3 m/ }! i15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
5 @, T s. k, k; R0 R% p: x4 t) b2 g& G; t9 _7 t/ h
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。% V# E3 v4 g/ M! g) u$ d- {+ X, z+ h3 v
8 r4 L" w) R5 S% i17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。5 P) L3 s+ j8 O+ p' B
& d) L h) a, }2 D3 W18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。4 Z; K3 y4 ] W1 O
+ j" ^8 c1 Y0 b
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。' M9 F3 Y; G( i n
6 p) I) L+ {! c6 x( H6 }1 a8 c
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|