|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。! r, l) V. p. [+ }2 f8 `
PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。6 z9 H" F `' M3 o
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。3 q/ z( n9 t# t1 b: D2 G( D
0 N, H3 E5 c" z
问题) P) @1 D, c0 t5 u% l
+ t" e& ]# \4 b! D0 z
1.对象的蓝图是什么?% [0 } Y1 U6 M/ c) X P- [
5 _: _4 k: c: t* A, B3 ~" g
答案:____________
1 X7 Z7 j( m% M* x+ g( P) f7 G! y7 O- i2 o/ T
7 p/ v( e5 m- X$ C. K/ ?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
" o7 g% K: T% P9 f* x. H$ KB.b2 ?% W$ J v2 u
C.a
$ @4 `! q9 J! }D.d
- E% \9 h$ z* D, i" U% ?E.e
[2 |2 `8 ~( U$ M* z" O. n- a: v- H# u# W" Z4 R0 J8 W
8 p! S8 {. C$ z8 }3.如何让类中的某些方法无法在类的外部被访问?% @ G( I: d% L' y' b
0 N, y- R' R( D d: G h! m" m0 ]A.把类声明为private& g: R: P; K8 K" k
B.把方法声明为private9 {) @" K- O) f- ~9 @8 i5 ]/ a
C.无法实现3 A9 V9 L7 b7 D& {" n0 H) g' I
D.编写合适的重载方法(overloading method)) O! A0 \* m. b4 j2 b
* U$ _, A& t; d5 y# S$ |2 O4 I2 }* O
$ p, K! ~5 X3 p2 K1 f4.哪种OOP设计模式能让类在整个脚本里只实例化一次?
& R' \8 }& X7 G5 W1 g: n' u
6 \1 k( u8 c3 ~( _6 Y% c9 A6 MA.MVC模式# h7 v3 a. d1 e9 s! z# ]5 H8 n3 _, e
B.抽象工厂模式(Abstract factory)$ L) E; ^! h( K
C.单件模式(Singleton)" h$ p# K( r" Z/ r7 m$ @8 G
D.代理模式(Proxy)
, B! u& c- c1 i# O6 Q0 kE.状态模式(State)# [8 e1 W. `% r% l4 i# k( L
& ^1 G& b3 y' g4 t
, m3 b. O. q k6 g5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?3 `7 Z: u8 C$ F S8 e
9 P8 M6 \5 K% ^) i5 Z+ u2 JA.1个
( I) X" g; V2 ~B.2个0 t! @! t* J; g3 A$ A! g! c" r5 E+ |
C.取决于系统资源: [4 T# H( P. z: s% f2 m7 M, X J
D.3个
7 m" `! u9 f" e3 |E.想要几个有几个
, e+ o0 y- b4 E4 c2 T& M; j5 T9 z+ T3 S0 T5 a/ k6 A
5 b+ \( Q6 L: k& S2 @ K7 G
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
' D ~- }) p" c8 p% i# {8 oB.接口
. ]% S$ f$ B+ ?2 r* t% v5 @+ Y3 {C.抽象方法1 z$ m& \) O H# B5 C+ f
D.Private方法, J8 A) o# C! A) w
E.函数重载(function overloading)0 C+ c/ l3 O6 Y' O9 ?
- D/ q5 [3 Q l2 _9 Y+ [0 t+ H
4 ?2 @# | V9 o
7.假设定义了一个testclass类,它的构造函数的函数名是什么?
% F7 a& L$ X! f4 M; W x/ C P4 L; S$ R5 L1 E" ]" E2 Y9 {( Z
A.__construct
- m4 L- k$ b( G6 e# x3 r- eB.initialize
: V/ K. }1 |, G* tC.testclass
9 n! K+ a1 w8 oD.__testclass: @( r5 ] u" `7 W
E.只有PHP5才支持构造函数7 o2 x2 ~7 _# F* c! P2 y
, i T1 P2 Y& C* \5 P _, v
" x& I) x% A1 T7 D- V2 f( }1 |% m8.一个类如何覆盖默认的序列化机制?* |1 ^" N$ W9 D8 O" y' C$ Y% U6 v; h
( @6 f$ ?5 W3 Y9 ~ |' o* IA.使用__shutdown和__startup方法
; v# i9 N4 L1 o3 o& E" h4 RB.调用register_shutdown_function()函数
# ]9 `3 |( j4 v( c5 u* V* ]' i' {C.使用__sleep()和__wakeup()方法% h5 t5 t3 O! S( a
D.无法覆盖默认序列化机制0 U" p) w b5 J8 @- v
E.使用ob_start()将类放入输出缓冲中# J0 E% d1 g9 s, [3 s4 q/ d
0 P- |! s: S/ b0 U
3 W E$ z! @; v5 Y8 d0 |
9.以下哪些面向对象的概念无法在PHP4中实现?1 C& H3 y: l3 Y9 Y9 d$ C$ W
+ x$ a" v; X+ `) H8 r
@抽象类
9 u8 D2 f+ h; d" S7 G+ d@Final类
5 w/ A% L Q n; c' L! M8 G@Public、private、protected(PPP)方法
2 c* o9 y9 E4 p6 K& m5 w [@接口3 a) r" w7 s- m
" e' k$ g( g1 s7 [- nA.抽象类
% n- Y6 \! B% s' o! z- r2 \B.PPP方法
; m c/ Q# J8 Z y( a" I/ }C.PPP方法和接口' b o9 @( S/ U1 Y7 u
D.以上所有都不可用* ]/ D9 f2 V% P7 J0 g, [
E.以上所有都可用/ |1 G, W6 h8 P, w: o
9 d2 b8 r6 T7 g4 v; h' X$ Y1 w4 R# p8 A I: n2 Z
10.如何在类的内部调用mymethod方法?. L9 H2 c. Z7 T/ P
@5 O+ z# _( q) _A.$self=>mymethod();3 ^. t% V% h( @5 l8 n" z
B.$this->mymethod();
$ ^( P% ^7 V5 q- ^: W; b* Y+ [) NC.$current->mymethod();
$ F+ S6 b) D. s) N& j p# z! d- }D.$this::mymethod()1 u. p5 j9 [) ?3 ~$ w c
E.以上都不对
# e2 B; u$ a3 ]0 u# l/ j( W% E7 P
5 C, e3 {' @4 g: T
. r R/ e. o+ z$ O/ h+ @; G3 R: h11.以下脚本输出什么?-
- <?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
* r7 t7 z4 e* x; s: mB.Null5 P. _7 Q9 b- T- m3 ]* I* T8 d
C.Empty, O4 o/ e4 t7 f g/ ?
D.什么都没有
& s2 m3 Z9 r" fE.一个错误8 R2 k0 b7 O; a
# ~# L$ y& ]! G- m0 C4 O" U: j* _; z; ^. [
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
1 Y- U/ }4 w6 `7 R$ LB.5* a& A2 G% h; `
C.2
& f4 Z# d, i \! UD.Null
# r, \$ ]2 p$ J/ ? N2 u! S6 |E.什么都没有
* b4 z" z2 O& O3 V2 ~1 K- I) m
7 G# B: F! p2 w, @: H9 I' A/ ~: S
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 h0 u1 o2 P( Z4 G" JB.10
3 q* i: c! E. p. ?6 P+ qC.什么都没有
" j/ P; P( h& |+ a7 W; ND.构造函数将报错
1 t# W3 y- Z; o/ b4 eE.510* A# a2 e% f) o9 W: \- C1 j
& k5 s4 D' J: B2 `
! `7 ~2 J6 e- l14.考虑如下一段代码,执行时,$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函数必须返回一个值9 Z3 ^4 g7 h! e c. ^
B.reduce_fraction函数必须接受一个整型值
9 X4 Y1 ?8 n0 w. jC.gcd函数有问题
+ f( i& A4 L2 \: J i# N# ^D.必须通过引用的方式传递$eight_tenths对象. N# k: R5 a" t' B# `
E.对象的实例不能传递给方法以外的其他结构。
. ~5 T3 \; t) @; m: Y- K: F5 X1 o& H7 f, V$ k$ C! j1 q
4 v: l; f% U% K* v( t15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法/ z* x. I& V1 r& {8 Q
B.生成myclass的实例并调用mymethod方法; z0 `1 S" L& H
C.产生一个语法错误5 M# E9 ]/ v& H/ {7 ^# g
D.默认myclass类最后被创建出的实例并调用mymethod()
* {% G. a p# K- W/ [E.调用名为myclass::mymethod()的函数
' y+ D/ I1 ~: h6 \+ h
7 S; [! `0 V4 T
0 c2 M3 ?- w; J& U16.PHP中有静态类变量吗?
& Z K3 X1 `/ {- ?' V$ x" t: q: W! l( C$ \2 G/ C
A.有
/ a' D! W" f4 K8 X% P# N$ EB.没有' {6 s. B# U. a1 U
2 n4 k1 e! |% z7 k
6 m: X8 ?4 [5 c _' `1 n3 z5 G17.以下脚本输出什么?-
- <?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
" S/ Z( \/ S7 Y! ~8 t2 yB.2
4 I" D: H$ b" f( MC.一个错误,因为没有定义a::$myvar5 [& i' M. D% A
D.一个警告,因为没有定义a::$myvar
: _/ X+ _1 R, H Q2 }. kE.什么都没有
2 p" ~/ i; {& e3 p5 R. V
`5 w, f, ]0 q( q. e- X4 R
' Z! B) R' z* N M# _9 s" ]18.如何即时加载一个类?5 b) T6 ]2 ?& u* q1 H) z4 O
/ K& K+ d( c+ A, G; uA.使用__autoload魔术函数
% G: y7 F- `% b7 zB.把它们定义为forward类( l, j0 v3 z+ J' r' x5 a
C.实现一个特殊的错误处理手段
& L2 K. `7 a) |7 F& PD.不可能7 \! j: [' E* [
E.用有条件限制的include来包含它们* e$ }- Z" K& e7 U) c
, R* Z- R# v- d9 {0 I
0 X6 Y8 ?" w6 O$ }; m5 I
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?1 C2 T+ S& |9 N# Y- k/ m
0 y' i$ O K9 b9 U# n 答案:__________
: }/ ^/ I9 g& w- `+ ]3 p3 z$ Q( T
% E& ?* p) `$ k+ E2 j$ {20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called) p6 P; }1 b9 t3 ]" E
B.一个错误4 A0 N) g" B( T' S9 e
C.一个警告
2 P! w/ U7 F; O* t3 }) x; X2 J3 y: KD.什么都没有
! f, z* W, `* S! n; q1 [+ ~/ r# M& _9 P" q/ n" y, ~# [' u
, ^+ a& v* ?1 I$ j
2 c4 v, r; i/ w5 y/ s; y8 s
答案速查+ N2 e. I' {6 I
1.类
. B# K9 z [; [/ ]2 T2.BCD5 }* Q' y' a& D& f
3.C
. I4 b5 n, `6 T( h: ~* u% G: h9 X6 v1 g4.C
& ?+ Q) f0 a) m- W5 I! l5.A
7 R& u; }+ q' z6.C
1 F7 c: R" R& u1 `) E" [* c( r7.C2 p+ V# r: z% [6 b
8.C- S) B' q7 W( w' d& V
9.D
* e- W& P, p+ u& J4 k5 z10.B* A) ?( U& K0 u% @
11.D
: Q a" C3 d3 s/ t$ G! [4 s. W12.B" v# F6 U7 ` T8 J; f3 h' p- x
13.A. U+ E7 q# ~8 ~6 s
14.D) r; y2 m5 \" @8 A- K
15.A
2 H# G5 `+ \$ L" B% g16.B3 m# A4 \4 i5 {. }, x/ l e) x- B$ l
17.A
9 [0 \. M0 }) {$ w" @18.D
$ ?. H) Q/ E4 y* ^+ P19.设计模式
6 C8 A3 i8 p# V20.D% @* ^) M/ s3 w
& M0 u0 k- o6 \/ n1 u
- O7 p9 M3 P2 a+ i/ Q0 m0 {
$ W. p& x. H% p- b& f答案详解
3 D2 ~4 E k" {& l5 U4 B/ z$ \0 e
9 x7 K+ ?& V1 R+ M6 J+ ?1.类是对象的蓝图(对象是类的实例)。% S; u r7 g/ ]* Z: E' g
! n: W% }1 i" l: k/ u8 j) v
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
F) U6 s6 Y! \6 b, L) ]
+ |- E7 S3 q* E$ k2 {9 b3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。
$ ]2 v: O9 F% M: D' {0 X7 `
& ^6 V( C4 R/ {4.单件模式可以限制一个类被实例化的次数。
9 D4 |" Y G1 ?& _
3 r9 d; |4 m" E% M. s' d3 N6 @5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
9 d/ S1 F, B5 w( g6 N* c! X
# H1 a2 ~% }- P4 M1 G# \4 s6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
: o/ O+ f# S" L m, N. l
9 B% ?' X6 m7 T. O$ H) E7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。: _6 V% s( V$ A' N
, a, W% ]* \" L2 @8 }
8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
) b; E/ N& W3 x) c5 r9 k$ w. g! }# E, D& S7 m% {* q; g' M
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。
1 U% Z* g! A0 |0 ?
) g& T: d, I6 s4 \6 M10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。# N5 h6 s D j: S5 ?
( ]7 J8 \, S' Y4 [1 E. W
11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。+ ?) @6 K0 ~) z* z+ a& a
$ P: P. y. u g% h' v- W
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。- ?) S* c5 U8 c' z# a, R9 d9 f
|8 v3 W/ Q' j1 [2 K. [13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。4 g! T, t/ X. T$ o p: W2 q
7 L9 w! t1 W8 M, {' A: X2 a6 ?" F14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。4 C% z7 s% q" }1 L. h- u4 r8 m
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:$ M, J0 ]7 ^7 k( U: b/ `
function reduce_fraction(&$fraction)
4 ~9 }7 P3 }& f; W8 p1 g答案是D。
0 C/ Y/ Q5 o0 ^ e3 ?7 c; a* v) ~% |4 t/ k# R
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。, C8 [( l c* Q0 x. D! a3 P
/ d y) b; Z7 F4 v5 K5 ?16.没有。PHP4只允许声明静态函数变量,没有静态类变量。8 Y" p3 {; h/ [( y/ Q
, G! J' P# ?+ J0 u17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。5 O" p T5 S/ p( J. C7 Z f" Z. C8 U
" D7 K0 f2 e# d4 F* X
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
6 k( {8 m8 K, @# V! w5 k# `, J$ a$ ?
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。$ q: o5 {6 f: j3 f0 `1 \
% t+ l" r, e1 T. q
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|