标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
[打印本页]
作者:
admin
时间:
2008-4-4 02:24
标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
4 {1 X' O# R1 G5 t+ E
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
$ ^) o) f' K; d; J& w0 }
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
* g* }6 A! F, C! P t
& c# Q! h; u V2 R& h, m' }5 A2 Y
问题
$ w9 O b5 H. C- M
; i( w1 S: K6 }% Z R
1.对象的蓝图是什么?
2 w; V+ I( L+ `8 I! D
% H' j% b: g9 j% E. U% I
答案:____________
1 v9 X6 {# Q+ E! d: D3 B, c
1 E8 \# v2 U7 d& p! ~+ e
9 U) s& h6 @/ Q1 b
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
% e% I# E+ W5 w- K1 I
B.b
" V& j; f% w" Q9 m% A
C.a
1 Y! A/ r" s( r
D.d
4 m L% M5 u5 v3 U6 U* p& A
E.e
( K2 k5 V# _* G; M) _9 H0 A# i u
* `* z% h8 \/ B! S9 D! G0 p$ p' W
* {1 |% C- [5 I+ E' E4 i
3.如何让类中的某些方法无法在类的外部被访问?
3 L$ W D9 H; o0 }! Z
1 O: z7 h) h4 [" p
A.把类声明为private
, O" X+ Y; l$ c6 j" W4 P
B.把方法声明为private
* G& a5 X% W$ g% p5 E
C.无法实现
2 @4 u$ V) y+ Z; h- w
D.编写合适的重载方法(overloading method)
# s: b: Y; O% S! N- z) s0 Q) U' X
0 O* q$ Z* I2 G; C& Y/ b9 I$ X
5 e8 D7 `" H+ }
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
1 v/ o" A% _& B- y1 y1 Y
c) w1 _* \8 @ z2 @3 W2 C7 K, `/ N
A.MVC模式
( C3 K+ ]/ c1 f, s% S
B.抽象工厂模式(Abstract factory)
! G) `0 \' G6 r8 L1 q8 |
C.单件模式(Singleton)
! Z: q. `5 i, q7 p9 }4 S
D.代理模式(Proxy)
' G9 w$ v" p4 u) c; ^
E.状态模式(State)
( G! z" `7 m3 K
7 t3 \! e7 V4 D1 B7 b4 `& o# F
. T5 L; t# D8 K* W9 F0 h
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
# c, {- U2 S3 E9 z. ]" U
& ^ Y; h# s( g3 y+ n2 ]
A.1个
4 h" v. Q% j- r# k, X
B.2个
6 X4 r( W8 y+ C2 o6 y
C.取决于系统资源
5 c" _- z8 ?7 G! s" T0 o
D.3个
) m- \0 ?5 @( g
E.想要几个有几个
g! H& J6 a: y6 n
& N V% j# K/ Z0 u$ U
0 R# c _% {6 n+ v' t2 _
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?
<?php
class my_class
{
function my_funct ($my_param)
{
user_error ("Please define me", E_ERROR);
}
function b()
{
return 10;
}
}
?>
复制代码
A.多重继承
4 [) Y* K' b7 D: ]
B.接口
0 G0 Q/ ]8 ~0 Z' B l b
C.抽象方法
6 C) r+ U- M* }, V, j Q# E
D.Private方法
4 I' R9 m% `/ `* f7 Z# q/ @' v
E.函数重载(function overloading)
/ L2 I+ F1 U& a) p. c2 @
/ u; e, U, }9 I/ B/ p
7 n$ ?7 Y8 `2 ?5 q% F
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
: Y' x- W Z7 U, V& K- x- {; P
* \3 @, a4 L+ v9 w" ^2 n
A.__construct
5 F5 D$ d, f8 }$ E& ^( V. b
B.initialize
4 z- g+ K- u& M4 J5 U$ t+ U) k
C.testclass
3 ]2 V# N, x, ^. h) T$ P; I. T
D.__testclass
3 [" [, {' m5 g, f) W
E.只有PHP5才支持构造函数
0 m1 N+ T! T9 g9 w6 C
~$ s2 R1 A; l, `% H, g
& G T' z* |, F2 y' k4 A( ?
8.一个类如何覆盖默认的序列化机制?
6 Z3 V1 O! K! g2 b' S
- [$ b2 U% h, g" A) T) O9 H: ~. S
A.使用__shutdown和__startup方法
) j- V l" h5 r
B.调用register_shutdown_function()函数
9 g1 D( i S9 \: }
C.使用__sleep()和__wakeup()方法
9 ]! S5 X% v2 l8 x
D.无法覆盖默认序列化机制
5 A# ^/ ?8 x# q6 @5 V8 W7 J
E.使用ob_start()将类放入输出缓冲中
5 K/ d+ W8 H7 v1 W4 m$ A
. g0 l0 F5 Y6 Z& F& o9 `+ |
# V+ a; i9 i* \6 j q m
9.以下哪些面向对象的概念无法在PHP4中实现?
" Q% t+ Q$ x4 j* r/ E4 B+ w, i
. i3 R- `$ H% T6 J
@抽象类
9 G: S0 U/ ^ l
@Final类
6 {7 ?7 g: r& |
@Public、private、protected(PPP)方法
: n5 A* @+ ]1 Z' j+ Z
@接口
* D1 F3 K! i( A! O8 D5 E' c
: ^+ A( c8 C7 t0 H3 L1 Y+ f. `( X
A.抽象类
; v4 I! D+ r% f. T
B.PPP方法
6 @, p X" @9 j' L% k' I* @! l s. b
C.PPP方法和接口
1 W8 f+ g! `, Z: d( \3 b3 I% `
D.以上所有都不可用
8 s D' \0 u& R& C0 _# s! p; _
E.以上所有都可用
) h8 H% K6 K0 r1 M8 e
4 o! ^9 F( W8 E0 H3 k2 d
4 [' s3 I: K5 S: n
10.如何在类的内部调用mymethod方法?
5 T" X) D, c3 }5 o
6 ~7 @/ n4 y# E/ L9 p; N' v8 ?6 i2 R
A.$self=>mymethod();
9 W T [% t/ i, Q- }- o" R
B.$this->mymethod();
9 |# f2 R4 Z! ]/ I0 E. A
C.$current->mymethod();
0 A1 F2 a+ l8 g# ~1 R
D.$this::mymethod()
. h4 s% p6 S6 S+ ` Y1 H
E.以上都不对
8 ^: Z8 j$ |% c) c
# }6 Z9 c- f4 i- Y
8 |5 x% B z3 ~
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
: I% t8 @+ I/ H3 Z
B.Null
0 D/ g6 ?; n, ]
C.Empty
( [5 f, y. h% n: D
D.什么都没有
- {& x! J ^" e2 B! v
E.一个错误
, q* Q# K( e0 _& Q! C5 E& _ W, H
9 b' B3 D: B$ A6 k! v0 s
0 x/ M- Y- O X: q! L" c7 c+ E
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
; ^% d% o6 K7 ?5 ~8 a7 x
B.5
4 G- K, y! i2 q% G H& k4 f
C.2
6 C2 O( y! A w( F
D.Null
7 W6 [9 Q% O% O
E.什么都没有
. u S1 M+ i$ u8 S% v
4 c b. p+ Q/ B
- L. e! D; t. q1 l
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
6 }$ W) v2 Z7 F! X' v" y' U, m
B.10
$ x; l+ w7 V# N7 ^1 z8 k
C.什么都没有
9 a( e" u$ w4 \; b- U5 p
D.构造函数将报错
9 k4 a3 `8 F( e2 v
E.510
) K; @7 c& g; P4 ^
) e w# S# e5 y2 ^2 Q3 @0 U+ y ` @9 O+ L
$ f3 h7 |7 `0 n! }& U& r; S1 E% A
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函数必须返回一个值
7 G. R0 }* L! G# ?1 a0 x) j7 W# B6 x, b; A
B.reduce_fraction函数必须接受一个整型值
, ]2 F. ^9 Z: A
C.gcd函数有问题
4 x; C0 \4 |3 s: U
D.必须通过引用的方式传递$eight_tenths对象
: t* u/ g3 u' C. O( z
E.对象的实例不能传递给方法以外的其他结构。
- |/ U2 `, G9 s: s5 s7 U( _
) J0 O: v" V- _% t2 \1 u
7 v% T8 [% C' t2 i$ R3 q1 z
15.以下代码是做什么的?
<?php
require_once("myclass.php");
myclass::mymethod();
?>
复制代码
A.静态调用mymethod方法
1 U* v4 p0 Z" S/ c
B.生成myclass的实例并调用mymethod方法
0 g0 g* m- @. M2 G+ t
C.产生一个语法错误
2 Q0 F+ x3 \& p) S1 V
D.默认myclass类最后被创建出的实例并调用mymethod()
3 |% _$ K1 I, _1 t3 a, l; ^/ E/ \, Z
E.调用名为myclass::mymethod()的函数
6 O6 I, y6 z C
" i* e+ y" j/ s, A ? c1 j$ e
0 w) Z' R6 [" k& y, h
16.PHP中有静态类变量吗?
/ `: p/ d- Z9 N& @* _
) s0 f8 m. s" y1 h
A.有
. ~: w" L& D$ @2 U# G# t4 N) C
B.没有
+ `& y/ n' e. D* S3 X |0 F+ X
0 h1 G* f2 u% J" [' E
; J, }7 y* c, f$ f6 k) h
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
: O0 p2 R) e$ Z0 \# m# ?% e9 D
B.2
4 Z9 n/ s0 \, B8 b
C.一个错误,因为没有定义a::$myvar
8 n; J# d4 R% L& N4 T# T4 ~
D.一个警告,因为没有定义a::$myvar
+ e& \& F+ _- K8 g4 f# G' q
E.什么都没有
9 d& B0 D3 l+ s2 L
8 ]1 B/ F$ r$ r, M' B W1 `
$ _9 e. h1 d1 J4 k2 Z+ Y
18.如何即时加载一个类?
3 S+ h! Z1 R: H2 L
5 }& U, x4 c8 p( s: L
A.使用__autoload魔术函数
- H7 M O7 ?* ]
B.把它们定义为forward类
, d( J- F* x8 y0 \
C.实现一个特殊的错误处理手段
5 w! J) z6 d. h+ c/ n4 X/ d4 ]
D.不可能
9 @& M' O3 m- M# m# }4 @1 ?
E.用有条件限制的include来包含它们
: n! w( U! t& Y3 o
. _ \" R# D. s$ P t7 K( b& C
! G2 W( {7 ]* X
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
9 V/ H8 J0 e2 f4 v# B# R" v' F
]( P* Z7 X# t B
答案:__________
0 a4 g/ @8 ?* x6 U2 y+ c3 [# `
1 [6 e& b J, |
) N, T3 g8 W4 D7 W) j/ J
20.以下脚本输出什么?
<?php
class a
{
function a()
{
echo 'Parent called';
}
}
class b
{
function b()
{
}
}
$c = new b();
?>
复制代码
A.Parent called
1 i) ^; A& W. x2 q( t
B.一个错误
$ Q5 d5 z. e/ U( z6 e# r
C.一个警告
; e) o9 O: S7 J, n) K& h
D.什么都没有
% I* w3 D* @* ^
- S3 G* t; ~ j8 d. h7 }% ~
7 f& x, W- p" U J" p% o6 e) D; _
0 r/ X/ k8 h& P8 X' u A
答案速查
8 i2 v+ `% h4 C( D3 ?# @ ~2 ^
1.类
V/ q6 J3 w4 c) X" h, L6 s2 u W
2.BCD
4 x$ v: V1 G; T: N4 N/ N/ v: E p3 o' G
3.C
" {7 l8 z- \( I0 j, ^
4.C
+ d; {. G" \( R0 b
5.A
0 R2 x* {( G$ _, t
6.C
; A: t& Q6 D! U
7.C
. H; _, \/ n' E1 S1 [2 A& B0 _
8.C
( s- b7 Z, X1 G5 i5 A7 j
9.D
' k4 E/ k0 ?3 s- v9 T% n" o
10.B
& H4 |. G% a- x
11.D
! _6 `8 V$ C# b( ^: E7 W% I
12.B
/ u# G- Q4 H: A' f
13.A
9 `5 H3 g2 V7 x% j: s$ s/ q/ ~% ^
14.D
1 Q4 F" g. C: G( G, B$ W
15.A
/ j/ d3 a \! E0 n' @) h/ E8 d
16.B
' u V0 j% n$ b; z8 O q
17.A
* _: [$ W" o1 }+ [! ?9 q% \ t. _+ K
18.D
) `6 ~+ r2 c. x) k' Y) M
19.设计模式
H& p3 P2 y K- s2 E9 M2 L5 x
20.D
' G1 [* {. w% @0 |7 z+ d. j' I7 m$ `
. D) H. ]2 d/ o- Q' m0 D) z7 ~, E
8 I9 c" D* C1 v* [
' @# B. Q! U- X
答案详解
6 R- R# k& T0 a
9 @5 M3 A& [/ R
1.类是对象的蓝图(对象是类的实例)。
, v8 N) H& a0 n/ f7 p) A, u) v1 @
5 s- {/ B/ ~7 h2 p1 I
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
6 U5 F+ R' Q. [& T3 x: o
3 b2 b: C2 d- Z- d7 X/ f
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
6 w) x3 I( p0 m) j
N; h- \9 u" `0 D, L+ m8 ?
4.单件模式可以限制一个类被实例化的次数。
) X8 Y, y' i; m& [/ D' e
" T; ]9 K1 C0 F1 M& D# |5 c, E
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
& {3 U, v; x+ S. q4 |. R5 ?
7 K I) l6 u- E( l
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
" l/ I# G8 `1 L$ c6 z
) B6 v( P$ M4 t! d0 R
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
) J# E% b' X5 c0 _
% e3 L* g1 N" x$ s7 ` v1 R
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
2 ~- t$ s2 T! \3 w- Y
( W: M: q; w9 s: s. _
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
" D5 s# m$ R, N& y- m# p8 M
! J4 `$ h2 q( z. N# U
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
( Z& E! h: e) B, _% K' m Q
8 m4 P9 {; @- q
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
8 M+ a. [7 A! m% ? E" a
) w+ Y# v) R2 v" c( u% Z$ V
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
; v4 y( E$ ?$ m$ R6 r# j# J% r
" H/ Q( u8 v- e% o( D# Z( h7 \3 u
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
V' v; ~0 Z6 b* ^9 h
' A- F& E# c6 ~. q2 }+ n% c8 {
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
4 \! _2 \4 d% U+ }4 n/ z
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
2 V0 j k9 ]% ^
function reduce_fraction(&$fraction)
l& _( P, O1 L. I
答案是D。
' C5 j, j( N- w% Z
) E3 `' _3 }2 {' L7 s. D8 P
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
1 u% I- O1 E. U. e/ F6 _; E
$ \' d. R3 ?# w" g+ s8 z
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
# j! l& x7 I6 ?0 b4 n
# Z, n& i* P7 m; e
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
8 ~! ?" h- H# t) ?( k% `, X
, v! t7 a* X2 h
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
1 y8 ^$ b6 x1 A
0 U+ ?' B, b7 Y5 n: _# ]6 X$ _
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
& J" z! Q! Y" J' c
, [$ c$ b) K0 M
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2