标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
[打印本页]
作者:
admin
时间:
2008-4-4 02:24
标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
! s* X/ F5 Z/ V' G( o
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
. C6 j5 h2 h: \: ]* x) b& e B
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
5 ?5 S. O9 |% D$ t Z1 Z0 C
5 r Z! ]: S- S* J8 s7 z. H
问题
% O, [ g* h* p5 J+ l4 `( }1 i' r
8 H; x2 h/ U9 z
1.对象的蓝图是什么?
% _2 @: X5 I A4 v5 |- E
- v% Z) j5 r+ O; y+ z' N
答案:____________
5 Q, d/ ?) ?4 W* s7 t* K
) }2 ]6 K5 K P; F$ }
5 R& |+ n( a$ n' j2 ?' x
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
. c$ h* H* K% r: T0 f
B.b
q& {, m) F( p
C.a
! z' D" y1 J* l4 r
D.d
# Q8 c P8 s/ N( ?( ^
E.e
8 x* V7 t* q( Y, V+ i7 ^$ S
7 c6 t- ]1 j/ I7 q( {
% Y$ g7 s4 t" n4 z' ^3 F
3.如何让类中的某些方法无法在类的外部被访问?
, z( E/ z4 {4 R" i5 q, A7 V+ } G
& \9 c% \1 A7 `! h$ }
A.把类声明为private
2 o9 N; h1 o2 X+ f3 ]1 v# Z# b
B.把方法声明为private
, [1 w( X1 D. ~3 f+ n
C.无法实现
9 {9 R P w! k8 D+ W
D.编写合适的重载方法(overloading method)
; u+ x! M7 l0 I# T
6 S) ]7 I4 s/ V) m! M. ~% a* j
* j ~2 g2 {- N: Q8 `* W* a
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
' j& h3 c7 j& n9 R
3 K" a$ [& I3 X) R# x9 P" A, E6 _8 u
A.MVC模式
# u7 Q: @3 y7 o* [
B.抽象工厂模式(Abstract factory)
- ~7 ~. f4 n% X6 U
C.单件模式(Singleton)
2 z3 H4 J7 h! G$ G7 P6 W
D.代理模式(Proxy)
5 H2 j! u) @+ p, d4 g
E.状态模式(State)
0 s% T# w- z! _5 F1 g4 L) ]
" b0 Y" t1 `) s( ?* b
3 L, ], k0 x% y+ G+ N
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
% e" q5 W* ^5 {: `
3 z8 W) n2 }" x, h* D4 N! H9 R' k
A.1个
* k% D, V- m5 u9 V. s
B.2个
+ K/ j; s9 J! O; q
C.取决于系统资源
" I/ x3 E1 q" X$ P1 d( B5 I# c
D.3个
K: g/ r! N2 |3 p+ m# l7 ]' R
E.想要几个有几个
, x6 n3 S2 S8 @4 ?5 l
# m& `! ~6 ^) i9 v4 Q7 p/ [
9 `1 |' g' @3 `" q! _ t7 Z* L
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?
<?php
class my_class
{
function my_funct ($my_param)
{
user_error ("Please define me", E_ERROR);
}
function b()
{
return 10;
}
}
?>
复制代码
A.多重继承
# G5 _! k* ~$ o* r3 z* |7 K- _
B.接口
! }- O9 u' a0 b5 `
C.抽象方法
$ y1 ]" [/ Y( P9 H) C [* {
D.Private方法
3 U# H' H2 c* x3 _1 o
E.函数重载(function overloading)
8 C+ Y" w$ B$ j0 C5 N3 K
$ o! t: t7 V9 h2 b6 k/ n
- ~. E) T( i% {8 n' B
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
8 }$ ~+ A n4 p5 O9 H
; U/ v' s3 X4 e" K# N
A.__construct
' O1 y5 i/ M) K# ^2 t4 ^5 c
B.initialize
( B& z3 K7 z, [. W) ^
C.testclass
( L/ o1 _' e1 i* Y
D.__testclass
8 D$ ^+ ~6 ~5 I2 K1 w
E.只有PHP5才支持构造函数
' {# S, _) }- L# _# w0 d
$ M$ _: W0 r7 U+ m
, l5 v5 W5 a+ @* |: ~# c
8.一个类如何覆盖默认的序列化机制?
Y- W+ E! O3 u' [
7 v |# t6 ~+ U- Y
A.使用__shutdown和__startup方法
" L& I3 O: [, t/ T: s( U0 R$ B
B.调用register_shutdown_function()函数
6 S+ L4 v. }& E+ d
C.使用__sleep()和__wakeup()方法
9 M \! ^- B0 a( l9 B7 R5 G- g
D.无法覆盖默认序列化机制
3 z$ H1 G8 N7 @5 i# R
E.使用ob_start()将类放入输出缓冲中
. Y, W% A- p* r& `0 A
1 v3 K8 X% _4 M5 s
& y8 }0 J4 U: V3 B& O! r' m
9.以下哪些面向对象的概念无法在PHP4中实现?
. L! ^* s/ ]1 B: M: V
+ e8 s9 x( [% S/ Y- [
@抽象类
% s& D& \) B) E: x C
@Final类
* N; @" N L. L) o/ K) F3 q! \
@Public、private、protected(PPP)方法
2 m" w4 [, ]: Q4 m, K8 C
@接口
, W7 @+ d l( Q) X2 L& `
- w m, k/ H4 o5 c/ k
A.抽象类
6 K$ C/ }8 q' x( N% T; @
B.PPP方法
& W0 Q& F: F! c
C.PPP方法和接口
5 _7 p3 _3 ?3 O- I
D.以上所有都不可用
4 ?" b9 O; b7 Q+ r0 Y1 v
E.以上所有都可用
4 {9 Y l% ]3 X- v4 f! ~
4 o3 k7 ~0 j6 z I- _1 y1 G9 L
; ~: K( b3 S7 ~: c y3 x4 V
10.如何在类的内部调用mymethod方法?
. S5 T& D/ I2 _/ r2 ?
, x: x+ u0 j1 [ y* N
A.$self=>mymethod();
: j( h ^& D7 e1 b# N
B.$this->mymethod();
) C& C( ]5 H( D B# Q- i* a) U1 \+ Y
C.$current->mymethod();
! f1 y1 v- H. S) ~4 G4 u
D.$this::mymethod()
$ H- @3 B: P- z
E.以上都不对
% _8 ^. h4 e0 d- p8 k+ W$ d" O
d8 @/ ^9 T' x5 d1 ?# X# x
! m1 Z# Y3 `2 Z. X% x0 Q- J+ W8 F. p
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
9 F1 c+ I w. Z4 J3 D0 |
B.Null
* T( L( K7 R; }! _- W- K
C.Empty
6 J& s' Q1 H: w! N1 L
D.什么都没有
: s3 x" ?9 C. G: P* S
E.一个错误
3 i' g/ @1 H& w
# Q8 T% t% M7 C& c0 @3 g/ f: W
- q9 e" K' {* l: e: w/ Z2 d
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
4 M5 j$ G6 F1 S+ M# h
B.5
2 u7 X! H- T$ U: ~1 }+ o3 I, |1 O
C.2
1 `6 O2 G+ D0 V
D.Null
4 |% j8 w7 m _6 w
E.什么都没有
9 ~9 z3 m, g" D9 M+ q- n
' k2 e0 Y5 q) X+ W- h5 X
& E+ w/ S* H$ d6 J/ l( 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
$ m' @( C8 t7 I( @. ]
B.10
+ O, j, ^8 A6 q+ X, K
C.什么都没有
! {1 v6 ]' W3 n2 \
D.构造函数将报错
+ O; v6 O' r- @$ `
E.510
& f6 h4 B- Y! U+ v1 {3 m
9 O6 w5 B0 A) @0 z, I+ ]
6 i1 I8 a3 r. S1 V9 U. ~
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函数必须返回一个值
9 o. \4 ]: y6 D0 Q, H" s, S
B.reduce_fraction函数必须接受一个整型值
% Z: c$ y/ ^' x. l( v, L
C.gcd函数有问题
$ p' ]; q/ I: Q, c* E0 l
D.必须通过引用的方式传递$eight_tenths对象
* x; I# _' m, V( K% f; ]* f
E.对象的实例不能传递给方法以外的其他结构。
& y% Y7 }/ e+ E- c0 H( r B f
& G1 |2 {, y/ e9 j+ {0 F
, U( v0 g) \/ W$ Y T" w
15.以下代码是做什么的?
<?php
require_once("myclass.php");
myclass::mymethod();
?>
复制代码
A.静态调用mymethod方法
7 ]; m6 x7 f# C7 F& Q7 _ B
B.生成myclass的实例并调用mymethod方法
) a8 w+ c m# _- t+ l+ ]
C.产生一个语法错误
( A) E& o$ s& H% }) ?9 E
D.默认myclass类最后被创建出的实例并调用mymethod()
: T+ w& m, i- {7 l0 `$ d: K4 Z( E2 o
E.调用名为myclass::mymethod()的函数
" W4 e$ h6 [, U
8 u' f5 Q( U5 c# A8 r
( o, L6 U! N" L& f2 S/ S
16.PHP中有静态类变量吗?
0 l) X& O8 Z3 D, F5 h0 D
: q( J+ U" Q. ?1 Z: z* y
A.有
1 n. |4 ?5 E/ y; {' z3 d. d. v
B.没有
- i, W7 A' i3 t; U
7 o6 a9 d0 a$ n
: J* k: S3 O4 ]& Z$ k1 X2 R
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
9 Y Q* ]9 w$ }) ` e$ S
B.2
$ E' f( Q7 @. R" O8 K, L+ ^: }
C.一个错误,因为没有定义a::$myvar
+ m2 z, o5 |( M) _
D.一个警告,因为没有定义a::$myvar
8 @( M2 ?1 F% I: w3 k
E.什么都没有
, @1 J& Z5 G/ T" O2 K! R
7 j/ x+ z$ G+ R- {/ e! ]
( J! H4 x- ^+ p. p
18.如何即时加载一个类?
, C# y" n/ \( ]9 f8 z
4 ?+ X( g. ^2 f
A.使用__autoload魔术函数
3 y% x ?, ^# M: @5 P2 p; E% f# ~
B.把它们定义为forward类
6 H% d2 h0 Y5 x# w
C.实现一个特殊的错误处理手段
i1 U/ R5 x% Q W
D.不可能
, [7 ?% i4 Y% o2 F% {( h' i0 {
E.用有条件限制的include来包含它们
8 `4 f0 p6 \# b! ^& T: K$ @
& P! |) x. T! x
: v P. J4 E; W
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
( h% T& d! y9 ]
5 ?4 K6 |8 g6 }
答案:__________
5 Q: p+ C& ~( o5 z& @
+ N% t; n) S2 d7 {
9 A+ g" Z) D0 A7 b3 G" ?
20.以下脚本输出什么?
<?php
class a
{
function a()
{
echo 'Parent called';
}
}
class b
{
function b()
{
}
}
$c = new b();
?>
复制代码
A.Parent called
5 P$ R/ d7 w' h+ h$ D
B.一个错误
4 P$ ?5 ?4 K3 j+ v1 \& q- x
C.一个警告
2 R+ K0 k: g- m e8 t0 u
D.什么都没有
% P" H0 O; s7 ?
1 O. S+ o% u0 F- f" k) B7 \
* o4 k9 u+ @! i/ {
% \ u1 M |1 T+ w2 `/ A
答案速查
1 L8 W; Q' V$ R$ F
1.类
# W) G$ F& z: O8 u/ X3 ~: g. ]
2.BCD
3 b+ K6 r, c9 }& g8 A6 D
3.C
5 {# g* c6 e/ ^- b* Y
4.C
7 {& [! s* n* a
5.A
- I6 ]' k: z, t$ V. T6 D; ~
6.C
5 k" E# ?8 O9 n1 k. i: s
7.C
; _/ k) c. `8 u+ r" G3 z
8.C
; C$ H; H* Z6 m2 i V) B, s+ D
9.D
' _( ]* T5 b/ Y3 }* f- g+ w
10.B
: B4 F2 x" x+ @
11.D
& A9 Z3 K' S# ]2 x7 E! {" Q# U( A
12.B
* k. T$ @$ e- \' a% @) S6 G
13.A
' C' Q' e0 c8 y# J, d8 s
14.D
9 `) f: g0 W" A8 D4 t; U9 n" `
15.A
. @6 G+ b4 K2 {( b
16.B
5 J' X% e& P9 D k( F: Y
17.A
) z0 U1 x5 \9 V4 l
18.D
7 P. I9 o" h% Z1 P2 C4 S Q' n
19.设计模式
4 b4 a9 t' t# t9 ~1 `
20.D
- J: @# d% U) ?! x. M5 J2 k
+ {9 ]) V8 c3 ~9 s9 r6 ]
* n4 [- @8 N: |% W* h6 W, ^
- r/ N1 \- r5 ]% \0 ?( Q' j" s
答案详解
- R- I( b, E* B$ h( J9 _1 j
: i; \& ~# z: g) U) f/ A
1.类是对象的蓝图(对象是类的实例)。
; l+ F5 z! V: ?6 h+ k
+ f8 Q' [2 }% A2 H" i
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
1 N9 ?3 x( ]* o$ Y/ E3 }6 l
" N: @7 I# H O! v1 V0 \6 ?6 f3 C
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
& M+ V) c B H2 n: P$ B
: t2 D7 t) S* {& j& J1 V
4.单件模式可以限制一个类被实例化的次数。
8 C6 N/ \2 E( q9 `
# z- G o$ k2 K1 _+ Q) Z2 H+ U. D
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
: A' d5 R9 ]/ i! J8 D
) P# c7 G. D# W6 p* f
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
& U- m J" s7 e) J
( ]3 z8 ^$ S+ j& B/ I
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
4 a% I4 ^% s2 M& V, P
6 u, B0 `" T# `. u
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
, R# K2 s: {0 u# B2 S
/ V# n* m4 F' ?' T0 _( F
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
# F; P: [! d* q0 X1 w8 T4 q9 x9 P
& O1 r6 i% V1 X# d/ [6 Q
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
6 u3 w4 g5 q1 w7 I% j
4 s8 z, t8 R( z
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
8 y4 e# c7 b5 `5 u8 U+ Q0 P# O
: {# \# i Z$ R0 m
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
! b( Y# L# o! h% J) O1 u" E
3 ?, Z* M5 X6 h( G& X, K
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
5 E9 X0 U' T8 x6 T9 R7 I
/ ]- K7 ^: Z; e- U6 N+ c
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
. `% _( V ?! e/ q
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
2 y( ^; U. }1 ?) {: g1 d# a' g* Z
function reduce_fraction(&$fraction)
! m! C( g o- m, b) m
答案是D。
$ E7 ]8 i$ [) B6 _6 j* P4 d6 V
2 v$ V' x" } Q- G6 E0 y9 j- a. v- y
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
; r8 @4 g, t3 H. x
: s C% k% U+ J
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
) s& x$ ?4 |' Y4 z# |9 H! ~' O$ K' N
/ R0 C% h: Z/ h4 n) j6 g! }0 w
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
7 `8 G- \5 m7 f( O
1 N2 c" g& b$ u
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
/ s0 P1 l E$ ^( q$ Y1 |
! N4 Q; I" U( o
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
[' W+ u0 ]6 C/ V2 O9 }
: S3 v% K/ K9 Y# a3 F9 b# U
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。
欢迎光临 捌玖网络工作室 (http://www.89w.org/)
Powered by Discuz! 7.2