|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14349
- 金币
- 2460
- 威望
- 1647
- 贡献
- 1408
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
; b3 @& O" Z! y/ |; ]PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
: N9 A; |- g) f本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。# D9 ~- A/ q; [
( O4 b2 r+ a+ K+ f! I( o$ o问题4 }2 R' I0 }; _# D8 c
, n8 J& D' u# m: _/ m1.对象的蓝图是什么?
' A6 |/ w+ U+ ~4 \* w; F# ~: h: h8 N0 G( I' D
答案:____________+ J* V. z3 k, H3 B& Z6 W2 g7 I
. s7 R7 g1 o2 A; Z6 M# M8 t
8 i$ n! s* _$ x9 r9 a& B2.以下代码执行后,数组$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
+ [3 ~) a" ^8 W* u" O" X' mB.b
) y h1 v( }2 x6 X9 g& AC.a
7 j" u3 C1 z# u# HD.d! j( P* X6 C3 b- d# s/ h6 h
E.e: R/ ? W# P' N/ {4 i3 y( l
@# {/ @# e8 e: J$ \ a
5 y4 X' o* s- B; G( r0 ]3.如何让类中的某些方法无法在类的外部被访问?; ?' f$ K9 U& v& s- O
; P I. F/ i* e$ I# e
A.把类声明为private
* J$ s$ K+ F) _" C+ Y& BB.把方法声明为private2 C8 v% k3 n1 N/ D/ `
C.无法实现
# Q% Z& I7 b% J0 V( e, cD.编写合适的重载方法(overloading method)
[2 s& k: k7 {, O; e6 o
; `, h8 ^3 J3 \/ l- F/ h
W7 r; z9 G1 M& `% W4.哪种OOP设计模式能让类在整个脚本里只实例化一次?- W7 e6 v2 _+ e* Y% `9 i$ _
. o# ^: J. \$ ]* Q8 YA.MVC模式' @) N1 f+ u1 V; q$ W
B.抽象工厂模式(Abstract factory)
+ D- I3 T7 m6 L7 F. A/ V4 UC.单件模式(Singleton)
* V5 C9 I5 z$ s/ t. fD.代理模式(Proxy)
, U7 U* C3 o" X6 n& ]0 I3 Z: }E.状态模式(State)) V7 P: m3 `" n, S
$ e8 P6 @+ _4 i8 K p7 g
- d* A/ z, K7 d" w( [% B5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?( W I) N1 Z8 V! k6 G. _+ G
" b" x0 B0 {4 C5 Q, P/ f: S- l( p
A.1个) B8 h8 J5 H6 R0 M [
B.2个0 E9 @4 p4 B0 j3 C3 O( ]$ _
C.取决于系统资源
7 |( k0 i% Y5 n$ V8 G+ yD.3个2 \: K+ c/ a: {; ^6 Z ?( @
E.想要几个有几个
! p- n$ ^. w' X
; m1 s3 d% J9 F/ t. t) m: D3 E
$ @4 o4 h; W- a W& I8 Y6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承: P# x! P8 ^$ [. R8 k* B1 t9 W
B.接口* a1 t4 j% X! j3 ^: _' ?, P/ t
C.抽象方法: U, \' ?9 W1 B9 f: {6 D
D.Private方法
|: n* h' ~& m K/ a/ ME.函数重载(function overloading)
. }( G! a3 d3 Y) f3 ?: g1 I
1 R: K1 ~! \) d- x4 w G8 k J# Z! g
7.假设定义了一个testclass类,它的构造函数的函数名是什么?; a h8 R% E& A: D& B
! E* a# C9 w6 u1 ?1 a0 ]$ Y- ^! r( CA.__construct4 A! W$ q5 o! d! y
B.initialize
9 x# ~0 e& Y! Q2 a; `( b0 gC.testclass
- R, R# {3 E$ F0 _8 l# t) w6 e7 DD.__testclass
+ B* N& k! c2 h5 p" b$ g* uE.只有PHP5才支持构造函数6 P% r y/ e( Y- o& h' o5 a
. B7 B$ n h* d2 V; X( W6 h, X. F2 H% |5 G0 u
8.一个类如何覆盖默认的序列化机制?
+ |# L0 j8 @& q. C. R
' f# L/ d @9 m: H9 r! @A.使用__shutdown和__startup方法7 B: ?( o8 s' c6 n% g) C
B.调用register_shutdown_function()函数
0 s8 F7 ~1 U! h" w% x) @# `C.使用__sleep()和__wakeup()方法
+ P$ v& i0 n. B! WD.无法覆盖默认序列化机制. E ~- g8 |# l3 z0 m
E.使用ob_start()将类放入输出缓冲中
" R( ~# y+ g' c) p7 _2 z: Q* c9 U. d/ e9 V4 A5 x4 k: p5 r; j
1 |# t8 ~4 t* X, U6 i: c. y# v
9.以下哪些面向对象的概念无法在PHP4中实现?. L! a+ i: y' D; I" t2 i
, y% Z$ V b1 B: ~7 U
@抽象类; X' J! S9 D4 s0 c. J! }3 `' k
@Final类* R5 l* Z( @1 I: `9 g0 o
@Public、private、protected(PPP)方法' N* e5 |5 o) D
@接口" @8 P! y: ~/ I. o
F4 H4 u/ G/ t0 @* w( @6 z
A.抽象类9 @' {7 x* O( Z6 N: c% S. D2 J3 Q
B.PPP方法4 D5 z! H. F$ z; ]! q8 D" i
C.PPP方法和接口' s5 p( s6 i1 N& v' g, b. d
D.以上所有都不可用: }% l0 D/ E$ a4 Y9 H
E.以上所有都可用; W. [' z. K; T. x
& m1 _" P3 q8 C' d3 W
4 O& H* S$ I2 t
10.如何在类的内部调用mymethod方法?
" n- w- \( v$ K! D* F
# ]) O2 |( `! xA.$self=>mymethod();1 e9 R1 K0 d! N5 K- Q( ~. T
B.$this->mymethod();
% J, ]3 h- h1 e$ o+ [! ]( O3 \C.$current->mymethod();
7 s7 W x4 ]8 y+ h4 \4 X0 D, OD.$this::mymethod()7 O c3 L8 K: D% B& [3 S! `
E.以上都不对; R) }& W! L: B0 h$ |4 L" a( p
7 l) h9 s8 S5 U g
! U; L0 n( t/ l* F11.以下脚本输出什么?-
- <?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( J: P! s4 b% D- J- b: w# I
B.Null2 z D0 r4 d$ q: Q- {1 o. {
C.Empty
% \( \6 l0 R" M5 q8 N7 n, G9 [D.什么都没有: z7 M/ c" \$ K5 m6 q" \
E.一个错误
( p1 z' S: H* r, y: g8 D9 e, x- L! U0 ]7 }- f* H
7 x7 t5 P7 T7 ]/ B5 d8 l. v12.以下脚本输出什么?-
- <?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
+ v0 c% x+ N( T8 I2 w/ [B.5
2 N5 L" x; Q4 RC.2% G) B+ Q2 M5 G% `$ e6 @& r
D.Null
6 U) \9 U9 `+ d( Y2 j7 F( B/ OE.什么都没有' ]* ` K* G( Z
7 z" c* o; Z1 P e0 T f" A* p4 I: H: q3 m+ X" Z! X
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 s8 X! x1 O+ Y# o" z
B.10
" a; U! V: U% y3 _& @C.什么都没有
7 C1 A7 t- O$ [- a8 [D.构造函数将报错
: ^+ d) R4 O3 a9 F8 x! A$ SE.510
7 N+ C- l% v9 ~* E+ |' c" q5 \
. G% |; N0 }. ?% P5 {* n3 O* l0 g/ A H, g9 B7 d3 U8 Q' Z/ Q
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函数必须返回一个值; y8 M+ b5 v" Y/ r9 R" B
B.reduce_fraction函数必须接受一个整型值
5 I8 Y5 \/ S6 V6 n6 L6 @C.gcd函数有问题
+ k( s, v* n8 wD.必须通过引用的方式传递$eight_tenths对象; f: ?/ g- u2 b, c8 a
E.对象的实例不能传递给方法以外的其他结构。+ B% A, @# ]; l+ {
+ l$ c! ~) {0 R- U' V3 Y0 n
' Z1 v% |% D# q15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法8 J1 Y8 `9 V9 f; U; M$ _1 V+ q; ]
B.生成myclass的实例并调用mymethod方法
' @4 P' x* O: E" K J/ cC.产生一个语法错误- ` _7 r- r' Y2 X. I9 B
D.默认myclass类最后被创建出的实例并调用mymethod()/ b: [/ p0 W/ A* Q
E.调用名为myclass::mymethod()的函数% R9 E: a; [0 K, h. L" A
" p. L0 r5 p% @6 f; q/ I5 G& e3 D% F( N0 N: S. `5 G/ H" i
16.PHP中有静态类变量吗?& L; b" t; A. F0 F, n0 \
* H9 F$ c, ^6 D! i! TA.有* @ _* {! `8 M: b9 i! X
B.没有% p! a' j, G) }5 _$ O
: L4 k4 Q' j$ A- K! J/ K
' o1 g- |! {9 R, ]( k' o
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* c6 i( V, Y4 `8 y+ q. f! v
B.2
3 D3 b7 ?9 y% L# P2 t6 P! MC.一个错误,因为没有定义a::$myvar
. z( v8 ]0 A) x$ J) V# O3 x8 uD.一个警告,因为没有定义a::$myvar% i* T/ _$ y2 o9 n- r Z! R
E.什么都没有
7 L% E4 e& n: q2 ^, \5 H6 o% v- L) O% ^! o
0 H/ g3 [8 b4 B: Z3 l0 y% P+ V: N
18.如何即时加载一个类?! ]* W4 W! A* b7 i6 S
8 ^: z l5 c! _% n, _9 q: d
A.使用__autoload魔术函数
3 L/ h9 ^; p& n" D0 p* a, dB.把它们定义为forward类: C1 Q1 w0 E8 Z+ X7 _
C.实现一个特殊的错误处理手段
. a0 H& Y% R9 @. G: n* mD.不可能8 W9 F+ M- k' ^7 y7 i# ]- n* e
E.用有条件限制的include来包含它们+ F8 Q/ [/ m- F* c% m; _0 E. H
. S4 v6 N# T4 M, i% v. S% z
: a1 O Q( C" u0 v& N% J19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
7 f2 G y1 F8 {* _# t7 m1 _6 A# w+ G* O% j6 B
答案:__________. k8 Q. x/ j9 g; T1 y( `1 y3 P; o8 c
9 k( w, E$ f9 d; O. _ p
3 A; |9 V: S1 ?$ F5 q0 w& b20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called( z4 M* x: `" t# T( p" D* Q2 _; q: P
B.一个错误) ]7 e a$ `; ]; I6 N
C.一个警告
- a: V; l) T1 eD.什么都没有% k, F. U0 O0 Z9 ^8 I. i8 x$ c
* U1 A5 n: k9 t3 F+ D7 j! a- V: @" v% S) e8 i+ }
& X! C; C4 f$ {: R3 N
答案速查1 V) X. g2 x( v( u( Y; h- J
1.类
# m0 ]% E6 C4 D0 `, V# W2 V* b: E2.BCD
5 C% i* g p& {3.C& {& z/ z5 V8 Q
4.C
2 M8 c% E% I# V1 T# g5.A( \. F J- ]0 X3 Q2 `* M
6.C
& @- S- d% a* c( D$ E2 H' S. L. V7.C6 D0 S1 C/ D4 J
8.C4 z. T2 D0 j% r, q1 e. V* {
9.D. t( o) U6 t# L& }
10.B: M. I) z6 @4 [; E6 _
11.D
# p, G/ X# y, w! ~: U( a) O D12.B4 ]7 _( R, [4 ?! @8 R
13.A
5 L$ S! H$ ?, f9 C8 M" E5 k" g14.D1 G4 X j, N9 N& [- ]( S
15.A0 V, M2 C, A; t+ g4 Y6 ~, y. v6 {
16.B) f- T+ Q' P0 M3 Z: T8 [
17.A
$ R: ~8 J, }2 D. p/ {. Q) Z' `18.D
- [+ W: P, O; q- w$ ^% |' @$ d9 _19.设计模式1 Q1 v/ M5 ~7 [3 }( U" [) R
20.D
* r$ G, i$ U& R4 H2 F( w) L
' `0 V0 n, Q1 q. Z3 C' Q- L7 b* Y, Y! J* @2 m- u
' b2 @# \7 X. `8 I# B
答案详解
1 y0 F, v" ^% ]* @# `) d( p! n- A' Z0 R8 }& |; x I; h3 u1 @
1.类是对象的蓝图(对象是类的实例)。( l* j/ ^6 Y6 h6 f) w! a1 y1 h! z
$ ~2 m. h9 y# M, F
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! H( @5 y s3 u
U; q; y ~$ W% m9 W% B
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。& a* t1 s1 r, a* Z
. m- }: t! F1 I) n) A4.单件模式可以限制一个类被实例化的次数。
: f. w2 m s* O7 ?9 H' B& y# p/ X+ _
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。2 B1 P, k* R5 b+ o0 Z: Y8 B
/ y' K2 A2 a3 c6 a: G* }8 V
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
0 _' n5 [5 ?9 |( x* G
0 {* u, u. M+ d7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
' R+ H9 L( G! o: k2 p% {9 N! i% K, m% E5 j1 d
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。& d0 \9 Z# N, m/ ^( G1 _
I: ?% n* |: m8 S \" L) I5 t
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。) o! I, G/ t$ g# `. S* ?
, k6 a z K; L$ N4 s2 q10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。: |! @2 J0 L+ ]( H
9 b; k! ^6 v7 Y8 w' J$ ^( m0 {
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
1 z: W6 M' w- w( K, v. l/ X- x! h( s- f% L$ T
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。* {+ [9 q* D8 Y4 f6 ^9 C
( h& ^! d$ N- H/ x+ y13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
' X$ j9 n* E. S; M7 m1 k: J/ K
, q3 N" g/ x5 \7 c) [' J14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
: H9 z8 H/ h) W1 Y7 n+ x! B回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
6 c' r+ a! _# J+ V( U0 o# { function reduce_fraction(&$fraction)
% u% D9 m+ ?" U! G n3 t& B& x答案是D。
! {" f3 \( Z; A7 y2 p1 T% ^4 h7 r. T( W) m
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
4 r2 \6 ~+ L9 W, @3 [& Q O/ y- y6 f7 G# R
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。) M2 v( v6 v; {9 X% W: m1 h
" r4 [6 B5 `. d: \/ H. _/ G17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
/ _/ F, o# B/ C! t2 Q" k6 V0 `% [9 Y" @$ _7 H9 a
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
( e) [* B* Z' I, W5 V4 G' E; E5 `! M2 q$ `
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。: q' p8 }! G+ W, @0 P$ C t
4 t# D' Y& I3 A) [4 C
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|