|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14389
- 金币
- 2480
- 威望
- 1647
- 贡献
- 1428
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。4 m4 H7 c8 r$ B" ]0 K) Q
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
5 @+ `. {4 u6 w& {4 S. p本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。2 ~0 X7 E/ X* v3 e. g$ u
7 g# `1 g0 x" Y" A( Z5 A
问题
% @# }" Y7 d' X) i2 K* C5 p
7 E8 s1 j1 E6 a- n. C- D; K1.对象的蓝图是什么?/ M; u; E3 o) e4 c$ Q' o
8 c9 |' S F3 G; Q2 a6 d
答案:____________
/ _1 W) F$ A, m* q( W" z% ?
4 k# U, N0 }5 o+ }+ e) }9 d8 U4 e: R, |
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 M3 O( k' U: u& u) ?/ ZB.b7 X, L* s" M9 j' s3 s0 u
C.a; P: o7 _) d$ L5 p
D.d9 v' y' R& v9 Q! E% y4 R# l6 x
E.e
k. S; w, Y/ r2 p& {0 `" S1 K( C$ I- G1 G
* p1 o0 E( S# ?6 C3 \
3.如何让类中的某些方法无法在类的外部被访问?7 x- C+ q! @: T2 t( B) V
) v; N* K0 ^) }! x. u7 E3 g+ P8 V
A.把类声明为private& e# p6 g) r- B6 A& R9 M$ L
B.把方法声明为private/ v b1 r1 s0 D7 x2 i7 E
C.无法实现
9 T( |: B% n5 G* t: l5 ]D.编写合适的重载方法(overloading method)
P7 L5 [% b9 S4 k7 o
, g) J/ u- u# y* S0 \' ~: u8 t3 _) c2 Q4 z% I+ |4 p
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
, S% F1 s6 N5 l* J' P6 `3 J" h6 ~4 ^( f- K* \
A.MVC模式
$ I) I, W. \! ~1 v9 c7 r9 gB.抽象工厂模式(Abstract factory)' s& w: }+ r" @
C.单件模式(Singleton)
5 f" h( I4 p6 t3 \D.代理模式(Proxy)
0 W# Y$ I/ G" M0 A7 A: xE.状态模式(State)
8 C' Z C5 G7 P6 Z3 V% m
0 F' p6 f# [% p5 ~; D: O/ b' W$ F$ Q( @9 F# l' N
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?7 i* z7 f: W9 l- e- @
0 J+ g. n$ J( T. w6 o: UA.1个
' k9 G1 G5 {4 A) R$ NB.2个& _, H) d) P. U( i G
C.取决于系统资源* \1 _7 F% g3 B% M: B l
D.3个/ L+ {/ l0 f5 n% F$ G, W0 H* r; z
E.想要几个有几个7 A0 Q7 u/ i: \' c% e* Y# t
$ m7 Y; E w& R# J
5 U/ ~3 }5 F# H$ h1 A" q- e6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
8 X* r$ j2 W) j7 y& WB.接口
$ F6 [' v Q9 s. S( L+ PC.抽象方法' t& P" O# C! G# u& C4 x# r
D.Private方法
* C; Z9 D1 e4 K% Y! M' iE.函数重载(function overloading)
, T+ L- N% p& J- \! T- ^$ o$ \8 t+ I) [
- a& b; g& J4 S3 w- c Z" @: b$ t
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
& }- w$ }% A# q! {& z: R6 V' ]# z0 ?' ]' K2 t. t9 l4 P- u
A.__construct
! A$ ?- r4 W3 n! U3 l3 U" }B.initialize
7 n' e4 v/ }& z% I, ~3 h/ EC.testclass3 q- n( h! n3 j; T
D.__testclass
4 A" X' x' S8 Z6 U8 LE.只有PHP5才支持构造函数
2 v9 c6 j+ J5 z# {* M2 W/ h& Q% [; o n; y j7 G
7 D) g4 v( S( s0 q1 a5 T; w8.一个类如何覆盖默认的序列化机制?
2 P7 G' r1 t6 J5 y( W2 P+ N8 m# `% L: N0 A' z% L
A.使用__shutdown和__startup方法
) E0 `* k+ w" l* hB.调用register_shutdown_function()函数& G" B( [# j7 Q$ s" q
C.使用__sleep()和__wakeup()方法- p P8 C" ?( b$ ]1 d' k2 F+ C
D.无法覆盖默认序列化机制
3 ~0 K% w! |( g% i8 KE.使用ob_start()将类放入输出缓冲中0 z2 g; f! }$ [, b" S
' I7 ]9 ~8 B/ w. Y- r8 [+ y
+ G7 u" x( \! a( v! c9.以下哪些面向对象的概念无法在PHP4中实现?3 W+ J! x4 r5 l" w& @/ V; W
8 @9 |1 F) H2 U) f) J( u5 z
@抽象类; E( y' D5 y9 m& e& K
@Final类- M2 j" y1 ^# l' v/ R/ R M
@Public、private、protected(PPP)方法: k7 j, z" Z$ v- M0 S
@接口( F& M# q) M4 u( I4 e! L
7 y4 J; ~$ L% D* j: QA.抽象类
' e) h. o \5 y* g( l! v& w$ mB.PPP方法9 R2 ~+ T* @( J( [% b& A
C.PPP方法和接口1 @" B5 Z, n: Y- ^ B
D.以上所有都不可用# E V* }: u7 V& a" {" T& o/ G+ {/ F
E.以上所有都可用
y% w; [/ |" ]' ?: s# G( G9 W9 a/ H" P, H$ k4 r; z( ?9 \
5 \- r( }. w$ J$ a. L8 x9 K
10.如何在类的内部调用mymethod方法?: Q: }( H; c5 Y; H5 x7 G
8 C2 W/ l% @( \! a. I6 m/ I+ NA.$self=>mymethod();
& M# G/ W+ F! M* n% n* a4 ^" DB.$this->mymethod();. I$ J( p+ ^3 D& M1 W4 H
C.$current->mymethod();, o' I# g- R! W5 D# x
D.$this::mymethod()
0 m' x- Q# R. ~( n# F3 K0 yE.以上都不对, W/ V4 S1 Y; d6 r* u7 r
; t2 F7 U% X. ~
7 C; h/ G8 o+ i, A3 w4 ^
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: D5 H/ E5 A+ {' D/ U& e v/ D
B.Null) m7 k4 w: m% J2 I& v1 X
C.Empty
|' W1 I3 c# U5 O1 e% }) HD.什么都没有$ s# c4 `% R" P
E.一个错误 ]3 e8 m( Y% d4 ~9 J5 y
$ f+ M- L- @! P% K& n x' t7 s( E1 ^2 i; o
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.106 }0 u7 Z' z# N- a8 `6 L
B.5
$ U, q8 I8 B; d1 w$ JC.2- j/ K2 G( H9 C2 i4 l& M$ X
D.Null, l+ Q; n, B* U% v7 X% x
E.什么都没有1 T( ~! @: I8 Q% f; a$ q
M8 u, ]& E$ z. p1 _/ [' U( c3 u+ r2 w3 _
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: B: ?4 U2 e1 ~+ u
B.10
9 ^9 K) {0 m: g, p* }C.什么都没有# w) _# y) h# \; C! f4 L" J
D.构造函数将报错! p; Q) }$ F _+ `3 M
E.510
5 p6 {- A6 \7 y4 V
5 u5 [1 K4 {4 _; l: d6 v
9 v s. `3 s! [+ ?2 C/ i1 Z14.考虑如下一段代码,执行时,$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函数必须返回一个值
5 {! I) k% F# \6 y+ O5 _2 ]0 A( QB.reduce_fraction函数必须接受一个整型值( U L/ S" ?( V' s1 h
C.gcd函数有问题
5 w" j% C. {8 J! S5 M6 ED.必须通过引用的方式传递$eight_tenths对象
2 Z; G5 B1 E0 H/ I/ A) {E.对象的实例不能传递给方法以外的其他结构。$ x6 L6 e4 P- B; u4 f
! J: r$ b$ f9 Y* `3 g% a$ a( M
3 J# {( o( A; O2 k2 n! O0 A( L& k
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
5 V" i% L* L' y1 aB.生成myclass的实例并调用mymethod方法
/ \8 t; f! b" nC.产生一个语法错误4 @# g# S* }" v& b' o, \
D.默认myclass类最后被创建出的实例并调用mymethod()
! n2 z, m* D3 N, }/ s7 p/ w# dE.调用名为myclass::mymethod()的函数$ D- |( T H/ j
( r' @; y3 K$ G& S; C
: s7 O* J4 F2 p3 e: U/ ?' \16.PHP中有静态类变量吗?
7 p7 {/ `2 K% m6 U3 j4 C' E3 N. F; j3 n! }% t* W. j4 d
A.有
$ Q: `2 X7 _$ ~+ v8 U1 i/ cB.没有+ F, ^6 `0 l4 X% }: _
; g% d. i& N0 n8 {
: J2 `9 |2 s: O; t* w17.以下脚本输出什么?-
- <?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.11 X, u9 r6 N" I/ P" ^8 }7 `
B.25 C- y- M) W/ `0 k$ c- R
C.一个错误,因为没有定义a::$myvar
9 F$ {, \# G8 a4 v4 [7 DD.一个警告,因为没有定义a::$myvar3 z1 z5 v9 z; a0 \
E.什么都没有2 J9 R+ e# k2 |- J8 `6 x' X* [$ _3 o. J
6 t {+ M1 N$ G2 u% h
( b+ P; w- H2 t# J8 Q
18.如何即时加载一个类?
" V6 t8 _# O. R& g$ j O
7 x0 q5 C3 Q' D* Y3 Y8 w4 s, gA.使用__autoload魔术函数1 H8 G1 N" f. Z" G
B.把它们定义为forward类; B1 ]# \3 Z! {5 z$ D6 F# F
C.实现一个特殊的错误处理手段
1 c- S% s: p8 T8 V: S$ m: p7 F2 VD.不可能* ]* k; k6 d% f R
E.用有条件限制的include来包含它们
" |+ v# W0 n1 T% G9 A% f) f/ \% A9 U: d0 ~
" v) ~! f- N7 ~+ Z2 N w& U( y
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?' ]3 o3 @. A6 }3 I% z) G3 Z# _! `4 ?
. ], ^ i( L9 \" n! I0 I 答案:__________& o; f. V7 D" V1 O
) t( |1 r- S1 Y: Z4 e7 D
# d7 e2 m; f: b: q% J9 z7 v, I20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
( T: u6 |% t2 OB.一个错误# k# u4 I- W; ]" z8 t
C.一个警告
+ N6 o$ e# j) z% B+ j3 GD.什么都没有
4 ^; x' q5 D' d7 x' t& Y+ \ R D& s- }
- d+ p9 N& W6 n8 j ^$ e& ]; R6 Q+ ~" Q* M
答案速查+ f: v2 @( }" a+ @' f0 Z
1.类8 y( _) W* n# M
2.BCD
" p: j7 Z/ d' z- E+ `" `0 S3.C% N4 {! ?$ Q$ h- P' r! T
4.C
, i x, c$ k0 g! S+ Y2 E5.A: P2 X" T3 o+ ]/ _0 k
6.C. c1 k; U/ Z0 I+ Z$ n
7.C- K) R/ p i3 f4 B& L
8.C$ K. ]7 l S, b/ E( k
9.D
g, T; x1 o/ c+ G/ M1 X# T; }10.B3 Q2 X: X" d# N. ~
11.D8 @% n* l" e6 m. K( \
12.B
& W" J3 z x% w. x4 R- z, g13.A+ G$ K$ N/ }; y1 z* a
14.D
+ y8 x/ Z' m& z/ h+ ~$ `15.A+ I3 p' l, R. \2 l) ]
16.B3 l- p! _2 M" {1 _8 z
17.A* B' o9 ]/ {8 Q! b% _0 P
18.D
, q- u& o8 M$ F9 r% a9 b19.设计模式. f1 [! q- n m/ w0 P
20.D/ i8 ?) r% S. \5 V: M0 F
7 r8 [/ ~, U* z- c$ b3 z( n% Y% { {& D6 I9 u
# W7 W9 r2 U) K. I# a: C
答案详解
- l* B! [# v9 v- m" D+ A* N+ l, d4 M. f$ g& a
1.类是对象的蓝图(对象是类的实例)。' e1 p6 n! S0 |' f, ^, O
0 Y) y9 ^! F0 ^6 Q4 `
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
4 q7 s2 X6 `4 s3 n5 J: @& ^1 b% _+ \' f' T0 I
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
' |9 U- l; Q4 R7 W/ T9 E7 l& Z
4.单件模式可以限制一个类被实例化的次数。
+ h: ^8 d2 W% c4 Q# b+ k' f4 ^% a5 I8 b5 j) A2 T! R2 Z: u# p: H
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。, `& s. X, t0 p$ V. ^; \3 o0 x. ?+ m) J1 U
- |4 }8 k, u1 O8 \. A
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。9 o- n0 ^$ V) A0 q1 a u( t
- x9 F* P% i6 c) u, a: U7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
1 m- B% y4 F. h4 v R) ]5 [8 `( I# q! \
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。/ o B( a/ ^- ]# C- C# U, a
* }2 N4 v0 ^* X5 x6 f, ~9.PHP4中没有题目选项里所列的任何一个概念。答案是D。) V) B1 A& r$ U
+ T4 q% B. f' P10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。( w K" P7 E8 V- t5 V
' }- R2 C- Z: `' \9 v1 [' X11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。* X; f2 V% a: g7 L/ g' ?4 H8 ]
h6 Y6 l4 u! Q& l, Y1 r$ y. d1 h8 s
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。8 [6 o7 E: w$ M; v
) x1 C7 G* ~* l. h
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
/ y' D; V0 Z+ X# @4 k
5 F: I" t0 ]. |9 ^14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。0 D7 w0 z. R: I) `6 _: T
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:( Q* x8 Q* R v( w( A2 f$ m
function reduce_fraction(&$fraction)
9 f7 ?- D$ ?4 z答案是D。! n' v# O( K/ _ d5 X4 M8 k
% ^! J+ G" a# k; e15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。2 O/ q* F9 @/ [2 a9 ^: u
- Q4 T6 q: Q" w' Y16.没有。PHP4只允许声明静态函数变量,没有静态类变量。+ z/ C" _4 f4 C
6 I0 F; {' r4 n17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。( `: C3 |7 ^+ I
g- H9 G7 l l+ e( M18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
) M# L9 x/ ~$ Y) J) o
; \8 M2 L$ q0 t2 C5 {" ^19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。! e5 }! e4 L4 h6 M" C! g' d
8 O! o: L% g. z20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|