|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14391
- 金币
- 2481
- 威望
- 1647
- 贡献
- 1429
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。1 V) G; F# W8 M) H1 [+ K
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。8 L6 u% x$ G+ g+ V, `% I: a: D
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
+ e- ^' K0 P. z9 ~0 {
0 j0 W: [# o" D问题4 c# H1 ]7 S0 a
$ m2 N, u* S, Z1.对象的蓝图是什么?7 D: w# L' T( E1 P. Z' u g" i
5 P7 @% u; t' d* K; L
答案:____________7 `5 r0 n7 v- X* t1 D6 b2 c2 G
8 ~& q' k* k' U( H% Y% y! C2 o5 F" A5 v; _0 q3 ^! z7 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.c1 J7 e6 z: e4 d1 p# x
B.b$ t3 \$ ^6 \/ K& f+ y" h/ w; j
C.a4 \' N" ^4 R/ E# S! U
D.d7 h, c m; p* B& M
E.e/ H" e; Y7 [1 V
# v, A/ O, V6 o; ^7 e
) K3 D, `) f$ {1 j! |& |, M4 p3.如何让类中的某些方法无法在类的外部被访问?( d: D" `/ h4 ~/ T1 M2 B
! M/ k) ?! D+ A5 c {' ^' _0 z
A.把类声明为private
. \/ ]- b2 ?) U- CB.把方法声明为private% v; ~7 L+ Q& D2 U; O
C.无法实现) R9 Y; g* L6 H2 B& w
D.编写合适的重载方法(overloading method)& z/ z/ ?; k) T" s' {, A% A [& ^
" x' A# N2 a5 N. J$ O J5 k; W
: G8 r8 N6 a* E; E* ~: f( r- {4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
& _ [, ^6 d: O Y- |
/ g0 h. K# i, Q/ ^A.MVC模式
1 U1 d! y9 v5 n. w9 ^( q# R" PB.抽象工厂模式(Abstract factory)
+ q- g! o. S" v: m7 aC.单件模式(Singleton)& P4 \8 Z; H$ M' b. U2 B: R
D.代理模式(Proxy)
|! P4 {! Y- \9 t1 C dE.状态模式(State)' _ J, h% i6 Q: v
) [3 L" A+ ~+ A. q r0 z% B! J9 g
0 J8 L' v4 G3 g7 S5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?( B- d$ k3 H' L6 w
1 x. Z. Q O8 p% |9 \, YA.1个3 X0 f& ~; x: N
B.2个
; c/ E" @6 c1 x* x# GC.取决于系统资源
2 | @7 Y* ]! g/ G7 `& n7 qD.3个) m- ^; j$ G" k& {) O
E.想要几个有几个. Y! }" ^& S; I2 T
- O0 F0 b9 k% T9 O& O+ E
8 L* p+ m1 N. b, A3 Q+ K T8 L
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
& }+ \; q9 I3 a$ K6 O) @B.接口
& t ?) R \2 L8 S& N: M4 ?0 u' qC.抽象方法: P! K* }' j6 G9 o, j/ T
D.Private方法 n% s: r# ]5 o6 t
E.函数重载(function overloading)
6 o4 I+ E0 s/ w, K; e; y D) i
4 N& `+ }/ f* P5 V$ ^! r' J0 W" \, ]* w* C7 ^* M& l7 V$ h
7.假设定义了一个testclass类,它的构造函数的函数名是什么?3 N w! Z' ~. J
. @( |9 T/ H6 p4 U. c" X [
A.__construct9 [5 l% a9 i9 w! w0 l' c3 T% o8 G5 _
B.initialize
6 d) H! h$ |) yC.testclass
1 J0 a* T3 J) }2 J% R! E( jD.__testclass- E2 l0 {/ U9 c
E.只有PHP5才支持构造函数
( v/ w7 b8 \' B2 C2 R. u/ [
7 { O; {( ~; x
/ M& k- I' A4 h% _0 Q! A8.一个类如何覆盖默认的序列化机制?5 G' v( E3 h* G! ^! Q
. @* N# U: U( V' x8 q
A.使用__shutdown和__startup方法& F$ F# g* o* q4 }6 f6 [
B.调用register_shutdown_function()函数
1 K% A. z. ?+ n, NC.使用__sleep()和__wakeup()方法" Y5 E& L- O7 x" S4 N, `
D.无法覆盖默认序列化机制
, g4 k$ @$ v' L* f: rE.使用ob_start()将类放入输出缓冲中" D0 r2 o( l* Z3 G$ h8 p5 w J
4 \ X6 }! d8 a/ l5 c( P' M, `+ g
. L+ ~: }2 P+ N, L% Q$ t E# k3 }
9.以下哪些面向对象的概念无法在PHP4中实现?
' n- x" v$ ~4 ?" `2 R5 w4 v6 \& l* ?8 n
@抽象类
% q$ ~7 p) Y. p4 L@Final类
9 m/ O. t# j+ K: U8 {@Public、private、protected(PPP)方法
" W8 k8 h2 I$ Z$ ?( Q/ y@接口/ `- _# @2 c0 t( A! ]0 a
& J& t4 D* W: s: @- \A.抽象类" t9 a4 B1 W" \, ]$ ^' a0 K) j! J
B.PPP方法- b$ l: I' s X3 ]( n( U9 |7 R: H s
C.PPP方法和接口8 q! j8 K7 U& z/ J2 O; p
D.以上所有都不可用8 w9 u4 }& g1 ?# ?
E.以上所有都可用
1 N6 I( I) ?, D* g
& I. Y" W. c3 @( \# z2 C) [6 ~5 l" h0 ~( e
10.如何在类的内部调用mymethod方法?
% T0 d* Z/ V# b2 n. c# v/ M0 d/ v+ q7 e
A.$self=>mymethod();( J* Y' _- }+ _3 ]% ]) G3 P0 g
B.$this->mymethod();
, X! H/ d" U+ e0 J% y7 AC.$current->mymethod();7 W9 { A/ U8 b( ]) @. n
D.$this::mymethod(). s; E( \/ P0 {/ @+ d* P# n
E.以上都不对- ^- L6 ^$ r& z) k
* Q% }1 m; i3 Q2 t+ |
9 ?8 {8 C/ d/ P- [0 S1 c11.以下脚本输出什么?-
- <?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) M' r! x$ H0 b5 t
B.Null
5 B* i1 f( H! v! i1 R3 tC.Empty
" Q4 j/ J1 o* T" o- l% YD.什么都没有! N8 e2 M! E7 L# V5 I
E.一个错误
+ P. n x/ S8 Z' C: C4 l" _. N) O b. ^3 v8 b0 e
4 m* M; f3 m( O0 F" d
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
: Z9 R/ h$ f; U# TB.5) K* L# S4 a, d; n0 [9 Y
C.2" H+ K* \3 [$ q3 V$ X3 u' @0 ^1 Y/ o
D.Null
B( P. |% ~5 F# O; f6 F# ZE.什么都没有
7 M9 U& y* s2 t1 v& a
. G, c" Y0 i; G% ?7 b4 I: `8 O% M/ K
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
2 n5 {8 [3 w5 n2 _6 sB.10
" V1 h, f' x, @/ s5 cC.什么都没有- n3 R7 b$ C! X* \
D.构造函数将报错
# J1 L. D' F8 ?) q6 `E.510& ]# r% G; [# |# V
6 s3 T- U2 j! W" Q- M- {8 y+ L# t
. A3 Y: f/ M) y- A2 w. F' V3 y14.考虑如下一段代码,执行时,$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函数必须返回一个值' y2 N$ u; P2 T; }
B.reduce_fraction函数必须接受一个整型值8 ~5 t! k" q# y; I/ O( `
C.gcd函数有问题
2 F1 ?. m& S3 t" W" ?D.必须通过引用的方式传递$eight_tenths对象; @" i; I9 U8 m9 C/ i0 O+ l, V
E.对象的实例不能传递给方法以外的其他结构。
/ D* Y b' A! g F6 ?
7 l3 m" \% [$ }: y- M* N9 F1 k- m1 |4 P% j8 _
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法( g& c; W$ c5 Y5 Q1 F0 t" x
B.生成myclass的实例并调用mymethod方法
* p' I1 _$ L) |' A0 |; n, I; VC.产生一个语法错误
, [$ \' K: B& |D.默认myclass类最后被创建出的实例并调用mymethod()6 ]! V. c9 Y k9 e4 p O& a
E.调用名为myclass::mymethod()的函数3 Z! O1 l2 x2 S1 ]
; s S( [* |* S/ M# |6 ^
6 l5 w: x! Z4 ?8 a0 j0 D$ B16.PHP中有静态类变量吗?
5 w3 Q0 t# {2 _' n; h/ \& i, {. E- J
A.有
! [- @# K4 B+ t* ^6 OB.没有
3 W* R: x$ }7 `- @; ~ |$ d) ]! ^4 Z3 H/ ^8 H7 i, J( f
; G# M# o2 E0 ^3 Z2 S# K( N17.以下脚本输出什么?-
- <?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
4 b+ k3 V! Z! q: H: OB.2
# i y( a R6 M5 J1 b: n9 G8 }C.一个错误,因为没有定义a::$myvar
2 v- T1 }, Q- uD.一个警告,因为没有定义a::$myvar2 h4 w( U9 U* S, L! V
E.什么都没有
4 @+ C: P/ N" F, p% C; \2 N5 b5 t
/ O8 d1 H8 N, `- a1 o8 d+ [* i+ Q# u k
18.如何即时加载一个类?
F. Q; S" r1 J: H7 `' w0 x3 C" i9 I% I9 j2 x
A.使用__autoload魔术函数
. P3 ?6 G+ c' h; @B.把它们定义为forward类8 a9 s3 e/ F+ [0 p
C.实现一个特殊的错误处理手段
" p& _# v; w3 P. ?D.不可能* W/ ?! v& {/ g& C
E.用有条件限制的include来包含它们, }! e1 Q M8 m, X! q* U F
; n8 |* k# j F4 ~
/ l& `4 a: H9 J: j- `2 U
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?) O% s3 ~6 _* \9 @* P7 y6 q; o
' _. c8 s7 g T* F5 W9 G; H! r 答案:__________
9 G2 P# |( U+ }7 E+ D7 v8 m0 k2 y3 a6 Q" z( |$ ^0 j
3 \( o8 j, U$ t/ k& Y8 v: z
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called3 b$ f2 k' g+ C" D1 W
B.一个错误& P7 ]# U( q# E' R7 x
C.一个警告, Q8 S5 u' g7 s3 r
D.什么都没有( E) i: C1 d7 G' {0 U8 u) q
& Y6 j# [# P+ Z7 ?) L
. w! x' B# Y! ?* O; _2 m5 q5 ~" X: k
答案速查% W; K( V {: b9 }1 G
1.类
6 {* B# h# I- u2.BCD
% ?7 a; T7 g: T9 P' d$ h4 {3.C
0 k" I& _' ~; \. L4.C
& `: c- p8 Z1 N6 j2 n5 U5.A
m7 P1 i3 S& ]6.C
2 [0 k* s1 h3 p; Z- `7.C
+ K6 {/ k, V( U8.C
* m( \& o; h' v9.D( S- _; R1 v/ B3 X* i6 m
10.B
. I- }5 {4 c6 H2 P' Z11.D+ N: n: U2 L+ e5 _+ p) e0 M! Z A
12.B
6 y; y; n+ q: I13.A! P4 t/ ?3 e* I9 w# N4 _
14.D
! V$ ~- f* M+ k+ q" T$ {0 A15.A+ P9 [) f" O1 ?* _3 a4 }
16.B
1 ~* c8 F1 o) y- O3 K17.A
* A( O1 [' H3 Q6 [$ G18.D
. x) P+ Y2 x/ U; |0 y19.设计模式 |1 e2 S4 M6 Z& \
20.D
. X8 ^. a! h3 ~" A1 [
. k3 u: z: A+ U3 ~8 b" Z; e
# }1 I8 _1 u1 ]" k2 l. A. m4 |3 u- A
答案详解
) e- { z6 x' o' _9 J
- f A( k& T2 c( z6 V- P5 @6 V1.类是对象的蓝图(对象是类的实例)。8 P. X$ N, l" }
6 \$ F; S: G! a% H1 y
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。! e! e) I+ C: `+ U+ \! _1 Y6 Z2 E6 x. |
; j6 L1 y2 I7 \1 _2 c
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
# x# G: d, y# N/ o9 K! ]
2 X! d* ^) O8 B4.单件模式可以限制一个类被实例化的次数。4 ^4 f, M+ c/ y0 Q ^
. a" H5 E8 I$ @6 P& s5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。1 g- x1 r$ T# M/ b5 a1 I! e3 [
5 V/ Q& m& K) n
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。: d* G: L' e/ }3 U2 q" x* Z
9 B" g" i: |9 m$ O* i+ ~2 W
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
. ], J/ a1 k; u+ O. u
) ?, O C6 E8 X# P- O8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。# x' B$ Z) a* u* P5 }. N% |4 L \
5 E/ t0 y `" ~) y* X& D6 d9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
; E$ S& c3 U& |# b6 \0 E8 m6 c2 e4 @3 ]) w
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
5 l8 m" s' D/ [) j* S0 D1 p& ]$ |
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
3 H1 h/ N2 X6 [1 n. i0 }; {9 i3 F% o+ v" K$ J2 R
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
, P' L3 Q' Y+ |/ E: A4 i K/ ~$ d- t
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。! y0 b! g* [! E2 }# k% Q2 s
- S P5 p1 W" Z8 }4 w L
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。1 O( A8 j0 I, _
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:( h% W: z6 w' F: S3 d( e- G
function reduce_fraction(&$fraction)% O% t! |1 [2 B0 j
答案是D。) @& ]7 K) K: A L: f7 J6 }
4 Q1 E3 s4 s+ s+ X; e
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。
, r0 s4 k' I# s6 K0 M( M& B; `/ u# R+ ]0 L5 ^$ k% @$ _4 c6 M
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。8 _; s4 N* c1 U2 a" x$ f* |
. ?, S. b- C; e$ \6 a" @& [
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。' i* |6 x) N! O* I# H
# I& Q5 d9 p! W6 M$ T5 d4 P' O
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
: r) K9 A& G" Z
/ [0 l+ H. w' J, ~4 j( i7 o19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。. x. @* d/ H* l9 V0 ?
$ V. ^. x3 ?7 ?4 q7 A20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|