|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14389
- 金币
- 2480
- 威望
- 1647
- 贡献
- 1428
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
2 q0 R& d+ s+ f% ?8 vPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。
) d7 @; H5 l- b- j本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。9 }: k4 q$ k. r
/ r) l% \0 u3 K+ [
问题
* _0 p( U# H1 i; r, h! [9 L5 b1 O$ q6 V& t& P0 ]3 L6 C6 b. L' g0 t
1.对象的蓝图是什么?/ E- b9 ?4 i) n0 n+ j8 Q
' l5 K7 y7 X$ J" G, v
答案:____________
" G% F& V3 ?. n# S$ p F
' q7 G- G8 E: x$ k+ B
6 J6 F. K! H: C" ]- t6 R4 J( e9 e2.以下代码执行后,数组$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.c4 m! `- g) R/ z) T) s
B.b! q6 X" I; n, F5 |! [3 ]
C.a' ~3 L( N) f" i W8 w( k8 F
D.d
# J/ W" f# e, u3 m- r# i6 YE.e
. A2 l6 p3 ` Z1 t3 I% c$ b. T) ]8 E& l
; v Q* F" w$ ]1 g/ S3.如何让类中的某些方法无法在类的外部被访问?1 s) n% k/ T0 W' I6 r4 t
* q# u x! Q/ r* W
A.把类声明为private
5 t6 Y0 D% I5 T1 ?' x& K4 BB.把方法声明为private4 V& U& x7 N6 h4 a$ V8 O$ h5 ~1 E
C.无法实现0 _ M; z [( s8 T( g" Z
D.编写合适的重载方法(overloading method)% r6 u/ U1 z# Z* ?: x F: j
1 M7 F% F' T/ P. ]# }& z ^& q- V. A) p0 |
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
2 N7 }5 i: ?/ {: p, \7 M8 r2 x1 w2 |& n" B$ j
A.MVC模式. h5 x# F, p; k: t2 N* b
B.抽象工厂模式(Abstract factory)9 ?3 _# d! x" T5 n
C.单件模式(Singleton)
) G1 s0 o$ U' _ m, x% UD.代理模式(Proxy)
0 }% p" ^+ ~+ d: LE.状态模式(State)
5 B$ z g1 p, F( s" @4 _" H1 e: Y6 p) @$ a# t' J ^# w* d2 H
9 G O9 U& c. V7 [4 c1 _5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?; [7 ]( F. p1 B p) {8 N
" w0 H! W5 K* i7 q. hA.1个' T9 X* ]) l2 |3 {
B.2个$ T% x% }2 w4 S- J. y
C.取决于系统资源, T$ u& u! L ~# T
D.3个4 D; A) h" s+ z% O8 T
E.想要几个有几个 J- A: U& p! R+ ^: D4 W
" n) r; w t( v2 w/ h1 Z% U2 n" v
+ l5 v7 g: `% ?/ O! W+ |6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
4 u0 b4 f c( T8 oB.接口3 g8 V9 h1 Q4 d2 Y5 s1 V2 h, y
C.抽象方法2 E& U" e/ | \
D.Private方法! L' u% j! H3 z( ~& r6 X
E.函数重载(function overloading)
0 X! B+ g. W q( @) b- `- k; ]+ } w6 B% b! d& k- V6 `
1 g! ^$ f* D1 B% L+ ?6 d9 I! Q. Q9 t
7.假设定义了一个testclass类,它的构造函数的函数名是什么?! E' G+ g3 ?5 K% W+ \8 v
& }( y# W0 L# v: ^
A.__construct1 L. F1 C+ }$ b7 [' G
B.initialize
. z: ^/ r1 q N% g v& i AC.testclass
' F4 f% W7 i+ K% V4 BD.__testclass
0 X) K9 ]: Q4 M. c1 x3 S0 I7 ME.只有PHP5才支持构造函数; V1 \0 Z9 t; S* m: o. `3 m
9 l& l( ?! e* d$ f j% ~" {4 L, B# b* A) R0 p/ R
8.一个类如何覆盖默认的序列化机制?
* } N" E! h( L/ \! v8 k; o4 w
/ e8 @( [2 \/ u5 s' B) P; @A.使用__shutdown和__startup方法" c" B8 H" t8 X4 a
B.调用register_shutdown_function()函数
7 d+ t! S: c- Z3 PC.使用__sleep()和__wakeup()方法
6 D1 a7 R( a( j0 {# W4 [' D" sD.无法覆盖默认序列化机制4 t9 H) R2 ]+ R* C K8 P
E.使用ob_start()将类放入输出缓冲中
3 T% V* d$ f/ K2 C4 [6 a2 C( L* x# `+ L
# C$ U. ~ o$ T! W+ G- X
9.以下哪些面向对象的概念无法在PHP4中实现?% L) I- J* w- C% d' N E9 n: J& E+ Z
; ?# y \* R9 g3 v6 x& l$ M
@抽象类
' D( v7 i6 c! s6 c) j5 t@Final类 r, [7 A' Y; I$ G1 ?) R
@Public、private、protected(PPP)方法
/ S+ P; ~4 z9 _: y& B' g@接口
! U2 u. x, b0 N( d- u6 ]0 k! I& T* u( n: X( C7 N+ K9 A2 p- B3 h
A.抽象类7 u; a) |0 S! m+ s
B.PPP方法4 c3 m- t: |5 w# f3 F: z2 d
C.PPP方法和接口
$ ~2 F3 |- u: r5 _/ H* T; BD.以上所有都不可用
" Q. {3 l1 L0 k4 R5 IE.以上所有都可用
$ g- R0 g: Y; m" V$ J1 M% k* X0 l' x5 Z R) q: X
! y- `5 e; T7 S" j& p+ a8 V10.如何在类的内部调用mymethod方法?; U: x" [' }+ Z2 Z, @' p0 P
* @! u, h: h1 P& ?/ q3 dA.$self=>mymethod();
2 x7 q; b) \) s9 f& C/ S+ `8 FB.$this->mymethod();1 v3 Q9 E' l" S+ a7 N5 E
C.$current->mymethod();8 |( n% x! n( p" \5 d: [0 O
D.$this::mymethod()
" J( e2 ~$ G% o: `7 h3 E" C, ]+ c5 zE.以上都不对
; |8 x3 d; Y2 k2 B
1 ?; d7 Q# [! K& ~/ ?" ]& J% C. G! |6 R& L. r$ V- J+ @! K) e
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 e+ W; N+ v0 KB.Null
+ d. k* ?& L& P2 Z- YC.Empty! Y$ C" N5 I- e( }9 \
D.什么都没有
{8 _ D' h9 }6 V* { q6 e3 XE.一个错误8 y4 u( m2 M. c2 R! x m
' t3 G( z. r m+ v: E
. N# }. n$ J8 R5 h1 p, B8 }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
. {8 V* m3 T g9 a; n$ P: M; AB.5; ^; i' G) d2 M. I( V4 w/ k
C.2
" ~/ _8 y$ m7 l% zD.Null0 q- c! w- V: {" r, b
E.什么都没有3 v" R) I% D+ k, c; ~
6 h- O j! b! O0 G. b. Q3 o8 ?
8 v+ h! v/ B% z* n0 J- ]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
0 F: H9 ^ N/ R4 _6 O- x+ E& n& XB.10
7 e0 t3 D2 ]) l( e' UC.什么都没有
4 x( ?2 y, ^* t# `D.构造函数将报错
7 i% R, n% g% d/ v/ X4 {3 cE.510
8 R2 e& v3 O; W/ y7 W# E( U: s3 d' y S" {/ v+ |
; J! Z% K% Z0 F. K2 u14.考虑如下一段代码,执行时,$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函数必须返回一个值8 e) }7 q [/ t, K
B.reduce_fraction函数必须接受一个整型值0 x, T7 o: p: z6 S; N$ W: e
C.gcd函数有问题
4 |6 |; M$ R4 a7 Q' pD.必须通过引用的方式传递$eight_tenths对象+ Z/ h9 M7 x6 S7 a3 P2 Y$ _* _2 J- t
E.对象的实例不能传递给方法以外的其他结构。1 k- K; R' f+ i5 f! R d+ j
( r1 v- Q9 p& e+ G& ^
3 M; T: x1 f; R( x+ H% H @
15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法. S5 x& a( l( x: K5 A# n
B.生成myclass的实例并调用mymethod方法1 I9 S( S6 x. F2 i- t
C.产生一个语法错误
; _$ a% ~; n& QD.默认myclass类最后被创建出的实例并调用mymethod()
Y8 f% }( `) X+ M3 h& ME.调用名为myclass::mymethod()的函数8 _& q4 ]5 ~9 y# t5 p6 e
" c8 q# O" w$ g3 a
4 M' L, l& {# y. W) u16.PHP中有静态类变量吗?
6 v( a+ g& Q* M3 t0 v c& J8 ]0 C' d& z
A.有) H6 O, d9 x5 L+ C' S x
B.没有# ?$ o8 F A. C/ I% B' ^
W6 l8 E; D0 }
4 r, T% _$ J, Q9 H( R17.以下脚本输出什么?-
- <?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.15 g) D; ]9 t+ r. s1 z) [2 @
B.2' v$ ]) q( K& J0 T I
C.一个错误,因为没有定义a::$myvar: b3 d+ l# ] C; o& Z% G
D.一个警告,因为没有定义a::$myvar1 q- R* u8 l& g0 e5 v. l9 M" @
E.什么都没有6 P% j; d$ M1 R2 {0 _# C* [" N
1 U+ ?' G! F- [: E9 P) M2 E2 f0 ]
6 h* ~7 ^; V2 X; g k; u
18.如何即时加载一个类?! S/ {4 V8 C' r0 L% n
; s' }) ?2 D, ~4 p( P7 Q
A.使用__autoload魔术函数, ]3 b. |, q8 I" l0 ~8 A9 m# B. l
B.把它们定义为forward类2 H' X% b. H0 w# x
C.实现一个特殊的错误处理手段
, i' R# K2 S0 W! ?$ T+ \D.不可能
1 f6 }9 Y2 D5 G9 }E.用有条件限制的include来包含它们9 R- U! ]/ ? ]6 [& f
% A. Z& A* j2 I8 ]6 t
4 @& N# ]; T8 U0 I! `$ N19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?) p/ r- i- Q) n3 d, d' b# o
9 \ o7 W% [. A6 d A( | 答案:__________
- }4 v6 v m% z2 Y: |2 j0 V, c( l3 E. r# Q) U( l
8 I- ]. Z7 u& i' A, s
20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called6 u7 H5 }; T' m! }3 U0 e/ _
B.一个错误
# U4 o7 | |& R" E1 z+ F b4 P0 hC.一个警告
! Y t& i& g9 e* |D.什么都没有& O1 ^1 |' H* I/ j' z/ B9 l, ^& x
) I5 g0 a: i( g, ~
0 D* E- ? y% y$ x+ A/ _5 z. a! X# Q+ b5 q3 C% h$ s5 h; o1 _
答案速查4 j" w3 E' Z3 T+ h2 t) l
1.类
/ c5 `( a" L; n; F2.BCD4 C7 F N. q9 M9 G+ c, d' ~3 c- ^
3.C
. l4 i0 }" }/ @6 a J% g4.C
+ B0 @2 M" g4 I1 Y' i7 k: t8 m8 e5.A1 ^7 ^7 Z; i8 i7 Y9 s+ p
6.C' X' W: ]% S% [( h8 _
7.C3 g! x: Q, F) r$ v; `" g# w3 r+ n
8.C/ \" i F1 S; w* C8 {4 D1 D7 z
9.D' N6 ?0 g8 P e5 Y% I
10.B
1 H/ |$ M9 ?% s7 \, T! q11.D' w4 J/ h2 q5 w, Y
12.B2 p" G$ O& B% U: L6 U" i
13.A7 E8 H* h1 S) A* F, S& F
14.D% `; q* a* V. r j3 A/ P
15.A
1 M3 n- a8 b; }: H3 c2 T6 D9 r& S16.B
. L+ D: L% `2 o. [0 w/ H17.A! r- j3 t% ?3 i/ j
18.D
+ K$ ]% P$ @. v% q9 d& |3 R19.设计模式
' z" G+ z% V+ B20.D
1 C1 c2 f, o. B8 I- ~1 t d8 [* a5 R% g
' U7 f5 j+ G; \( v5 q
4 [! s, c* x: x1 L+ m! \( q0 O; [答案详解
1 X ^4 U# f; [
2 o: U, B# X8 N) j6 ?% Z& E8 {1.类是对象的蓝图(对象是类的实例)。
( V2 h& l) M5 C, I ], I$ ~
! E" _" L+ J" _# \; i2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
2 a. e2 c$ q5 a& Q
- _* W9 r' M) [# ^3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。1 ], n8 z, a! l5 R* P, a
8 G6 S7 ]" y X4 V/ g
4.单件模式可以限制一个类被实例化的次数。/ y. X& }# @3 ^" b5 A8 L* Y [9 D
; y9 Q! A/ @7 o8 f4 c% d
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。. V$ T4 S3 @" s$ z5 H
# b* s. Q, }& o, i6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
2 m6 M# Z; y1 Y" Q" O9 y2 r0 @: e. a4 j! C; {
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。
0 k4 ?8 n. {8 w) L/ H7 ^7 J: C K. Y# I
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。3 k% x( \9 z3 A+ D+ X/ s
6 ^+ C% B: ]4 q. h
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。: K% u9 X) I) @9 Z6 P0 B2 b8 o
@& _/ \. [0 F8 C | G
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。" F' ^( {7 T+ s- [# _( `% B
2 V# g7 D4 E$ J
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。
/ C( U |, p1 z# L2 F$ [8 o1 ~* Y; U( R# y5 S8 O+ k+ e; @' _
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。0 X& A$ i# \- r9 ^) V2 i2 C. c
5 D6 J+ j1 X' H5 F
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
. k- J; r/ x9 `' V
. q& K& ~% ]4 i9 V j Z14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。: y4 {" ^4 o. B" F7 Z
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
% Y# D1 D9 U5 v function reduce_fraction(&$fraction)- t" X; W6 o, Y4 ^+ [" |4 O* a
答案是D。
9 ~+ y) `: {' F: A" A L- B; H
- H% |+ H9 a9 m& q- t15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。; X! Q7 R# F2 I; p& ^
$ G6 e( a) e& F16.没有。PHP4只允许声明静态函数变量,没有静态类变量。4 {5 Q, g' L e) Y4 g
0 n) ^. Y4 m0 J$ m6 \6 g
17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。! m1 _- Q. [. p
; w! u u! Q; [, R/ z% ~* J18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。9 r( \: n2 I( R: S
7 F/ U# B0 f* n: M' ~19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。1 Y/ f5 f I2 p4 a: ?) b
/ Y9 `8 H" c) A" @5 S- l20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|