|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
! D5 O( b: z+ S: D. pPHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。0 U2 y; m M3 O: j4 f+ c
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。' h% [# f; C0 Z- t+ Z& j* G
$ R) n! C" a. ]; f5 L: M2 L5 M问题
% n" P6 _% g3 d q+ F: h
" k3 j7 k9 a3 j3 g7 E. d1.对象的蓝图是什么?
# B \4 d' B7 W( R6 u. g% T/ D0 y$ _
答案:____________3 V2 L7 |, B b6 D% j6 y( m
- o6 R. G1 l" _( W' Q) m- C, Z3 \9 ]2 E' {) X1 o8 v0 ~4 C2 [
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
1 d, p* _! X. Y! A3 O5 {( DB.b
: t: T: ~' y0 E* O- _" K, WC.a
) w( u# K7 M" q5 P O8 w7 iD.d
, U% x) O: X4 OE.e
$ I5 X$ k6 A+ M3 Y8 G! n/ v; H: y
' i9 b. E/ w: @7 y) ^ o& N
& ~1 Q( n" S4 Y" c: T/ V2 ~3.如何让类中的某些方法无法在类的外部被访问?8 n* f5 p' d8 a+ Z
* f9 m9 x# }. K
A.把类声明为private
, L! q; P1 m# i, fB.把方法声明为private
" L9 r& p; m* uC.无法实现" W% x) k& k. \
D.编写合适的重载方法(overloading method)
6 W' m* Z/ {" e2 E' L
! j+ `5 S+ h! p2 o) k$ P" s) }1 ?1 _! Q/ L
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?# b/ a2 W+ v) H8 Y4 N& E' Z* q
$ Z# _1 P" f* u, c' o8 t9 J. c: S
A.MVC模式7 w. ~5 C* l( m# n. l" j. i
B.抽象工厂模式(Abstract factory)
4 S8 t* X( J# B! uC.单件模式(Singleton)
2 D, N0 b3 n9 n: n" Y" b, l: l2 vD.代理模式(Proxy)
" ]- ^6 k' n0 RE.状态模式(State)
9 N7 O! J/ t% \. {. w% c4 I! x( Z# N5 x
4 p% ?! L, b! \4 Q+ K8 V% E+ e
5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?7 d/ T: P1 D7 j5 k" c! Z
/ B9 P+ a2 i/ x' o* t5 VA.1个, R7 K+ S+ e1 b8 b) ~! q) [
B.2个0 q) W% R% Y, T! |' D6 |
C.取决于系统资源& A& a1 r+ z5 ~$ d6 s; v
D.3个' S; \0 f5 r) ~5 b) ]
E.想要几个有几个
" U! g2 c. ?' K
- [0 }# t: S) s0 Z2 L6 D8 }, ~: Q: \: `& C; S7 F2 U$ i
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
; w8 s) b' ^2 g" G# ?B.接口9 F |/ x( H% F" w: k" d' U7 }: C
C.抽象方法
# F/ g. P7 C* ?D.Private方法
% ^- J$ W5 L$ g3 EE.函数重载(function overloading), [; O9 T5 q# m3 X6 K
" b' t+ n, g+ ~, F' N
3 m3 r+ P. W5 w! f- K, s% N2 K7.假设定义了一个testclass类,它的构造函数的函数名是什么?
9 E: ?/ b0 x6 ?# X4 H* i N: `
+ `9 q0 p5 D7 G/ eA.__construct; p7 |! t+ c+ O
B.initialize
2 D7 R# l2 m3 e( Q5 gC.testclass0 A. n- Q7 }7 l& h7 } @
D.__testclass
/ B/ D @( m3 ]7 T3 ~4 B% y% b8 _E.只有PHP5才支持构造函数
" d1 j1 g: a. J8 S6 K( C
' }- D2 ]! o& O) J+ _% |7 l' W/ m* }
- l% v3 j7 J0 R1 O8.一个类如何覆盖默认的序列化机制?8 e/ U8 U" H# N m9 m9 P
) e- g/ Y5 s C& l) OA.使用__shutdown和__startup方法
- b8 F7 t2 c3 U( g PB.调用register_shutdown_function()函数, U3 D8 f& K0 C" X- y8 o
C.使用__sleep()和__wakeup()方法
; L9 s/ g+ O9 s% u4 aD.无法覆盖默认序列化机制* N+ V1 M9 }/ l0 d0 W& n+ J
E.使用ob_start()将类放入输出缓冲中
4 |% B0 y: T+ t+ F9 h
+ d7 V8 T2 Y _) T. ?# h
. u7 a6 H2 G, {+ D% V# p% W* W9.以下哪些面向对象的概念无法在PHP4中实现?3 Y8 e$ J( V) l6 B7 v
( v1 H g9 T8 j( m0 l) q& N
@抽象类- F- E) v, M1 C# X
@Final类
0 s7 l+ T- {: E' w" |$ F@Public、private、protected(PPP)方法
/ @2 N8 ^8 Z# B6 x& o8 ~@接口
6 ]# H6 Q5 o* O' a* N- I% c* |( K6 l/ ~, X# V! E$ k8 {- h
A.抽象类
- A1 b' i3 N3 e) @+ e, _B.PPP方法2 E3 r1 k( ~* }( j
C.PPP方法和接口
& u6 |) A' u }8 qD.以上所有都不可用3 E+ F5 H; i! N+ e* N
E.以上所有都可用) E/ b' p4 T; D8 y% U. ?
7 ] r& J2 n6 i
, g* X/ B) H! `: A) }6 S2 g2 @10.如何在类的内部调用mymethod方法?( w" q' ?5 @- {) o* d. K
/ d- R# t' {( j, L" _: e7 ZA.$self=>mymethod();$ |8 g" ]2 r0 J4 f; t
B.$this->mymethod();
& j2 G5 C/ _5 N; l1 e% MC.$current->mymethod();
" o, ~6 N/ ?0 D4 ]D.$this::mymethod()# {8 C& k/ q8 I- y
E.以上都不对
0 s6 B% A9 P7 H; i8 ~
$ U0 K9 S3 c- _2 k
/ p T& J S( d6 B5 B+ F11.以下脚本输出什么?-
- <?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
$ n8 z# b9 l1 w, v. u1 jB.Null E7 j3 _ J) F7 z% o0 f
C.Empty' h: U: j9 X2 D4 k5 D* T- l
D.什么都没有
]1 C% G% d2 @; [+ ~E.一个错误
0 i; y5 R: V9 f) I+ z
^8 ]# `7 u+ {$ o$ b9 X7 |9 k' H E! k1 n- H1 I
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+ c. I. \- C! C: L2 J# n! @
B.54 m/ u! P! g0 j* d- u5 y- G
C.2' B4 R; L% Q Y
D.Null3 {8 R9 F7 g* c! S8 I: H* n( Y
E.什么都没有
0 n7 j$ @0 u! ], A- M% Q4 [4 S4 S) ]- S6 |# @6 `
+ k, \8 t$ g. ~6 ^& Y
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
6 M0 U8 B, p6 ~8 P6 o a+ Y/ ZB.10) T2 x% I1 {; Z- Z0 b
C.什么都没有
4 B# h3 P% c- M+ t( f' P! lD.构造函数将报错
, m3 A2 u- j# G5 vE.510
( D; j4 @- J0 d' @6 y% t; r# e
+ U- B2 F* h" P- ?3 C4 G, n% O2 k ]/ Y
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函数必须返回一个值
. ?) R: B1 C- V0 v( I7 m e, RB.reduce_fraction函数必须接受一个整型值
$ S& u9 Y7 [+ q" v; E6 q8 S6 YC.gcd函数有问题
7 [9 N: E+ r' V! P, A$ k; ND.必须通过引用的方式传递$eight_tenths对象. B7 b/ Z$ t7 A, b7 Z3 o/ `! T4 X E
E.对象的实例不能传递给方法以外的其他结构。
X Z' j& ]) }+ ^+ G
9 H* r: Y4 u( ^+ M# ^. d4 A* R
% K/ g2 m2 E& y/ n5 `- W5 ^15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
& ~( O; C1 P: ]9 J" P1 ^# w& {3 yB.生成myclass的实例并调用mymethod方法
w" j' ~; E3 ~# MC.产生一个语法错误
. { e* A. C4 Z" x( `3 GD.默认myclass类最后被创建出的实例并调用mymethod()
; F: S$ H* x8 G6 R1 j" n# NE.调用名为myclass::mymethod()的函数7 S8 G& i" f9 f8 e
; l# D A0 C4 F* g! \+ B1 P
G# }' E" h* r0 X# m2 Z16.PHP中有静态类变量吗?( g8 O0 ]2 V/ u$ M( p7 L
- l7 k4 T/ `# U6 O' ]
A.有# ^/ |6 J V/ {: D/ p* [9 U% f
B.没有$ r% Y+ }* i4 G# N l- J
N; Z: s% e3 `0 q0 F* k, ^6 c9 `5 K3 @
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
8 x3 T( ^% A. p" F; jB.2
# ?2 m0 `6 Q" a3 d: p/ R, FC.一个错误,因为没有定义a::$myvar& C( z. ]$ u3 ` h. D' ]
D.一个警告,因为没有定义a::$myvar9 `8 `6 q3 `7 m8 q1 S* y
E.什么都没有
2 _% ]6 T) g( w) _& x: p7 ~
" o4 h/ |: Q! d2 F- c- p8 H7 K2 G8 I0 t0 y5 a* E
18.如何即时加载一个类?0 C: C* u( h' x# P
& a& T0 S) D$ u
A.使用__autoload魔术函数, z+ T; Z$ e Q' D1 W
B.把它们定义为forward类
, \7 |, E4 H6 e2 ]C.实现一个特殊的错误处理手段
% H* T- H& E% r( O; PD.不可能
! m/ F3 R, _3 e( h |, r" Y% KE.用有条件限制的include来包含它们3 Y0 D8 n9 o* {$ Z0 I8 o8 ?
`9 L; e9 q2 r
" x6 I6 Y. n9 l. r# n; K& Q# S
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?
, P: |: h; Q6 a% ?+ P% ]
1 q1 Z) i# i% v$ N6 ^ 答案:__________
, k1 F" b% x4 ]* R% H4 i$ s4 ]* j( O0 W" G0 k1 i
0 d9 t: A' R' `# Y20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called6 V; f a" `6 h! z" d: l
B.一个错误
* I7 a1 `* s% gC.一个警告( W! L& a! ~& D! y
D.什么都没有# q; l+ ?9 p$ H1 d
) \( z Q! }9 ]+ ~) d# M( w( u9 t- H7 L. @( L5 o. L
; r, b7 J1 n; R1 b+ K4 F
答案速查- S$ r) y- ~6 n G# H- m+ R0 {
1.类 x5 l: W4 |; q. g8 o
2.BCD, s/ a) h9 i0 S. Y
3.C
- \3 C5 m0 U0 e5 ]9 e& \9 Y4.C \5 m' U# Q& u( R, ~1 \+ d
5.A
) G$ `1 d0 d; N; `# v# `6.C
! W e0 _9 o; A3 q/ h7.C a1 c! t& O$ w$ I2 G# Y
8.C
7 b3 h- z* y, n5 U9.D2 B+ T! A2 o9 o* C6 I0 P b8 ~
10.B
: P, a7 a4 a% Z: z# \* T11.D
9 Z+ \2 }2 ~: q+ I. `& d12.B
: _$ Z# U7 N9 C. L13.A
% s6 s- I- E# _14.D6 j( E" L' h* a# b. r2 o! j A- T
15.A
: {/ H* P: \$ G16.B+ r5 a, Z0 O; q& W8 q
17.A' \1 M. I8 f( K8 ~6 D' e
18.D% i$ ^( q* r, C$ @* v4 h
19.设计模式
0 c& A# ^% p$ J3 b6 J) ?& B20.D( T7 C+ P+ I& x' ^7 \
4 H# P N$ ^0 j& |; k! v
: Z( E; W$ _+ n+ D2 ?, ]+ h; e
答案详解3 q9 |2 H# t$ s7 h, m
0 ]) ` z, O( g9 E, b& v4 Q1.类是对象的蓝图(对象是类的实例)。2 F: u6 A* w' f' ]; Y* ^% E
8 m. |: y: ~. ]' |; L R7 P: }2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。6 d# D, W$ q% \- ` G
# T- X5 e$ a& z4 u2 l* N2 [- A
3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。) u z- V0 L. I! O7 F- U
; M5 S# j5 `( A: P* D* R# a3 Q4.单件模式可以限制一个类被实例化的次数。/ ~( [4 I l4 y5 l3 p
$ j% l) } D- Q
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。2 x N6 r `% _ a+ O) b: G; ^
* p4 f7 `8 |1 m0 i" C6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。8 |" h; W7 G/ [: F* r8 l
, c" G* i6 b* S3 w7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。, ~- p( I) v) T. q/ h/ d
0 Z# B$ i6 d# ] b8 n1 \+ d7 t( K8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
# m5 U( y: w' |: X2 _( J: D5 o7 d/ Q7 u
9.PHP4中没有题目选项里所列的任何一个概念。答案是D。8 e5 O( P8 d+ }( C7 c
7 L5 v$ w2 _% e: x10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。
, m4 _& C" r& i3 g9 ^
) }- k, J0 G2 G% e& {11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。- K. H+ ~, A' W- ]6 Y/ w7 S3 t/ B
% G: ~. L0 d/ m
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
7 [( w+ O6 }& H4 P$ c8 E H2 @1 U& L' T& Y- [& `7 Y
13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
5 s8 e d0 U2 D4 M" K5 l% Q( e6 K8 U7 ^% \5 @' a! b0 V
14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。2 ^3 b0 }& h# }5 j' ?0 T
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:
8 r- [5 U- O3 |" j function reduce_fraction(&$fraction)
" p4 ?/ S2 A1 b7 ^% E( M2 @! s) k" e答案是D。
M7 @, U; K+ x) g8 P, a' I1 l4 F% B; z" q/ R' Q0 f8 v7 B5 z6 L
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。+ @4 O3 a& T+ v% g
+ d- E8 d1 @/ A8 B0 n7 e* W
16.没有。PHP4只允许声明静态函数变量,没有静态类变量。
: M m1 O' ]. H a7 l3 Y2 x
, X) i: O; o9 D17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。( g1 ]4 B+ {5 p( O
/ w6 I6 ~4 d- _8 k! ^ V
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。
0 h1 }: v, h/ h0 T. b) ?& Z
* j# r: Q& }+ @' ]. ~3 ?9 y19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
: D$ r5 ^2 W: L: G
+ c( _% D7 p) \* Q+ V* {5 q20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|