标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
[打印本页]
作者:
admin
时间:
2008-4-4 02:24
标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
0 l" Z+ O5 b' V
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
$ o9 n, }5 p* J; K; l
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
0 }: y3 u% J7 j% h; P( A8 O7 U
0 f, v C4 _* V6 {- H
问题
; l/ W, A5 K' u4 L2 n: X; k
3 ~ a* [3 M/ F# @7 M, M$ R- r
1.对象的蓝图是什么?
4 P6 B: e3 x+ e. f7 j
& e( F# L7 n# y7 v8 r: o
答案:____________
- S) I! s: Z9 s* O) E+ g
% @5 N; A/ [1 E6 V
7 i/ d; v% |! q$ K3 u
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
0 c& _ u! H% O' P* l0 T
B.b
) w* X Z% U ?) r& F" Y: `8 F d
C.a
0 m1 x: R2 l; P' F' b' _. F
D.d
6 [& n2 K3 ~( |& _8 ~/ t& H7 g! k Z
E.e
( l/ l5 e7 Z& {+ y
5 D& P! M# P! S1 U' ^ g- `
9 f* E* }) H3 f- Y' B; X
3.如何让类中的某些方法无法在类的外部被访问?
6 Q7 C1 O2 H; B/ M3 g6 ^( F
: Z' r5 J6 y! m8 B
A.把类声明为private
; ]) ]& e9 c% ]; S+ X
B.把方法声明为private
; F- Y n9 |" b, V( @. [% S6 v
C.无法实现
2 Z# ?9 R" ~6 ?, F8 |6 i+ c1 [& F
D.编写合适的重载方法(overloading method)
2 N* A) n/ H- a" h( |9 F+ L5 E
' _ q0 G# {$ m& Y( ~ i
- c" ]$ u0 y9 ?8 {
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
4 J2 t: B+ E8 B4 E2 A% y
( j0 Q- U! l0 H R
A.MVC模式
( ?* Y4 P# ]$ b8 R6 O. \
B.抽象工厂模式(Abstract factory)
4 V; R2 U; [8 g4 t3 H
C.单件模式(Singleton)
, I! Y- D6 o8 X/ W, r! b: I
D.代理模式(Proxy)
/ z& H1 N0 V7 T6 I! V
E.状态模式(State)
" b& H1 B+ I o5 C1 M- w/ N1 Z
" Q* T4 G* r, \ b Y
" A$ J' s- r! M+ M0 V& ]7 B
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
' h5 j7 ]! b; f: E4 ^ y0 G; n
3 h3 X* O" @0 l
A.1个
: i" R8 s: w* G. A% J
B.2个
: t" |8 {6 {/ E! k& r
C.取决于系统资源
. }4 [( t% n) C @7 G( k/ Y* T
D.3个
- e. j/ t( _% Y4 d. Q; y7 @
E.想要几个有几个
. r) ?2 S9 l" N: e: R( R
- q( z! `( f, ?6 `: r; `
+ ]9 N0 L* r7 R Y: w/ n' x
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?
<?php
class my_class
{
function my_funct ($my_param)
{
user_error ("Please define me", E_ERROR);
}
function b()
{
return 10;
}
}
?>
复制代码
A.多重继承
, |3 E. i8 Q5 `4 S9 N
B.接口
+ p' t4 p& h: G7 y+ F
C.抽象方法
. V0 w) S* ]; C2 h
D.Private方法
8 z; f! S) n3 }" q2 S$ U
E.函数重载(function overloading)
1 \! ^! x, {" z' c7 b& D- Q
/ N6 i( n/ n' I0 p; A, T9 F
2 o5 m; z3 w D# b
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
, }' X( v0 o/ Q
h7 X2 E" u6 J6 E
A.__construct
0 D. ^" ~# [: [; v+ \
B.initialize
- i: _7 Z7 P9 Y8 f+ B
C.testclass
' u h9 r! O: A3 ^5 g4 ^7 k5 A1 G
D.__testclass
' [: K- Q) C0 [" X
E.只有PHP5才支持构造函数
2 x. J/ n' v2 |7 l$ w+ Z
0 a. K! J N$ p, W5 d! d
' i$ L t7 q P- j- }
8.一个类如何覆盖默认的序列化机制?
7 Y e# H- S: T' i
: E4 k L) L) \$ K5 s
A.使用__shutdown和__startup方法
+ V5 Z5 N+ g, _: V
B.调用register_shutdown_function()函数
2 E- a" T: g/ F+ `! _
C.使用__sleep()和__wakeup()方法
6 s* `4 `; q5 o- m4 Y, F
D.无法覆盖默认序列化机制
; @( J9 ]* d9 S
E.使用ob_start()将类放入输出缓冲中
6 N: H |; {1 a6 N, j8 j
1 z; e) s1 Y( O) q8 t
2 v( s+ F$ k# X. Y C
9.以下哪些面向对象的概念无法在PHP4中实现?
. H7 N4 }7 C+ m$ p& Y3 }8 I! M
0 [0 F3 H2 G+ h! F, P
@抽象类
1 v, g' N- J) D. [) a( r' ` }8 j" S
@Final类
3 D7 L/ N# c" s4 a" y/ @
@Public、private、protected(PPP)方法
+ E; I) H$ s$ g/ M
@接口
) z0 d! a9 G9 O* r# L
0 s" W1 @/ t2 w' W8 ^
A.抽象类
( S8 V! l) N$ ^: X
B.PPP方法
$ f5 ?. B" K$ z: V
C.PPP方法和接口
2 y% [4 j; ]$ g9 ?0 @4 R
D.以上所有都不可用
$ q) x b$ v. ~8 C0 ^ k2 R& V9 h- U
E.以上所有都可用
/ _& ~6 I- p; b" ?" A2 ?
6 c7 K8 d, F; B' g4 O) k. j
9 L, N% s S: G# u3 Q
10.如何在类的内部调用mymethod方法?
$ A4 Y0 ~% Z- r0 C. n
: T! N& Q5 M! Z7 Y W0 ^
A.$self=>mymethod();
& o4 k% u) f$ l2 H8 z3 Z
B.$this->mymethod();
. @6 K" q2 f) c7 e9 P
C.$current->mymethod();
+ d, |% K* @4 J; N3 n( \) C
D.$this::mymethod()
5 C( e s" a7 ^% A- ~ S, K# M7 N
E.以上都不对
- I, u( Y- [: Q% ^# U" e r
% }6 ?8 J/ ]3 h8 r
0 k0 j: z$ q( g6 V) @( j
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
+ ]% L8 P; J; y) ]$ v
B.Null
; M% p4 Q+ o- @9 B @, P
C.Empty
1 `+ C) @9 w7 k
D.什么都没有
3 ~+ n1 v" A! T% _/ {8 }% s8 m
E.一个错误
; E7 C: k5 B o3 h, G% Z; K+ T
3 K4 J' Z( a I& O) w
! }2 R# S+ M/ I" P' R! F
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
) W8 q: ~: i0 M6 `! N( O+ M
B.5
/ ?$ L' p6 _+ _/ |5 a
C.2
# Z8 f. I3 N' t, d5 M% E$ q; c
D.Null
- }9 t1 K, K! K, r; y: Q
E.什么都没有
" B: a2 y( F/ D4 s: d
( j8 j$ J+ d+ [4 z4 q
/ Q6 o0 e1 r: o" B p7 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
# H% }$ G: `1 K( Q$ T% ?9 s
B.10
7 N: |: D. U& p- h3 J1 W2 ^% U
C.什么都没有
. W. k9 J8 Z) i* G% u2 V0 |: }4 f0 a
D.构造函数将报错
6 e+ g% B r% J: z$ U6 |
E.510
8 g% E, D& H0 q
$ j7 {' E" e' G2 ~) H
/ p9 ^. I" m0 {- u5 ]8 z$ b
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函数必须返回一个值
. G2 Z4 Q9 J" f7 a3 K. D/ w( i% l
B.reduce_fraction函数必须接受一个整型值
" ]; ?2 Y/ I) V z; f
C.gcd函数有问题
3 @, c- \; Q: ?" |* c A5 W, e, J! r, |
D.必须通过引用的方式传递$eight_tenths对象
. B* j( V( ]7 C' o
E.对象的实例不能传递给方法以外的其他结构。
0 I: `, t8 P4 Y
/ C- h5 O3 q' T" e5 c. l
: \! l2 c+ t y: h% H
15.以下代码是做什么的?
<?php
require_once("myclass.php");
myclass::mymethod();
?>
复制代码
A.静态调用mymethod方法
# {, n) I, g+ t/ b
B.生成myclass的实例并调用mymethod方法
( U1 ?" }/ J; t/ @' Z" r- k5 E7 H
C.产生一个语法错误
. |6 f# E" \* W5 i; ^' u
D.默认myclass类最后被创建出的实例并调用mymethod()
0 X" T. b! ?( `0 n8 g
E.调用名为myclass::mymethod()的函数
; P/ D* e M6 |2 L: m- c
1 p' Q; N& R' j. N. D6 }
4 I7 a% {1 q+ |6 z8 r) Q# B* `
16.PHP中有静态类变量吗?
, j9 C8 C8 @0 [" M0 ]
" }( R+ R ?# m5 s
A.有
! e% K+ t4 e8 j
B.没有
2 p% ?8 t9 @# l8 F) t
# I6 |- E) O( o) C& H" @
* I# @" r4 i# e, i
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
4 Q, ]+ f$ n, n; j) z: x+ Y' x
B.2
: ?: P8 L" i/ i9 N
C.一个错误,因为没有定义a::$myvar
& E" W- |8 s2 H! H
D.一个警告,因为没有定义a::$myvar
' ?. l/ S& ~' F w6 r
E.什么都没有
% _' _4 K( g& j1 A A
+ q" T/ {! z- ]1 K3 r+ s+ p
/ N, X) @( [/ U, i5 N* k
18.如何即时加载一个类?
7 q1 P% [8 V( u: w( c3 j) d7 }
- T9 k* Q: a4 t
A.使用__autoload魔术函数
: @. J7 |. X- m% R, @* R3 w0 P# q
B.把它们定义为forward类
n% ]9 u& D. ?( f8 L1 D; `
C.实现一个特殊的错误处理手段
+ D4 V( W! a) a) }# A3 B
D.不可能
( L5 s- A6 d1 k& i# Y9 s
E.用有条件限制的include来包含它们
( l# @' J$ T4 M8 S
) H [; V: H3 F7 q
1 f- W9 B( }" [
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
- Y5 s8 k- j% o" v! x
) i8 ~* l; q% E) M# F3 u% y+ f
答案:__________
- Q1 ?5 B0 [. w. h S8 W
( k) b2 _3 f8 B: t) i2 T
* \. Y/ l! V* C4 x: A, T3 j
20.以下脚本输出什么?
<?php
class a
{
function a()
{
echo 'Parent called';
}
}
class b
{
function b()
{
}
}
$c = new b();
?>
复制代码
A.Parent called
' I0 O" ?+ v5 P# V
B.一个错误
' s0 w5 I0 w" u/ P# }" o, {' Z
C.一个警告
8 J. s: Y2 f$ _
D.什么都没有
7 G) ?* [! p7 G9 U5 S
7 o0 p- |! U) g$ R# y3 Z" h1 _- [
# u# f) ]- H* E6 _
9 j: Y8 ^( V. g/ [# }
答案速查
$ P8 I1 X% [4 M4 U
1.类
7 X. M9 T) W, \# c3 ]( ?
2.BCD
$ O/ g6 `% M( c2 a9 ]6 ^
3.C
/ R( T3 J1 S- n7 c9 a
4.C
# w& ]( X" A2 G0 D# \
5.A
5 X8 Z/ x' c% {/ U0 Y' @
6.C
: J- S7 T) T. H. s
7.C
6 e8 P3 s4 Q% P8 i" N6 C- x
8.C
" R# h% H7 @) X+ J% K2 z- A
9.D
9 H6 W" }$ @" ^4 W# T' F
10.B
- E! y9 C' x8 s; o
11.D
) o9 s+ A8 _# d1 Y
12.B
5 }+ Q f4 P3 q5 N, M* n
13.A
6 n" n- w, l8 z* n: x
14.D
; C. f. d6 ?. c% P. F
15.A
6 g5 `. A. P4 [8 f2 `1 u! M
16.B
" B. n8 \/ n1 I0 d6 ?0 T
17.A
9 S$ N" ?! z0 j# w( k. e
18.D
1 Q0 J) g* q1 `5 b$ c0 l7 i
19.设计模式
* n5 |/ E# }3 v' q, l
20.D
9 K, A, \! c0 D# g7 S
8 z* M1 T& e+ \7 P
0 n, z8 S6 X, X9 ~) A# ` u
; t4 d5 i0 i7 R1 j4 Q
答案详解
( G- f& N, f5 M' m
7 i! o# B; ] @* P0 u# J
1.类是对象的蓝图(对象是类的实例)。
3 c; T$ E4 a& D1 G7 @# o2 P
$ y8 g: \( q @) Y; k
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
6 E5 I3 L4 K" I$ ^
; L% n, @ ^3 A) G! A# H
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
9 O$ S4 e1 d) f$ W- q2 C
1 X. C, |& [- p* p8 A
4.单件模式可以限制一个类被实例化的次数。
$ c$ E$ s! {, W
$ q% z; z; l: f2 a0 p; o' J! N6 H! F
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
$ @& _0 U+ _% C" N3 _0 t# u7 v
: J& i0 o, P& o- g; V4 Q# c
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& ]* _% k8 _7 z: y4 P- c& n5 ^8 x
' u" c* r# b$ c. T
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
# r; V0 P3 q5 u3 H3 v! q* n
& U3 R( j+ J7 w3 H1 {6 {
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
% Q7 J5 {, t* R8 ~9 j ]
0 V- S" Q. e ^# X
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
3 r; {6 K) V" [
6 l- @8 x! D! r5 n" j+ O4 V& c! A: D
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
0 O# E: y" x* {, j, G
4 Z0 M) Y* _" g
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
* _5 v* N I+ S! u1 \
: w3 V! c7 ?5 C0 ^2 M
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
8 B6 l5 T; P' x
, K9 u2 [) [$ n9 T) `
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
/ z0 |$ r6 M+ {# t5 g4 A
. _$ N1 i! N0 {) s) W, k* N
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
) F; g, @* d: V( G" f1 [; z
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
5 T8 n5 u7 a( j8 ~
function reduce_fraction(&$fraction)
1 d) R9 I9 z! i& S! Z
答案是D。
! S9 M4 |9 R5 d) D
$ q, Z5 c+ d# ^; q" g
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
: t5 D! w. S3 d7 s2 c5 h# e
4 n5 @( s+ A0 \
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
6 n) E# S. Y: j0 q
/ i4 L& h9 k/ C9 E: A" g% C' O
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
4 h; H& {1 s U
) l) H% z2 P' S' B; z
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 c! n6 w! Z2 t
9 z# F- Y6 G; l& o0 h$ Q3 W
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
5 d2 u0 q( L7 ?- V( J* Q
- ]" ~9 V7 \6 z: k
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2