  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。0 l7 G1 p+ u+ ^1 _. l
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。4 Z5 P# M2 ?! @3 R
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。* d' u8 d7 Q) |+ f; p
' k* e+ N6 D* M/ C6 |& O, R
问题
5 g3 }- B; ^7 u& c6 G2 o* x4 G! b- V0 U" w% P. V
1.对象的蓝图是什么?
# r' U% O H9 f! @8 Q& A4 Q6 q4 z
& _3 Q- A; Z# y+ C( a: }4 N0 K, z答案:____________
- R$ M7 V3 t" S) \# ]# C) K% ?* }3 d: V6 d1 q2 f6 c$ r2 W
+ X, s. V; I1 p# g% q2.以下代码执行后,数组$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% f/ v1 z( @4 C& k# p
B.b, @" p% [1 F: k" m( v
C.a$ f# y# Y$ G7 D8 d
D.d K$ w& B1 E8 {1 O7 I% C
E.e
0 T6 e l2 `( @
- E5 C) y# X5 X+ I. V6 n; m+ w3 x, ]% F
3.如何让类中的某些方法无法在类的外部被访问?
& h+ F8 l! G& L& Y! P$ S7 U+ ]* e' g1 J4 {
A.把类声明为private
6 S: h. Z! E3 [9 S% H a" [B.把方法声明为private' N$ h; i$ ?8 {* U
C.无法实现$ u# q' Z9 o& v8 _
D.编写合适的重载方法(overloading method)
1 r1 E4 |! V( ?2 }) W2 K; T
, g& s# H; @" o8 Z4 p1 k6 {7 k& j* K% v; t$ r9 P
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?& ~0 v! o8 G ?. h/ F- P' ^! e
o, W% L- E7 t) @- AA.MVC模式
! ?; l5 x- x7 |7 Q' X, }( mB.抽象工厂模式(Abstract factory)
) _3 ]- {; Q% k$ u* YC.单件模式(Singleton)) A! s2 J2 _% ]1 p: e t
D.代理模式(Proxy)3 [ u2 E, u& z0 d: G
E.状态模式(State)
% K% i) Y& p0 A$ |% u8 f7 F. U2 T2 k: H9 b2 |9 a/ @
. ^( ?5 J+ y$ t8 [5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
8 Y+ f2 Q' H9 d" j8 o* P) k) ]$ U# Q) Y* p& r. N) }+ ^/ C0 C
A.1个
. v ~& x+ b, h. d0 M6 G; WB.2个1 N q4 H# M' J: f+ {- f9 w
C.取决于系统资源
v& M7 _/ L r0 z# fD.3个
1 o% |6 {# Q9 @+ C8 \, B7 ^E.想要几个有几个9 g f# d5 z" ^: ]' V+ ]
* S7 d$ I( Q3 R; Z' p
# x: e0 o/ l6 ]' m+ v8 f+ t6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承3 ~, e5 t6 h( u: {! N* i. R
B.接口8 U1 n U! e7 q7 ]: q( C" G2 h
C.抽象方法
2 j) X- ~/ v( [/ LD.Private方法
5 U" @( ?! g" PE.函数重载(function overloading)- J W- ^) v1 L3 L! z8 I* g
3 a: g* E+ G; M0 Z
% v$ [( M# ^ c* Q2 A9 \( X2 A3 l% K7.假设定义了一个testclass类,它的构造函数的函数名是什么?
8 J0 S- [/ W# ]: i+ ~' j0 Q0 Z k/ b; z2 e3 ^4 \4 |
A.__construct
: Y6 e$ O) s% Q" q0 b, \( @B.initialize
; o" {& N! F* S5 AC.testclass
8 {9 @6 o0 [9 R/ u3 eD.__testclass
- \6 [2 f( i" W# N0 Z# sE.只有PHP5才支持构造函数. e: k _; ^: @. b" z+ d2 x1 C; n
& D# \& _: ^- l, `
3 z3 z2 b* c* o. [! g8.一个类如何覆盖默认的序列化机制?
- g/ }( D# r* b9 N/ S7 c( y1 h
4 C. }( q \: o" m. uA.使用__shutdown和__startup方法0 C+ e9 G2 a1 i7 f# {
B.调用register_shutdown_function()函数) H! O: q# f- z) d( r, ]
C.使用__sleep()和__wakeup()方法
8 e8 N# O8 Q& \4 ID.无法覆盖默认序列化机制
6 |& D) G4 P7 NE.使用ob_start()将类放入输出缓冲中
" L! v$ Z5 V" e4 x5 `
9 c7 C: N/ ?1 J
Y5 p: E$ A G4 ?2 X9.以下哪些面向对象的概念无法在PHP4中实现?+ a1 s6 \. Z+ n4 z7 G0 ?* p x5 d
3 C) L# @* R, }0 {* q& X; a$ {! q
@抽象类$ u9 y% v8 l9 N6 }- L" k
@Final类* S6 I/ _+ l" D9 i9 D, D
@Public、private、protected(PPP)方法
. Q6 \( W- {2 d$ Q. }@接口3 g! W* g4 y+ R$ z0 e! o0 T
- b2 m, |! Q" o; C
A.抽象类' S9 W. k0 ]1 b" m$ [
B.PPP方法6 f$ ?2 c$ B; U# n* \1 r
C.PPP方法和接口4 M9 ~+ N! |/ c0 E) x$ c; f y7 m
D.以上所有都不可用
, W7 \: b. {& S* ^! ~E.以上所有都可用+ \7 |- ]% N; ^8 f
9 i+ T7 v4 ~7 Z" J9 j8 [2 r V x% E2 p/ _
10.如何在类的内部调用mymethod方法?
+ n4 ]5 Y; w4 x! Y; _/ _" _, [9 x1 w; y! T$ F0 K X q) ~
A.$self=>mymethod();1 J6 E9 R0 h8 }5 M! I) _& U
B.$this->mymethod();: [7 @! \8 N# V3 I9 k8 g$ E- ?
C.$current->mymethod();0 a3 g$ G0 i) @1 H
D.$this::mymethod()
3 e) Z' b; {, O3 qE.以上都不对
5 f) L# g, F/ W! n. N- s e L8 h$ o6 c/ V3 E
, }2 @/ F* _+ d4 g/ o8 l n- T
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/ V, D5 F% x0 x' z6 ~
B.Null
2 O4 p2 L. J# EC.Empty+ z" n1 L+ S+ N e) B5 @% c- x
D.什么都没有- Z0 B: @5 T4 g7 }4 y; e9 u0 N3 c
E.一个错误
2 n% _: a9 T. b# Z* O* u
, i/ q7 w7 H8 K3 p% M- u
& ~; D4 w" Y b3 J12.以下脚本输出什么?-
- <?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.101 p. B: T, u( ~. H2 t' K# I: x. T5 Z
B.5. c7 i1 A7 g: p6 P& H
C.2
. ~9 m I, n1 W# UD.Null
; X l& e! d) F8 I" }- |7 b3 d. |% aE.什么都没有
0 _) e# Z: O, F3 X. `" O( ^/ T' ~5 z6 H; N' s# R8 e% m. }
+ |$ V! a, ~; A# q' U: R; w& m% g
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' C6 s# I, M1 J5 }- A
B.10
H4 D* p; t' |$ Z! @6 `& N* v, KC.什么都没有
8 A- N: d& E) aD.构造函数将报错
$ p1 t2 H% m& A9 B$ d7 y$ B( h# BE.510
5 l- s% ~; i( ^' Z* V) p0 T3 ~" s _" r; B5 U) L4 f, O
1 ]. |; h) ?0 N
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函数必须返回一个值( P U& g' \4 I! E
B.reduce_fraction函数必须接受一个整型值
- k& P, j4 V3 j5 aC.gcd函数有问题
/ r9 |! i' X8 I" fD.必须通过引用的方式传递$eight_tenths对象& A/ } s1 C* v$ Z' z' T
E.对象的实例不能传递给方法以外的其他结构。9 s: E- a$ X! Q7 U4 E8 Y
* |4 ?1 P( B k( n7 e4 `. _! M( ~! [ }( `. [- A) A" L# H, E
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法6 b4 W# j G! `4 y+ a
B.生成myclass的实例并调用mymethod方法
) C7 t9 S& r/ R: S6 aC.产生一个语法错误
' |5 f! D/ f% t* b! ZD.默认myclass类最后被创建出的实例并调用mymethod()( g {1 \* Z2 F3 g7 D! O8 m+ K
E.调用名为myclass::mymethod()的函数/ l& P3 i; R- h( P5 [- G" L! t
3 z, [/ U* o! C; X4 Z! F* z/ a$ b) O6 r$ |# G' ]& g
16.PHP中有静态类变量吗?' b5 q5 O2 {7 |; Z
. D: U Y2 v c8 C4 `
A.有
, R# _" ~, r% a0 ]+ D) YB.没有0 W2 Z, t; L0 i5 A2 `
5 k( o& l7 W; Z) l; [# J! n( P9 Z1 ?# K8 a u
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
' @, G$ w$ U& |5 c& Y0 }B.2
, X; O( h' ^ ^& RC.一个错误,因为没有定义a::$myvar
1 M$ o j# U8 ]" k& T: ]D.一个警告,因为没有定义a::$myvar
$ r4 G, Z( w5 c7 o/ N4 n- r xE.什么都没有! F/ }$ ?7 t F" x! L [% {
' i8 K) L5 [2 P
2 L" Y5 O9 I# t2 i3 W18.如何即时加载一个类?. X- y4 o% n, [8 W7 J
0 t. v7 F% P% c1 C h( t
A.使用__autoload魔术函数
5 d9 R- W1 }8 SB.把它们定义为forward类
+ K" {; S. q: sC.实现一个特殊的错误处理手段. k0 n- s2 l3 X- S
D.不可能6 f7 Z2 z+ ]# f& q& [) |! O0 e- [
E.用有条件限制的include来包含它们
0 }% i6 K+ J5 {" H8 O* D1 r+ j2 u3 O2 R+ Y
/ u0 t, j7 p, C19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?7 Z2 x4 N8 U. y. n
. e7 @ c- a3 ?. T5 P
答案:__________% |" S9 v2 A- w: O5 y+ s; _) t
. p( c# Z+ j% L0 _
?# @! ]3 J- D4 L& r' J) k$ _: B6 D20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called0 D/ k( b- F, S0 M: r- Q/ E0 |8 j
B.一个错误& t! L2 ]7 _( m3 N
C.一个警告* y4 U9 Q8 T" D6 c) t2 w
D.什么都没有
i: e. R& k/ b2 a# A. `
, {1 ^1 {1 e& P' x4 m9 @" W+ _7 ^3 G0 P0 z
7 X6 F! z& J5 h4 v& R. K) w: ?
答案速查* w, i( ^& _ R/ b1 |' a
1.类3 \8 K& z$ `2 F! r5 T
2.BCD- T. Q/ _3 f. \ e. o
3.C" o- ?. {0 U# S
4.C
8 i2 }; |% p4 A& G) \% ]1 ?+ P; w5.A9 D, @1 P/ f4 i7 i% |* n5 Z
6.C$ ^7 [7 w* k% T, X# |( u
7.C; l+ J8 e+ F5 E0 l. ]! k* h) n
8.C$ X0 [: F( C* J2 H7 L
9.D1 q* a3 V: L$ ^2 y
10.B
- R8 q, }2 R4 Q) b3 k! L6 ?11.D
* n7 C, B9 D8 P; x" c" Z" A12.B
3 @; k, ^* T4 g0 \: ?13.A
z" e* X' U' e# j14.D
5 X5 v, w) y& v+ d# H15.A
" x( Y% U3 `" j+ _5 Z e16.B
( |1 d7 D2 M1 C% }1 A) y17.A
! \2 q5 y' W. n) T3 w18.D. d$ u5 ^, i, x& u% r
19.设计模式; v, e1 e1 k) ?' g
20.D; B- q v8 y7 T: s: ~
: @1 `: _( \- P) c; @; D) g g# H8 m7 C. m$ |" v: S/ }5 j
2 [2 {1 x( \" i/ }答案详解
; E( y+ ]9 ~# l7 ^- f/ a0 N( i' i$ g* C
1.类是对象的蓝图(对象是类的实例)。
0 r3 Y6 @1 t2 F3 T
& M+ u ^. W8 y$ y+ B5 J- m5 \2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。% g6 o6 V9 C: _7 W k+ ]
8 O x8 b2 C# c( y3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。. o6 a9 H7 I3 q! B7 z! F
6 x, U( O) x P# s4.单件模式可以限制一个类被实例化的次数。
8 V3 T/ w3 Z4 `; P; m: z3 t' D$ u# P5 J0 J
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
4 ?+ _* T% K9 L$ X& L0 x
) K: W% k# G b/ ~ c6 y6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。; i7 @7 }$ B) g
3 b0 X" `9 B8 x% d6 K: |
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
! _) q2 V5 J' R2 q) w! f6 L4 |# u9 w; F* J9 w
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
" B/ ^: \8 N" K5 F. I, T& o+ F" i2 A' L% T* T
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
9 `, r) ~& c% J& `8 e3 a _( S. [; I* u1 X# [, S
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
' ]# \ i( r \( v; l+ `9 B
8 j+ w- ^1 e6 [: A" i4 I11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
0 c/ g+ j. k/ z$ n6 @
( x) h: u: d7 N; k! Y12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
- M6 W! J. Q1 \. C' C6 R9 f! [3 k$ h* A
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
& k$ b7 [( j- Y/ W
) b- g/ A& j* S6 H- A1 d `+ _1 Y: |14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。0 S/ _( u% T: ~1 L' L
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:( O! v; [' ]% U8 v- ?8 _
function reduce_fraction(&$fraction)
+ m. v7 l# i0 i9 X6 X1 v6 E( C答案是D。 g0 |6 a" \6 d& ~- X! q
3 ?9 N! ?! j# U7 i, g" l9 T
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ |! |8 W' l: B$ {; d% x
# v2 J Q! q& D$ ^$ g16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
; [1 c2 a# f; r9 a% s4 e2 o% F4 r1 q: Q
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
* M' v9 y U: C, K# T5 q' Y
2 m: Q. j9 ?6 i$ F/ B& k18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。1 H5 b* y9 n9 K; p9 f! p( J3 A
$ J+ d+ f, Q% X" f2 L19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
3 [- o0 {1 E* \( U& j
- P. w" W7 Y2 w7 n4 U20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|