标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
[打印本页]
作者:
admin
时间:
2008-4-4 02:24
标题:
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
7 ^/ `9 K! m9 `1 _
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
e3 s" I; u3 \' a* x
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
4 W' F \" J3 C) [
7 M4 m& W% W/ w( u5 v( o
问题
# @" c" ?, S l, K. J
: E0 N; F, J% n9 k8 D
1.对象的蓝图是什么?
% I9 Q6 ~1 W) [# q$ }
) V2 }8 h. R: U& t/ R+ ?+ z$ q
答案:____________
3 f0 o. f; q! P ^. J |- \9 `' W
0 q7 ]6 g' U6 A
+ Y: s! q( J4 a
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
' ~: Z$ t2 ]5 V. k# {2 D8 A: l
B.b
! e" A# P7 \3 E' y+ K% n1 `7 Q* |
C.a
3 \6 x3 Y0 T2 c5 Q
D.d
$ }( q* Z8 V' R6 H$ o& z
E.e
5 c1 q1 n$ Y$ X8 q% @
) Y& p) {* W$ L; w) ?
1 q; T/ i) h! `- F' s% K
3.如何让类中的某些方法无法在类的外部被访问?
) a4 ^$ Z3 s% W) n6 H, B8 w
" x1 f" j) @; S
A.把类声明为private
2 @) ~* L3 L0 j) j9 S# B5 T0 ] [3 Y
B.把方法声明为private
; I: X. u% z% J# A! v: p/ l. \
C.无法实现
! g, B. W' W8 {1 x) P
D.编写合适的重载方法(overloading method)
1 ^; f5 v- j, i# {4 F
: y& Q b- m! P5 X, D- u; z# b1 `
2 b' ]* }, b& k: {7 s
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
/ w9 U. M4 i# Z8 P% Y1 Q
% j) g! F& s. X# E8 N/ L. {
A.MVC模式
, Y! z2 i1 k% u$ ] r$ q1 `. z
B.抽象工厂模式(Abstract factory)
; F, j+ |7 `% _
C.单件模式(Singleton)
% I# t7 w% P# G& u) t
D.代理模式(Proxy)
: t& A4 ^$ e. l2 ?) b8 u
E.状态模式(State)
9 R* S( e) S, H) Z2 N
$ m* S/ x+ Q/ o# a( W* ?! ^
7 B- D' y$ a; ^% j* o- X. l
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
; p4 {4 A! ?' e* q! z. V/ Z
) i2 }" F% R; i2 w& C8 b) F7 u6 W
A.1个
) F8 p& j9 Q, @" H3 A. U
B.2个
- |, W i, `/ E0 ?
C.取决于系统资源
! x1 S$ {/ n( t: R5 _
D.3个
3 A6 g' y# M" c7 b) [( r* j1 C. ~
E.想要几个有几个
8 C! r, t( m( |- J" g. p
! o! w& Y6 }2 }9 c$ X
( N3 Y! E' u& ?& ]) U$ H
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?
<?php
class my_class
{
function my_funct ($my_param)
{
user_error ("Please define me", E_ERROR);
}
function b()
{
return 10;
}
}
?>
复制代码
A.多重继承
7 f/ _( }9 ?& Z! J$ u) U6 I
B.接口
8 v5 s+ a% K3 x
C.抽象方法
; |, t- k* N9 h& L, m) b. a q
D.Private方法
0 B. ^! o$ b$ H: f$ v1 M
E.函数重载(function overloading)
# e' Y& {$ s4 A7 e: z) d( o
# s+ D* }7 E, B0 \' N
$ W7 c4 V* ^/ P, x' R( x, @
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
3 c4 L) M- ? J
# ^7 \+ }5 A0 m+ ~. Z/ d/ k
A.__construct
4 F/ v y3 J- s8 h, @7 O
B.initialize
7 X( W a H X$ h
C.testclass
9 W: s( u8 W/ F2 H3 u2 A
D.__testclass
! u/ R7 s! L2 D2 e$ f, f6 [, r9 y3 u* Q
E.只有PHP5才支持构造函数
1 w, C! l8 D& U i9 h+ f( R& V
' M# n, M. v3 I$ v7 W. t$ O
! t% U% i% o+ _1 [$ T. o" l
8.一个类如何覆盖默认的序列化机制?
0 E( B( ~) w% m5 X: W
, ^ p3 H, [3 P! G" _5 D0 f% B
A.使用__shutdown和__startup方法
- C+ B$ i9 i: W' `$ c
B.调用register_shutdown_function()函数
( m" d X; M- n' Z& N* C
C.使用__sleep()和__wakeup()方法
: l# G6 j* r5 Y0 ?
D.无法覆盖默认序列化机制
: T0 i! Z1 A1 J& ~* ]
E.使用ob_start()将类放入输出缓冲中
9 s" P/ o, h/ }" P( u5 y b1 F8 t
* R7 l k; t% n! \
; }4 N* F8 |% \7 }
9.以下哪些面向对象的概念无法在PHP4中实现?
g9 D9 N. [ \- m- W: Q* c1 Z
: r5 N+ v a; C/ T3 v( k V
@抽象类
7 B `# u3 T$ @" T8 ]
@Final类
/ g3 a1 r0 O ^6 b
@Public、private、protected(PPP)方法
" `/ ?* l: X4 Y, y3 O# j
@接口
; _/ G8 q0 f4 } O, n
4 x1 ~5 N6 L0 \. M- Q
A.抽象类
' B$ _/ {$ q& a- u
B.PPP方法
3 p2 K) u' A3 e
C.PPP方法和接口
; r: J1 K% \6 `2 G$ Q/ g
D.以上所有都不可用
9 @* J5 ?3 q- d& {# n. o* Z
E.以上所有都可用
D2 \1 {$ B9 W+ R! w6 \* ^
. W# I( ~5 t" e1 {1 p
6 U1 g& m( N; N' }
10.如何在类的内部调用mymethod方法?
- ]9 ~- |# J# G& x
* H t! a4 F2 n' ? S
A.$self=>mymethod();
4 H6 y" @. K2 t6 i ^0 I
B.$this->mymethod();
# \) `) w1 V& M" O. N% Z
C.$current->mymethod();
" x4 V+ f0 q/ N! P7 `3 g, k
D.$this::mymethod()
% k8 R1 w& E+ m- [$ y7 ]: X
E.以上都不对
8 I! w# a" K8 n" n
2 B. k8 E" B4 U, p% A
, n3 ^1 D, ?. T: z ^% Y
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
3 V5 C4 P8 l$ D& h6 U( V9 h0 j; k
B.Null
8 g8 Z% \; ]# t" S: t* s s
C.Empty
. {4 }. q$ }/ z9 B0 z
D.什么都没有
, G7 q* `. q2 r* t5 Q" Z
E.一个错误
$ m' |) o: X7 H9 F$ S/ p! g) o: j
* |7 [% W& @5 B/ P8 n9 Y; T$ q6 I
! _0 p4 t$ `! G# K" G7 z5 S7 T
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 J: U) Y) I/ Z) j! M( b/ Q
B.5
: A( \( D6 z& ~
C.2
& C+ x8 y! u# o
D.Null
: h2 h. c9 w& U$ r* M5 ]( v
E.什么都没有
8 W/ z$ h* A& {/ I" y& d( I
3 J b/ u4 R7 S0 V# U2 }! B
( G. i* S9 ^9 i
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
1 j, Q* a$ T$ w$ g" M) o
B.10
* k `' G/ @% v2 P/ Q
C.什么都没有
" U$ w2 ?5 m/ Z& P/ b
D.构造函数将报错
- w# k! a+ T8 F; z
E.510
* j8 T4 X+ K, _# r8 P8 K
8 `: a) r# N( `, u2 x
/ d/ @0 h5 H$ f6 i
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函数必须返回一个值
* Z/ }5 ~0 n! z+ ]
B.reduce_fraction函数必须接受一个整型值
- G, P- t+ T6 b
C.gcd函数有问题
8 \/ x9 k* v% g6 W( M- o# ?% {: ~1 Y
D.必须通过引用的方式传递$eight_tenths对象
) l! a) K6 C2 ?* S" ]0 |+ ~8 x
E.对象的实例不能传递给方法以外的其他结构。
! ~1 M, k- m5 n; s2 a% z8 ]
+ |) j' C. a" {# s6 y
( s" A+ ?- y$ ~4 ]- v
15.以下代码是做什么的?
<?php
require_once("myclass.php");
myclass::mymethod();
?>
复制代码
A.静态调用mymethod方法
0 C% [6 `, N- w& t" c! `2 C6 [' E
B.生成myclass的实例并调用mymethod方法
* a4 r2 k/ |7 B7 j- B8 j' f, w3 v
C.产生一个语法错误
s/ p# s& K# w6 g; g3 ?
D.默认myclass类最后被创建出的实例并调用mymethod()
# g/ G- `, ]) z& h
E.调用名为myclass::mymethod()的函数
. l2 }' {" P% k8 O- F6 q
5 ]$ L4 J0 c- [! H) t- P" R! v
0 } k! i4 L e" {8 u
16.PHP中有静态类变量吗?
' `: d+ K$ a. T, A/ C* A& F' h5 U
, U0 I' s4 c5 y8 @
A.有
( l" m4 z3 U! Q7 ^
B.没有
# p7 F- x% D4 ?' V
" ?6 Z5 o: ]: Z
* p% X, q6 y: Z9 z" }
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
/ Q. U( A6 c# D m
B.2
# q0 I8 J. K: K! b# `
C.一个错误,因为没有定义a::$myvar
2 D x: ?# ~& X- S: v' [/ d3 `
D.一个警告,因为没有定义a::$myvar
! u7 R5 h# b; K1 F8 w9 M
E.什么都没有
6 m2 c# Q/ L" D- s- h
7 }2 l1 U% x$ [$ r! q# ^
1 Y" B* f: N" q$ W2 ]
18.如何即时加载一个类?
8 ^, W. Z; z, }# `1 V
' T0 T5 k& M. A9 u2 Y7 F$ u
A.使用__autoload魔术函数
l6 E6 b9 M9 D; j5 Q* B' ^
B.把它们定义为forward类
# @7 ^2 y! z% a; u; \
C.实现一个特殊的错误处理手段
, \; k" F, ~. t( c% D( ?
D.不可能
& ?! B/ h: M* V/ I+ o
E.用有条件限制的include来包含它们
9 Y( v; }! B. D5 d& [4 j
$ Z8 h- F- t+ u, ^5 p' h( e
8 [- O$ @' \1 Q. h* T
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
# ]/ p& M( U5 c* {
, }* E" H& ~; q5 S! `" K) D
答案:__________
5 e; g& \; t* O+ |* p' [, @0 C
" y' t/ b. i$ c$ @4 E0 v, T7 g
- f, M/ N O( L/ L$ ^! } L r
20.以下脚本输出什么?
<?php
class a
{
function a()
{
echo 'Parent called';
}
}
class b
{
function b()
{
}
}
$c = new b();
?>
复制代码
A.Parent called
0 A6 c! e1 G& B
B.一个错误
" `' J$ u( |; x' q5 f) n
C.一个警告
- @% R" D0 i+ s
D.什么都没有
; V$ }% `5 m7 r. ]$ e% B
& v& |' J4 e6 H8 X$ W7 k
* O: e+ E R a5 V
H! u% K: l& d) O d. o
答案速查
. j) _# B3 s2 r7 ?: U" Z
1.类
& K- n# @! M. `" ]6 g/ G
2.BCD
5 n+ g5 [; Y+ B# \
3.C
2 r" z/ \ P% b4 K p
4.C
: v- M4 q q: O$ T/ O
5.A
! b, J; n$ s: \
6.C
- [* ~! g4 \ t
7.C
3 j/ E( Z, d& h( W1 Q
8.C
$ W9 C* n! E9 v$ }+ |5 }2 U
9.D
6 h7 T7 n. Y% Y$ @9 i
10.B
1 q; t9 b. m5 M2 ?' O3 C+ q
11.D
3 z# ~" m/ L% y7 m1 e
12.B
. t# x% o. f, U9 i/ \9 Y* E6 m# I
13.A
3 g5 e+ G. f- E' d4 L
14.D
+ d5 C) J4 ^+ g
15.A
5 j0 Y1 I% q! H& H& ?
16.B
1 J' V( c9 z: |( `( G
17.A
9 F+ g8 ^' l$ L! D5 C/ b$ P" M
18.D
- M9 O) \7 X; q* |! b
19.设计模式
" |+ _+ b' w+ R. P% n
20.D
6 p% ]( D+ L! y2 x! e
8 C: ^% b- n3 g/ x& j( w! S$ w. V: D
L# x* V, P0 e% T% H9 z( t$ I
5 F/ I7 `- b6 L/ F) Z
答案详解
4 B- d6 S* N$ e1 s
+ K, M' K; z* X& Y7 v
1.类是对象的蓝图(对象是类的实例)。
7 H3 R9 L* A3 D n c1 O
# e7 @8 c" x9 \. W
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
; }( \2 b* B2 \1 j% l
* B7 G* }0 I* f' r% G3 A- d2 B+ h
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
4 ^; J, m$ x( ]3 |! O
8 d. u; _; o" ]: O( ]+ m
4.单件模式可以限制一个类被实例化的次数。
! o. u" H9 ~. |
. W O# z3 b& B2 @
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
6 m2 M, a8 h8 T# ]7 O9 J
. p$ ]% h2 O6 G: L
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
0 @. R4 L3 M2 t) G0 G" M: m" x
* S4 N; t: ]! t1 B2 ^/ c
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
1 g! w# Y7 Y4 `7 _; _' r
+ I0 I/ M( N4 w7 F
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
" v7 P9 Z. r j% f3 j
: s; o6 M) B5 M! U0 ]
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
5 k) I: R" Z0 ~; x8 i9 d
+ n1 D) A2 C1 K6 q9 k& G& L
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
' t0 O& X! Y' Y5 K3 i9 L
/ f( m. \+ ~ i% d/ D: o R$ I
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
; }* S* @) k) g7 [# O' u
5 c% ~' u$ p7 e# i
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
; \: W4 v0 q$ D4 g
: V. G ]4 G+ q, w; ~
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
+ O( U) f1 c7 b) P7 i
% }$ y$ p$ y; u [9 U; K5 Y
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。
% s8 j. R* r' i; P
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
+ `5 E; Y2 g6 x6 b6 j9 L4 c
function reduce_fraction(&$fraction)
5 {# d! u2 [+ m: _5 A
答案是D。
" _/ }4 \4 s0 d+ Z9 H/ B
$ r$ N) S# b, |+ A
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
F; d3 n( _3 A- @: x b
: Z) {& O) G( w! V) M2 B( A
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
9 l! d& n! n. U, X" y4 g5 \
1 ?( N" U# [! g4 Y/ U; {; W6 p
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
7 [) g5 `2 e9 P9 m
( _) b0 `: _' D u1 u8 T4 i* g
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
8 o# _$ v7 Z/ y( b9 p& z
# J" P" B _1 Z# @: |2 A! E6 L0 G
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
2 x9 p' R% i7 i% l4 t
* q u0 f; _! Z" j7 o- c
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。
欢迎光临 捌玖网络工作室 (http://89w.org/)
Powered by Discuz! 7.2