  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
$ F5 D+ q8 @/ s% G; K% ^PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。- P) s3 t6 |2 V% K/ e$ I
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。+ V5 e& o! O8 M: g/ L, Q
. K( U; c/ c3 T1 w1 a' ?4 v
问题
! f8 M" q% d+ K; @8 y4 Z+ o* R2 E! H
1.对象的蓝图是什么?
& N' s# f: |1 Q* y4 u1 }4 L1 u+ v. w" o. D
答案:____________
/ G" Y$ l& }, s! e- D
& L/ |1 {, h8 ^, Z' m: \% t. I3 |) c+ v- g
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; b8 o# v) _5 |$ D5 @( h1 a
B.b
5 a' s1 z) c: [3 \ T1 J" rC.a
5 y: x- n8 s' b6 AD.d
+ o9 P s6 U, n N U1 eE.e
4 e: X* \+ m5 q* T; {' f) ^# |4 [; g
e) u* C {' y v$ {6 G! Y4 \3.如何让类中的某些方法无法在类的外部被访问?
4 W X- ^- ]6 _& }! W
' ?0 V3 r: B I* _* N; ~A.把类声明为private
/ O( }" V1 E# B+ Z: fB.把方法声明为private( h" d% l p1 X0 U% }
C.无法实现( g! @0 c% ~( t1 t- G o" |
D.编写合适的重载方法(overloading method)
0 s* ~) A' d% T2 p8 x: a
9 G; R1 ?. c' ~, k. U3 U
; y1 d/ y3 s5 i5 o( V' {4.哪种OOP设计模式能让类在整个脚本里只实例化一次?: V/ \6 C' x8 P; Z) X! k
9 d# c. f/ { a! g. N3 I% x
A.MVC模式" H! X9 [9 |" k! b
B.抽象工厂模式(Abstract factory)' G" a! \; p& [* `- V* D% J
C.单件模式(Singleton)
9 X1 y3 g* X5 Z5 M0 w; a% W4 qD.代理模式(Proxy)0 g( H9 U) d ?7 o8 X
E.状态模式(State)/ n. u- P7 b* O. b- D% }! K
- }+ z( y& m: ~
9 | X" h2 U" f' X/ j5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?, [0 z- X/ A+ n
{+ w } V% w G, X6 T8 K3 O) I: h
A.1个
: d( `8 _% y! v0 FB.2个
) I8 `3 _) t; Z* q' [; b4 QC.取决于系统资源
+ Q- f' c. o% w/ _8 B8 H% aD.3个
, s* K6 u9 H8 T1 [# L rE.想要几个有几个9 J% {! m1 Z/ {! Y, c
+ }( J l1 i7 T0 [. b# I% S
( l6 y9 x$ \5 n2 X- M6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承; I3 K1 `- r8 P! x( }' \2 L
B.接口
. Z! r. U! ~9 P) }C.抽象方法
' ~7 J9 k k) pD.Private方法
1 a3 ?4 x- z) k% uE.函数重载(function overloading)
/ X1 \; D9 l. p
5 q% ?# t& `3 ] B4 n
% }- H& P, d; Y2 {; O# `& V7.假设定义了一个testclass类,它的构造函数的函数名是什么?* d# ?: g3 V3 e
a1 Y5 f+ W/ s+ ?A.__construct5 ~& _! o# { T8 d
B.initialize
6 V% W( n3 o4 k) `8 ^% aC.testclass! \& j; w, A, F! Q) C8 }* H
D.__testclass' Y' A" B' D { W2 i1 ~
E.只有PHP5才支持构造函数
; h) D* y/ i7 g4 [2 B1 M1 t3 l7 U4 S, i! a3 O
7 t" O: G7 C. _- T" a+ q8.一个类如何覆盖默认的序列化机制?
: `# Z- _5 v( R# U0 O3 q" B. L6 `) a" B1 Z0 F
A.使用__shutdown和__startup方法
' B# U+ i" K$ u3 A* RB.调用register_shutdown_function()函数8 A2 `& v6 q# F0 ~
C.使用__sleep()和__wakeup()方法
: i2 ~0 M6 `" m( s; }7 L4 s- }D.无法覆盖默认序列化机制
4 x) B3 i3 h8 R8 qE.使用ob_start()将类放入输出缓冲中
( ~6 B( N) p, }% \) Q' f% T
+ T# d" G3 b: S- P' y! d" [/ y ]; }. [2 K
9.以下哪些面向对象的概念无法在PHP4中实现?; n; ]. t- K3 J f2 C- z
+ y" S0 S1 X1 F- B. X
@抽象类2 I% |' e) ?4 O( M) f b2 E$ H7 h
@Final类1 A/ ]: |7 U' L
@Public、private、protected(PPP)方法
% @) h# ]5 b$ a2 Y@接口
9 z( Q$ ^' ~ G( ^2 Q7 b& y# Q, N8 _* \' @' A
A.抽象类
) [$ b- c# S% j8 B( e. {B.PPP方法+ T0 h3 _; Z0 S# k# _& T
C.PPP方法和接口
0 O5 I1 `' I* l* _0 m' kD.以上所有都不可用% a0 D) y6 b) y: q; g* e
E.以上所有都可用 \) K, j$ ~ j
9 [# d7 R* P. S! e3 j
/ n. F& H. a) V2 ~: m9 E10.如何在类的内部调用mymethod方法?9 @# N$ p3 J& l& z6 y
1 }7 O1 n* w1 n+ k4 l# b* l/ ^
A.$self=>mymethod();
# \" Q( f1 R" XB.$this->mymethod();+ ]% e# t; [7 r: Q
C.$current->mymethod();
K2 ?/ w0 H* S: T: N; [" mD.$this::mymethod()* }( E! I% a4 W, b) m5 w& L8 J
E.以上都不对% a4 o* h7 P5 W" `" q0 ~6 [
4 l, l! \- B9 {- f) o3 k7 _
) L" k* f1 k: z0 N- Q11.以下脚本输出什么?-
- <?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.104 m. k2 I% R' a" r
B.Null
8 E( @% [+ t3 j7 w5 v8 M9 a qC.Empty+ W# r4 q5 O* B0 p( h' V
D.什么都没有( K3 P$ b& T% z# h- K# y0 G
E.一个错误0 r& S* b7 `8 Q# W+ A
3 L1 @ N9 y5 a0 a8 e
2 j0 x+ ]( T6 b c4 D$ f" c
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
+ u; v% I6 f4 S. q, Y( k6 R9 IB.5& q& d$ u V7 C4 K1 I& ~$ n
C.2
! {1 z, G8 M$ f$ A5 B3 c( [: bD.Null6 p7 ~0 A! C/ }" K
E.什么都没有
; ^6 T% X6 P/ t, W/ ]' z |6 h3 |- q. F3 z$ b
* Y2 l# P0 v% y/ r6 e) e" G13.以下脚本输出什么?-
- <?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
+ X" H1 k# B! _+ wB.109 N5 R3 F0 D, H" U! q. g
C.什么都没有
5 U" r/ P2 I& |' `; @D.构造函数将报错/ O. b6 _& A1 D
E.510
( q8 J( f+ Z( s5 r5 ^) h: T4 W5 k* x2 Z9 A- j0 {
, d8 p) H8 `; z* j0 P" u14.考虑如下一段代码,执行时,$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函数必须返回一个值
+ B' ?) V+ Y/ f. b/ B eB.reduce_fraction函数必须接受一个整型值9 ]) v& J& X& ^. d
C.gcd函数有问题
" v% V6 {! ^2 J( i0 e sD.必须通过引用的方式传递$eight_tenths对象" L2 F* a3 m: s+ i
E.对象的实例不能传递给方法以外的其他结构。
( N5 {1 r& K' q2 \9 z [8 z. O! T9 ?/ H" u6 }) x5 i
e- t# ~9 ^+ S
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
$ _/ y8 V1 J$ _" R9 K( C% FB.生成myclass的实例并调用mymethod方法" p. E& u1 ^7 ?
C.产生一个语法错误
& N7 q$ |, ^0 w8 ?3 X7 eD.默认myclass类最后被创建出的实例并调用mymethod()
& D6 f, C {( ^1 F/ AE.调用名为myclass::mymethod()的函数
9 Z; |% g4 h# g) s' K5 @7 w* |
* i# u6 b6 M6 }* H- W& ^; @: {1 g
z; t& M9 L. ~3 p4 ?$ B2 J* _16.PHP中有静态类变量吗?
; |. g& }, R1 F/ R i; P4 u6 W9 @ `3 Y" W9 X. f
A.有5 Q0 Y! E; X; R; D$ j1 M3 ]7 p
B.没有* L1 ]/ \; c0 H9 d
4 E( |( F) ^7 b, v- `& Q0 t! z% ^+ f% L& a! T' Q: y1 z8 y' ^* J
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( b% f6 ?( fB.2
& d' F3 N! s- ]) f+ QC.一个错误,因为没有定义a::$myvar
; y# {3 p0 A" ~! W3 ]: nD.一个警告,因为没有定义a::$myvar
8 I8 j! z# w7 N. z* ~; tE.什么都没有1 q" M# g( x6 n' ^( F5 D
# v/ `& ?$ k' D) F# @4 t
8 n1 R3 q1 @" }* b& N2 B, \. i6 ~
18.如何即时加载一个类?
5 c# d! B3 o- F* y9 o' a, `! A6 a* E: @& ?! M
A.使用__autoload魔术函数# i" ^' P# @; r* ^0 N
B.把它们定义为forward类; {- B1 F( e s$ X$ p+ ^) g
C.实现一个特殊的错误处理手段* N! o- G6 t2 b- R: z
D.不可能- I& z1 E5 A9 o: ?# ~$ H5 {
E.用有条件限制的include来包含它们: |* F& O5 e. O) P& w% y
8 {+ [' k& ^" M9 I/ A- v) z0 P- _ m7 N7 B
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?' P( B2 M6 N/ H$ c- t# x
! l6 g% J1 Y5 n2 t6 B, X, S/ R3 f
答案:__________
2 h& Y8 @/ Q; a) d( ? ~) I8 o0 ^( p( ~9 E6 ~
7 ^! x, K0 t! ^+ E+ k% w8 |20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
% f- t! r; P' ^5 QB.一个错误
" M+ ?/ f% v: P( `; B( k( E# lC.一个警告
2 e9 T0 j+ @ }! qD.什么都没有) ]; f! S: }. p
1 U! ~6 U$ v8 o5 C8 X6 f
3 U& G I- K; q) L: p( [# b) d1 I3 m' k4 t
答案速查* C; C3 g; Q1 h& F
1.类
+ h% d/ i/ l1 B7 ?& U2.BCD- n' d# V8 L6 S9 c' O. i( V$ E
3.C
+ y2 A/ Y Z# H$ \7 g3 u4.C8 {+ j1 U3 {0 M) }. z/ }6 m" z9 |6 ?4 d
5.A
7 \: z6 n6 W7 J \* Y* n- M& d6.C
' T' g" x3 R* |2 @2 n$ i- y7.C
0 o9 @) K( P0 R7 E. z- c5 t! r" R8.C" Z9 ^" k1 I4 L5 o) h
9.D
" I8 l, @$ W2 K: s10.B' r/ [9 H7 X K! b4 `
11.D* A4 W' k$ A7 D8 h
12.B
: N: b, k; P; [; {0 |+ v1 _13.A9 d& s; N8 A5 x: K9 T9 f2 B* y
14.D9 W. h3 W& Z4 U n7 z
15.A
4 X: w* T* s" J i; A4 E16.B
2 X1 q* W Y7 H, b17.A
" O% J# L) o9 @) T! T18.D8 E4 o2 @; f8 J5 O& E( w
19.设计模式
; W5 ~0 U2 B) ~8 Y# C20.D
; s: X/ j, B/ v+ C! `' a/ y/ w& O3 @( O
9 n& |( f8 d8 Z; y J$ p. T: S5 Q, W$ n, e( i9 G& X: [
答案详解" L- D; d# p- B3 q' b4 u, I0 ?
" _3 @& S- Q6 F5 m }; S
1.类是对象的蓝图(对象是类的实例)。0 V) O' O9 m3 a6 [% r. W
5 ~/ @' v0 h0 M% B2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
5 c, b1 E! S' @$ x* L, A9 j
Q) W6 I9 n, I1 w9 _- c3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
, Q! @' N: x/ Z Y9 e/ V1 s- r; p
( N6 k% D! @: n2 ^0 S4.单件模式可以限制一个类被实例化的次数。$ D7 b7 m1 _# v4 t$ m( z
U5 Y+ ?2 F8 f: I+ k5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
0 _/ @* E6 F+ a& G! N4 m
5 E/ G# M: B+ }: E" Z6 A q3 j0 B6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。$ ~0 X: @8 P1 X% l$ N6 |- r8 J
$ S% C- g( n2 x R) F7 S5 A7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。 A7 ?2 w+ T4 G
/ J, ~$ w+ \) e
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
/ Y. S+ I$ ]- w8 [2 G# Y* N) B9 \/ _% B
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
& D- p; k7 d5 z+ `$ N/ P) w! W% c6 A) E7 t. p7 `
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。5 R6 v" Z+ H" J/ }+ }4 _' F
; @ S$ [% N; v' I) Q- R" B11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
5 w. T- E% M; J9 f5 N0 t4 [. b' Q
8 U3 d7 u! f2 B0 \. n/ R* O12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
. w; \( [5 P4 S
& w- b5 L Y1 F13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
6 l- x0 U s0 J. h4 ]- @/ |: Y& K8 H' L: F
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。1 |( U' L- T" `( E5 ~. k- Q
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
: `4 P7 g( k9 c6 V) h function reduce_fraction(&$fraction)* {" O* h! f. L" F" @- O5 S/ n
答案是D。, s5 z4 U+ F, c. H/ j
% G; m7 i6 V/ w5 a" H1 N8 V15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ u: g8 F& M, {, @ P( M
" v+ @9 B! p1 P: ]4 o. J' u& ?( P
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。4 r. Z$ V, n# N' Q0 ]
& h) J2 |' m- L3 p7 x0 ]
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
0 m2 z" e7 z- p2 F/ R; Y- B7 Z
/ Y& K) S+ y7 a+ ?18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。9 U- u/ Q C+ I# k, M- [7 o) K
$ [* P5 Z k" U% q2 K
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
2 {% k4 J; b/ B% t+ S R7 t+ X, `
: v+ M6 ]0 l6 [' @4 r20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|