标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
[打印本页]
作者:
admin
时间:
2008-4-4 02:24
标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
2 m% }# p5 s! a W) A
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
8 s$ f9 R! B3 t; e _1 V q7 d9 V" ^
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
# |- K9 u$ q- y' r4 U4 {+ p
3 [ G; g' ]5 K1 G
问题
) i" n- A0 J+ U4 D/ x# g+ X: ~
9 F% l% `* i a3 a
1.对象的蓝图是什么?
/ j7 y8 U1 z2 q, G$ T
( P9 f6 E+ @: e9 I2 J
答案:____________
6 L' H* U$ p, C) |- W* H5 v9 P
% e- G7 M# {2 W
2 k% p3 Z9 i& ~; x4 I0 _8 B& h
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
* W0 P; C( U1 G& w. u
B.b
; R" x7 L+ a" q; {% E# s
C.a
; o8 Q( v5 J( L4 D
D.d
. x2 a w: L- |+ e
E.e
) q- a# y7 o$ b3 `: Z
/ }( B, p( S3 h
, z7 z& l2 O E
3.如何让类中的某些方法无法在类的外部被访问?
5 _5 N1 O5 o) q( o: j1 w
3 z: T, s5 ]9 |" s
A.把类声明为private
3 F$ i, i6 K& X Z% N9 X& F
B.把方法声明为private
/ _# n; D0 i, x& m7 q+ V# g
C.无法实现
# z. u' ]: J* r# X% |
D.编写合适的重载方法(overloading method)
1 S9 v. T' }* R3 H3 R
8 M& W. ~- }; J% Q3 L; W
. ?, B) i6 j% E- j1 d- a
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
; v6 V% v4 R' c2 ?# V9 U! p0 Q" k, ]
- V: _+ z! a- V/ S, S
A.MVC模式
! d8 \& T9 X3 V0 A/ S* i; g: Z. `
B.抽象工厂模式(Abstract factory)
8 O4 c( Y# u. b8 [
C.单件模式(Singleton)
! W& \5 U! d8 ~5 P# g4 @- L
D.代理模式(Proxy)
, `& `% Z4 o9 V
E.状态模式(State)
$ j9 w; m7 {1 ]: h& w7 u' O" d
, X) ^ n& h2 L, u; `/ y/ g
. T3 a$ O9 q- {+ P* a2 l8 T0 I
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
( k' z; Q# v1 p' o
I8 v, g7 ^: C" Q3 l! ^6 O
A.1个
3 L+ [. d# G8 Z. t( j
B.2个
% ]# }# h5 T" `8 K/ t4 e
C.取决于系统资源
6 q- D" t" x7 h1 r4 S: S2 M
D.3个
1 m+ K- W4 w- y" I/ }
E.想要几个有几个
' S/ }9 u8 ?6 O5 a+ A
" c8 E: H8 P- j/ x+ m
3 U2 D% T7 r* N6 Z: T4 N8 n
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?
<?php
class my_class
{
function my_funct ($my_param)
{
user_error ("Please define me", E_ERROR);
}
function b()
{
return 10;
}
}
?>
复制代码
A.多重继承
8 U1 D0 a% H3 }
B.接口
1 T* G# ~" x- C+ |9 r
C.抽象方法
K) V0 K! Y L( C
D.Private方法
& y: J* E, }: K3 A! }
E.函数重载(function overloading)
O3 i# L, R1 O7 J: G* T* K
. T* N3 q( A+ ~3 w. k
% Q; X7 U% e8 h0 S
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
' _& |- {5 }1 ~& a: ]
5 a1 r& ]# A0 m" E* d
A.__construct
7 I B* t' V$ l4 f8 ]! K. \/ D. f1 b
B.initialize
% x" H$ H7 g/ c
C.testclass
$ Z4 a, Q& O' S+ R
D.__testclass
1 A. ?/ f9 w9 S& R
E.只有PHP5才支持构造函数
- g/ Z& G/ P% L# t8 @$ B6 ^. G% `
# Q0 p7 P \- A( i$ w
* H9 V9 y; O& S7 q8 ~3 B2 K
8.一个类如何覆盖默认的序列化机制?
}9 V8 P& l# }) p
Y0 T( F& ?0 m! }* o: y
A.使用__shutdown和__startup方法
6 H; j5 J% B; A" j
B.调用register_shutdown_function()函数
$ |8 q& G6 v1 ^; g) I
C.使用__sleep()和__wakeup()方法
% \. u+ z% m& J3 ^$ |5 D: M" I
D.无法覆盖默认序列化机制
3 W9 u9 ?3 o. _( e$ Z
E.使用ob_start()将类放入输出缓冲中
5 k% k7 L7 x& \ @9 n7 S7 V
8 n$ H! G/ r k8 x& I- T
% y. a: Y% h9 M
9.以下哪些面向对象的概念无法在PHP4中实现?
- a. O e% j9 Q, Y' }) ?3 e+ g
* \' J& q4 x" f1 L2 X- V
@抽象类
- S; v* k t7 C
@Final类
& K( b# b6 k. e* K# j) {# x
@Public、private、protected(PPP)方法
' i7 Z T+ G" U1 b& c3 `' N: {3 b
@接口
9 o' x$ u4 O$ ~6 C# ~ K+ U$ H
# W9 N/ ?/ s9 h, L- L
A.抽象类
; w( z) v8 Y B+ z, e! B6 D0 j
B.PPP方法
' s! A3 f+ ~& ?9 R7 U6 B; M
C.PPP方法和接口
/ z" Z" n1 u. U
D.以上所有都不可用
$ O& z! t! X3 l. C; k, ]
E.以上所有都可用
& g( }+ E5 Y4 s. C) u( j% D
- ]9 s, y2 j$ S$ C
1 I, R2 `8 ]9 S# \
10.如何在类的内部调用mymethod方法?
/ B% j8 b, I* s! l5 m1 _
- [" `# W( M: I$ d
A.$self=>mymethod();
0 [. i/ W: D: n5 c6 H L
B.$this->mymethod();
" ^2 B2 l7 ]( s) H8 _; H& l" b
C.$current->mymethod();
g" ^4 m {* T$ |+ h
D.$this::mymethod()
, x) h, u5 q/ A6 X; b- e& R
E.以上都不对
- I+ P. J( |- h
$ \5 }5 K% X- p3 l
: `2 {" Y D& n$ P# p2 V! B
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
6 k g8 r- A. M
B.Null
, I9 Z* U+ p$ ~7 X- `& c
C.Empty
1 n# f/ {) m4 X9 g* I! M2 a, M
D.什么都没有
6 B6 L$ O1 h |
E.一个错误
* x& d+ h, b0 C) D$ f1 L8 Y
* `2 v8 m3 V& A
: {$ @% B& G( \' {. Q
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
. _2 h/ ~ t1 ~
B.5
0 n. j K' [5 H, w) a
C.2
3 J) V# m/ s4 ?1 a; ~% R
D.Null
9 w5 w1 K! P' ~7 H% t" V5 c/ _
E.什么都没有
" V5 l5 j8 W$ Q# n
8 k6 b$ h P, p8 g* w0 [2 b
- {! E0 \3 q4 F! e
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
+ V9 Y4 _8 H. D+ E
B.10
1 P3 H6 x |1 J1 ~0 z! t* s
C.什么都没有
+ r; E$ S% K# y4 B* Q- k
D.构造函数将报错
1 t9 l4 j9 K+ A8 y
E.510
. H( q! \1 }, a% Y2 a# t2 ~* b
) T& `0 G) W3 d$ h- b! K. l
+ N2 g' S3 n2 h, p
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函数必须返回一个值
6 ^9 C" ]! Q$ h' t
B.reduce_fraction函数必须接受一个整型值
& j+ r9 y2 n7 p7 o$ e( W
C.gcd函数有问题
4 V: Z/ W5 a- V2 T
D.必须通过引用的方式传递$eight_tenths对象
" V3 S! ~" u: `' Y# P0 F
E.对象的实例不能传递给方法以外的其他结构。
1 i0 ?# M$ h/ T0 q) c
9 d, Y/ K9 g2 I3 ?
9 u3 l! L1 R& K+ w7 q
15.以下代码是做什么的?
<?php
require_once("myclass.php");
myclass::mymethod();
?>
复制代码
A.静态调用mymethod方法
+ N k; m5 F7 s3 M
B.生成myclass的实例并调用mymethod方法
( l1 p2 b L- p |
C.产生一个语法错误
, p; A' }6 `- Y2 W% i, ?5 h8 p0 M
D.默认myclass类最后被创建出的实例并调用mymethod()
7 z$ ?% V3 f9 s# s
E.调用名为myclass::mymethod()的函数
- E3 b4 J$ `, W) ]
; y' e _2 z" T7 {5 P* M. k
A2 {# {9 n& u1 g& i* }
16.PHP中有静态类变量吗?
0 ?0 d- i3 Q0 m% B6 E
9 S' T) m2 M2 h& P& g j
A.有
$ p, \6 \. v5 \ K+ w! W! @" h9 x7 N }
B.没有
4 O& P( i9 m# q- p2 R. Z
/ r( `5 M9 {: w' g; q/ k
) S8 M. K# o- O }& M
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
, M S# p7 h3 ~
B.2
, n( N o# u/ }* x$ o/ u
C.一个错误,因为没有定义a::$myvar
1 h' N8 m/ w7 E$ a; f: @; M: }
D.一个警告,因为没有定义a::$myvar
; ~; E: V/ E$ d s+ ]. a
E.什么都没有
' o7 s X9 }3 v$ r i& h" \8 n
* o7 v( }$ N- @8 {7 Q& z
& e$ A/ y) A- X: S% k+ Z- ]6 ^! ~: _
18.如何即时加载一个类?
6 e/ z' Z$ b: j$ W$ q8 U! e3 U
8 c6 L8 x! E8 L* \8 D* K5 Q4 V m
A.使用__autoload魔术函数
3 B# O) L' e# M; p/ ^. t
B.把它们定义为forward类
9 V4 S! y5 I7 s. v8 r) R1 F
C.实现一个特殊的错误处理手段
& s1 u: }+ r! k4 O& L. l3 k7 H
D.不可能
1 D3 B% Z; b: n7 s1 \
E.用有条件限制的include来包含它们
! X, O# Q+ M& p) v ]6 L
7 ^1 ]2 g- t9 _# Y1 G" P( N
j+ v3 _ m( { i( W3 y
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
; A# ^ A4 o! ^" z* t( c3 c
1 l8 w8 ^$ p5 N" s& q' C2 }
答案:__________
; i1 n5 w6 Z! f4 f& f$ D
$ T5 ?7 X7 [' _! U; a2 K
1 W- o( Q! c0 i y+ b* P/ H; ^# r
20.以下脚本输出什么?
<?php
class a
{
function a()
{
echo 'Parent called';
}
}
class b
{
function b()
{
}
}
$c = new b();
?>
复制代码
A.Parent called
$ ?$ k6 D/ D& g- h0 R/ k
B.一个错误
" p1 |- j: J( s" g# d# [( p
C.一个警告
+ ?( `9 {+ F1 ~. r9 K' S* m a" ?
D.什么都没有
5 j' X1 C; O8 A3 E: y
7 E6 L0 ^5 U' I4 ^ K
/ P* r; `1 ` w2 @( y1 b F
* [- L, s- A! Z
答案速查
/ C1 I7 X/ w$ h
1.类
; S$ Y* |9 i" c7 c0 S/ J
2.BCD
' W, F6 D% A: m' Q7 d+ T. `
3.C
, D# s$ J5 d0 W, y4 U
4.C
+ ]+ l! a, B7 }3 G+ j+ w. p' P
5.A
. z1 `, M9 v: ]1 [+ M/ \ k$ T
6.C
4 D6 d7 [0 B3 e' n1 z$ v
7.C
! H; W! b% I" P/ a/ K" ]% H7 b
8.C
* I+ Y& x! \4 S7 M" N
9.D
4 q# M+ H4 P) |+ U
10.B
# v" o: [8 G2 g6 B* K" o9 B) P
11.D
# R. O' Q$ m3 G# S0 D% `% h) a( q
12.B
, o3 j; @; x3 ~
13.A
/ p5 W& u0 W4 J
14.D
' ]$ o4 l. q* h- @ j& q g
15.A
3 R) S. L# e# P+ y- F, L3 N
16.B
- T' q6 K" L- C c: X
17.A
+ i' o' L; O# {0 L" \& {6 y- @4 C
18.D
1 K# Y5 e+ t& d* W6 B
19.设计模式
$ V8 ]% ^/ w/ X$ q$ ?3 Y. p
20.D
1 T: ^" ]5 W+ B# L/ H$ Y0 U# {( V
- m' A5 H2 Z8 p) n& A/ z! L- T0 ]# y
) _! g) g) V* K2 u+ Z/ B* P3 Y
6 u$ ?" `6 Q8 B9 H: F9 F. `! E
答案详解
9 m5 ~5 N ?# }% m" l& w& P
/ B `3 I: a6 P u% o
1.类是对象的蓝图(对象是类的实例)。
. {% B3 m4 h3 n" @7 g/ r
: W* W5 O2 w& q/ C8 i7 K7 }
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
g8 l8 K! A* ^0 {
. j. |+ b/ t( b
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
# c3 f: M& D3 U+ i! I+ r: h
3 f: L/ V/ p+ q! c8 V
4.单件模式可以限制一个类被实例化的次数。
9 f$ W1 y: {: k
0 m' B8 T5 x* U* Z
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
d7 Z c, O0 s9 Z. u
7 O# k& k) g) h7 c4 C* U3 M- k
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
6 A: J5 |2 Q! h0 @ f( e
7 A' m. w, w3 \/ [; m9 V+ a1 n
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
" l8 |, P0 {8 v; N1 l1 t1 B% q5 W
6 V4 D- k: G* F1 U7 A& M! N; |
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
B% g0 X; ~! `( p' i! _0 c
" S# i: q) I [0 T3 p
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
% T, B9 B1 b4 ~0 m; J$ i2 L4 h
& ?, H4 u) P6 K) {% P
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
2 c2 r1 m. l. r7 t, ^: L# {( x! D9 F
: l* y x- ]% U. a9 v
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
2 ~1 V, j3 s2 ?; Q6 ~* ~# W' S
0 [% \; J1 |. j" { e1 i3 D
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
' B/ J/ u4 K0 }
4 u- [% H" |1 j: u1 E% W6 L
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
5 ]5 w0 j, D. }" h% z% Z
2 D& ?' G( k/ P' j) _1 I0 D8 M) A
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
( c0 B1 G' a' o) C9 m' ^% e
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
8 j0 w1 o2 H9 T- m e. V2 f0 Q
function reduce_fraction(&$fraction)
9 i/ V( a! \" \' ^- j5 T- j
答案是D。
4 { k0 M' n7 {, C1 X9 Z
5 S1 Z | _ E/ Y8 j
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
& I$ Y+ [# @; \
" O8 i9 e0 _* c V$ z% Q3 @$ @9 w
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
' c3 j/ A8 O; B; n+ e
$ Y B, i M; O. M0 d& \' U& X
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
* K- A* S- {3 P% d4 S) K
" C, Q& a& M V- Q9 ? R6 J
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
8 o# I7 i8 Q% k/ f5 v, Z
2 E0 x- t p: r( N
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
5 g* k" N4 i" o! l: N5 T2 k7 r" V" Q
3 O( ? Q# r- r: j+ I* D( y
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2