|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第二章-用PHP4进行面向对象编程
尽管PHP4的OOP性能不强,但它还是能够被用来构建可行的面向对象的代码结构——只要你知道对象模型的缺陷,并且小心的处理它们。
6 x$ c( b& V3 ^PHP5在对象的处理方面做了很多改变,你或许会因此更倾向于完全忽略PHP4。但事实上,许多用OOP的程序员从很早以前就开始用老版本的PHP编写软件了。所以,大量的OOP代码早已存在,甚至在人们跳到PHP5上进行开发之前。* |: \- q* J9 r" {# `1 S3 V# M
本章不仅考察你对面向对象知识的总体掌握,还包括对PHP4特有的OOP实现机制的认识。
4 t, P2 e7 v7 D7 E
- r' o% X' P! Q' r问题
! g* W1 m+ d* G. H3 `/ a; l' `3 i% g7 w3 Y: b1 o
1.对象的蓝图是什么?6 V8 R& S6 y, t7 O0 e/ W9 o: w
8 ]$ K0 [8 B" E& j% R4 d
答案:____________
. |) ~3 v: x. J% x1 ]+ f6 B( D7 H/ a& T$ `* @, F/ n
5 o: H3 v% G+ D
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* W6 e) Y/ P6 V/ s/ y
B.b
$ N/ { I) G+ J" k. z; TC.a- J/ `9 I$ Z4 @( c# U4 r8 l
D.d
% Q% A4 B4 \/ ^E.e
c Z: S- C2 J0 d- c9 K" r: q. W8 p6 U# v8 q( v& V: E
* m- V# E0 x- g9 l( q l f
3.如何让类中的某些方法无法在类的外部被访问?/ w% D) l5 V/ \, G
) j. |/ b- O" Q( i2 L
A.把类声明为private" k o- o: Z( t& P- [' y. L* N
B.把方法声明为private
+ H9 E: i1 ?- Q0 P, A% sC.无法实现
+ {+ A5 b B( U5 K5 D8 f, OD.编写合适的重载方法(overloading method)" R" d s) T4 s6 L) z
) @1 x! n0 @; P+ G0 `3 G0 i7 G
7 z# p# a: V- Z- ^" {; g* r+ y
4.哪种OOP设计模式能让类在整个脚本里只实例化一次?6 }) N, o4 x! L! H; S/ q; e) N5 M
( n) U& o; Q% W& X
A.MVC模式9 B7 P- k. I8 j% H: B4 X- ?
B.抽象工厂模式(Abstract factory)
; S7 I% T$ @$ Z* b" B1 }) q* JC.单件模式(Singleton)5 G: d, N, z7 D8 s# ` h- C3 L
D.代理模式(Proxy)
( n1 ^: j- b6 w. H; \8 `E.状态模式(State)" e! O9 j2 C6 T# `$ @
9 X! n& X( j0 I; @* c4 e' K1 s% r
3 s. t, Z5 S: b" y7 B9 C5.借助继承,我们可以创建其他类的派生类。那么在PHP中,子类最多可以继承几个父类?
+ d; z* ?* v4 @9 o# F3 ?5 e; i2 S1 w; p8 l+ k$ `
A.1个0 G7 @1 M* }# R% O- R ]* ^$ u
B.2个
6 l* f$ Q, S% e* r- cC.取决于系统资源
4 T6 L% V& ]. l0 ?& v( X7 X# TD.3个
& L) P# A3 h. D, \8 n+ FE.想要几个有几个0 W2 \! V: E4 ^* H1 p
+ W+ O+ c3 o& u7 R
5 |" D8 {3 P9 \$ D5 A6 h8 _4 s* L
6.以下脚本近似的表示了一种在PHP4中无法实现的特性,请问这个特性叫什么?-
- <?php
- class my_class
- {
- function my_funct ($my_param)
- {
- user_error ("Please define me", E_ERROR);
- }
- function b()
- {
- return 10;
- }
- }
- ?>
复制代码 A.多重继承
" L; e+ P' Y2 I ]# d- f+ ~8 hB.接口
% p, i6 c; |0 ]/ oC.抽象方法
- x4 _3 L) N; J) ?; @: }; XD.Private方法. u2 S. Q4 Q' q: l
E.函数重载(function overloading)
+ V" v1 K" C7 \; |# B7 |7 Z
% I% ^9 @5 Z+ B$ y/ g
& h* m- s9 |! q* @) x2 x, W7.假设定义了一个testclass类,它的构造函数的函数名是什么? \6 _ R" a3 D
( d0 s+ f! W- r3 p1 y- wA.__construct
% q2 T! i* X+ a9 pB.initialize3 Q; L" C+ u; }
C.testclass1 ~7 v* m* ^+ l1 C' @/ X% ?& Q
D.__testclass
y# O: g, J4 ?# d' K+ ]( a( ]8 e* ~( s. @E.只有PHP5才支持构造函数6 U2 P6 E* d3 W0 }2 I6 Z; }1 T
& z- @* K- `2 J) R, J& O9 h
% A; }& M( @! u1 Q$ E
8.一个类如何覆盖默认的序列化机制? T2 ~2 T( U3 m5 i! S. s
, k8 u8 V( v% g4 `4 x
A.使用__shutdown和__startup方法7 z. h9 P" D% O# s2 T& r
B.调用register_shutdown_function()函数+ g; a- z# A1 `! O0 ?* g7 I0 X
C.使用__sleep()和__wakeup()方法
7 q3 W9 s, y% R% ^& A O/ Q7 MD.无法覆盖默认序列化机制6 q5 `; T$ w# X R
E.使用ob_start()将类放入输出缓冲中
8 ]- S' j6 @# r" b5 B! p7 x8 d3 `8 h8 l$ |
& o% V3 }! }# F! C
9.以下哪些面向对象的概念无法在PHP4中实现?
8 p1 w5 a+ d4 p9 A z6 ^: ~" {" m v4 D9 D8 p) E' _8 O3 C
@抽象类
4 [& j5 R* L4 ]( b) t@Final类
- d6 N3 G4 Q- h- `7 F@Public、private、protected(PPP)方法
1 ~6 Y! w+ { \+ }5 ^@接口7 N7 N p( j: f% r, ^
! g' I7 h6 O; |; t# m9 U' FA.抽象类1 @+ P) i' }. h% q7 {
B.PPP方法
j; d4 d& v2 I) XC.PPP方法和接口$ e9 }$ {5 k$ ~5 B$ X; A6 c+ O
D.以上所有都不可用
+ [0 j0 N; W! i# x, U. Z; kE.以上所有都可用3 g- z" @3 X& y
: _! K3 c: Z7 m+ Z3 r* P
& P1 i+ i4 `3 U% O: |; d10.如何在类的内部调用mymethod方法?
- y6 A8 \$ o9 V8 ]* d5 o
5 X7 y H: H7 s8 ^" bA.$self=>mymethod();
( |! P. S) o5 G/ {! J4 f iB.$this->mymethod();
) [6 |! }2 C( ^1 v3 h" N/ fC.$current->mymethod();
( p% Y' v# }# ~8 E7 X: ~) _7 Y3 LD.$this::mymethod(); F5 u$ [0 a. J
E.以上都不对6 h* y5 E. M, H
2 @2 G% x" h: l1 C+ i3 b, a2 ]1 N1 L* u* s+ W/ a
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
5 Y. T% J4 Q/ t$ e( n2 rB.Null
& p( w" ]- A D6 J& KC.Empty5 S$ ~6 N4 p# H* }- T/ C
D.什么都没有5 m: M, w& I) }! R6 Y. C5 [
E.一个错误5 [3 V1 h# S3 t7 w8 D
C! x8 S1 x3 {$ M
8 E- U; s0 k3 N( i& C2 P12.以下脚本输出什么?-
- <?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 l2 \, G" Z0 G( x9 Y
B.5' `, s- ~7 j/ F$ B7 e
C.2. v0 r- \6 Q7 E; T2 R
D.Null
r3 W2 M) K8 k4 C, ~: [' `3 rE.什么都没有
7 Y- k$ p3 N- W1 t" [
/ U4 E$ ?! V9 w9 h
2 l) p4 A/ m4 m" p- h7 K13.以下脚本输出什么?-
- <?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; y/ r, \- d; G1 l
B.101 @3 _: U% o, \7 @
C.什么都没有
: _% L7 c. n8 j& m4 n; t2 B( b) sD.构造函数将报错
4 k4 C R$ @: w+ Q% bE.510
$ }' ^4 c' s0 d% V: g7 @7 a/ j7 _& b! x r& i
P8 `0 Q. W" Z9 f) x
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函数必须返回一个值! X# T7 j: k! c. m$ r+ |" T. @
B.reduce_fraction函数必须接受一个整型值
+ P4 t$ Z5 H- n! D5 M* D4 AC.gcd函数有问题
5 ^" N! U3 v3 Y. P! {2 W) Q+ ]' XD.必须通过引用的方式传递$eight_tenths对象 F/ H6 e8 @6 v& q
E.对象的实例不能传递给方法以外的其他结构。
, N1 {/ p% n1 L9 M2 K7 p
) s( N. O7 ?( E/ b
6 _' _. {4 V4 v9 W/ m15.以下代码是做什么的?-
- <?php
- require_once("myclass.php");
- myclass::mymethod();
- ?>
复制代码 A.静态调用mymethod方法
" F7 a% B* u j( z9 V* q/ \( X9 @B.生成myclass的实例并调用mymethod方法
* k1 R& Z8 @/ C$ AC.产生一个语法错误
6 z' F% T2 D( q* M( g; b7 ]D.默认myclass类最后被创建出的实例并调用mymethod()
5 g. n; u1 V/ {7 n+ N8 M9 ?E.调用名为myclass::mymethod()的函数% m* z" _- ~6 `* F* ]1 E7 _
7 P$ u3 o2 J2 K; S9 p" D
1 g- X+ X2 a& \! m16.PHP中有静态类变量吗?! i1 n! J2 q6 k2 E
& e# c1 @3 O( j; Q
A.有
! G( w: y3 i2 X2 gB.没有
0 X; ^4 C, E5 u% z* k& O/ B! z; y8 F' F* h1 l+ K8 e* c
6 L5 |$ \, ^3 ~: s6 m17.以下脚本输出什么?-
- <?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.14 w! H' c( C, R, V; Z+ b
B.2) {7 I4 F* \9 B' g
C.一个错误,因为没有定义a::$myvar. E- Y" y! q7 B" E' Z. ^
D.一个警告,因为没有定义a::$myvar
, r) A* D) B. iE.什么都没有. i( M: y y" m1 d
2 [$ Y l5 B- u4 N2 N! i1 ]8 e* b+ k- u ?" S8 q* O
18.如何即时加载一个类?9 T P) |7 r5 r0 o2 C2 h
9 R0 Y, U- @# g# p3 u
A.使用__autoload魔术函数
% p H, O4 A2 ?* @B.把它们定义为forward类) |% v* S M' z8 q+ @* Y5 C3 F
C.实现一个特殊的错误处理手段
* z" j. p# S7 [8 K, t( zD.不可能
' y0 x4 |7 q* u# ]5 Y- a# I6 YE.用有条件限制的include来包含它们, @' T5 _$ e- Z! l! f. a- r7 ?
) J, ?! f1 T- n* X4 T
" @: |7 F3 ~) t, A B- D- @ |# X
19.__________提供了一个高性能的解决面向对象中重复出现的问题的方案?- \* C" i/ S9 h+ W. E
9 Q1 s7 |- L" m5 e
答案:__________
0 z% G, e' m: i) K2 V0 E W2 G
( l9 G' b/ |% h3 p
% ~6 e0 G, N% m$ B8 V- t20.以下脚本输出什么?-
- <?php
- class a
- {
- function a()
- {
- echo 'Parent called';
- }
- }
- class b
- {
- function b()
- {
- }
- }
- $c = new b();
- ?>
复制代码 A.Parent called
, O; ~5 Y% L3 b9 ZB.一个错误
& R; P9 h) ^+ J- i2 K4 w6 d6 |C.一个警告
, }+ ]& y: h5 t. w) {* O/ n0 }( |5 |D.什么都没有
, A9 d6 O) H6 P W1 {; c
$ [- H9 H% Q- Q' `
3 D7 p# i7 f; }# a, g4 {- D" Z8 F4 v4 |
答案速查$ O& N5 _1 ?" j. \
1.类
& j, U! a: ~! `$ q) M! f7 Y2 `2.BCD7 G" h+ h" N/ X2 A" d% U! [ C
3.C/ C' N& {9 n! l* N* t& T
4.C& V$ f: G7 c; y' r0 O a+ \, C2 s
5.A
* t. D+ I# m! T# d9 N5 C. W$ r6.C
2 ^ {) V% `3 |) w8 p7.C7 T4 [, j" j5 O! C
8.C `7 S5 [7 `& m. }) e5 T
9.D: R9 l9 M1 V0 I& ]
10.B
! N. |: D- T2 `6 @/ U11.D: x! p. `8 M) W: ?
12.B2 s! b- f) E! N; x" A
13.A2 K" I* A0 d& j- |; R
14.D
Z1 K) o. {" ]. w4 g6 n15.A
: R$ I# d- q& g# @( X: F2 r16.B
7 k& i* g) m; @/ q( M! ]4 _, b17.A; _ L ]& `3 A. q3 O
18.D
/ N* J1 b' ^1 u3 n( _2 ~9 v# r19.设计模式( E& p( N6 [" D! G, s
20.D
~! X; e( ?- m: M1 J5 o7 r. K8 {% n6 O% C. C
3 b. F7 Y0 j4 q6 F$ B5 G) B
& d6 ^; V' l& L! S/ y: a( H答案详解& z* l; S) R; ^( x
% I7 _6 M" h" h, O k- p; o1.类是对象的蓝图(对象是类的实例)。
- R: b( F" J& N6 ]0 B! U2 F1 T% d4 w& y7 g9 W: R9 U* ?& m4 t) W7 ?
2.正确答案是B、C和D。set_value方法使用了错误的表达式$this->$my_value,因此该方法实际上是空的(这在PHP5里会导致一个错误,但在PHP4中不会。——译者注)。
0 Z0 ?0 Q$ ?/ I# J
6 _% {8 s/ |9 X" M3.答案是C。PHP4中无法限制对类成员的访问,而在PHP5中则可以通过private关键字实现。. D. w: F6 F' T
6 b0 J, i+ ~9 A8 s0 W2 [4.单件模式可以限制一个类被实例化的次数。7 s% T0 y1 g$ i6 v- r: m Z/ U
: q; h/ E; F' t
5.尽管其他编程语言允许多重继承,但在PHP的对象模型中却不可以。因此答案是A。
. M& a5 S( o/ F- o( f3 z Q8 U$ ^* U$ ?6 g/ N( n. Z) G
6.方框中的代码表现的是抽象方法(abstrace method)的实现。如果这个类继承自其他类,而my_funct方法在子类中被调用时没有覆盖,代码将抛出一个错误。虽然只是近似的实现了抽象方法,但在PHP4有限的对象模型中,这已经做得很好了。
6 a) M: i* m6 u# h+ c: L0 p* [" I5 g
7.PHP5有统一的构造函数(__construct()),但在PHP4中,构造函数就是和类有相同名称的方法。对于名为testclass的类,它的构造函数就是testclass()。答案是C。( O4 u# g q7 Z w
( u) L7 a' I# q- D+ [" T3 v0 }8.__sleep()和__wakeup()能被用来自定义对象的序列化过程。正确答案是C。
7 |& n& o1 E% g
# p( b6 h0 Y, L' Z9.PHP4中没有题目选项里所列的任何一个概念。答案是D。+ e9 }/ V3 Y% ] y1 p
* K+ i+ _! q$ r& l, J0 R
10.PHP中,在类的内部访问其成员和方法,要用$this这个特殊变量。因此答案是B。/ x R' ]/ g# r. y
3 z2 X' ~) j% B+ K' \11.正确答案是D。my_class::_my_class()不是合法的构造函数(方法名的开头多了个_),因此脚本不会输出任何东西。你可能觉得这题是在考眼力而不是知识,是的,我们就是这么打算。仔细想想你就会同意——绝大多数的bug都是由错误的拼写造成的。这题并不是在戏弄你,而是考验你的排错能力。7 g, P. `9 e# J# G, m
9 a* p) z7 u' h2 B* ], f
12.PHP4把对象视作标量进行处理,当$a赋给$b时,解释器创建对象的副本,因此对后一个对象的赋值不会影响到原先的对象。答案是B。但是要注意,PHP5里就不是这样处理的了(将会输出10)。
1 B# B$ X5 p8 z+ W; s1 T
+ V i9 u# \5 v6 U3 M8 k4 |. d13.一上来,构造函数my_class通过引用,将自身存储在了变量$global_obj中。你可能会因此觉得,当我们后来吧$global_obj->my_value的值变为10时,$a也会相应改变。不幸的是,new操作符返回的不是引用,而是对象的副本。脚本输出5,答案是A。
% r( W/ }0 K6 P; M6 _
- ?. N% S7 X" R% O" l14.PHP中,把对象传递给函数或者方法时,默认传递的是值。这意味着通过参数传递给函数的对象,其实是对象的副本。这点导致了在函数或方法里对对象进行改动时,不会影响函数外的原先的那个对象。' E% P0 e3 e" u" C2 x% ?6 `1 p
回到第14题中,这就说明对象$eight_tenths从来没有被reduce_fraction函数改动过,而$fraction对象(参数)则被改动了。如果要在函数内部改动对象,就必须以引用的方式传递参数:3 Z7 o& j( y2 Z' ^2 E
function reduce_fraction(&$fraction)* t4 O$ d; x) b0 ^. T# y% q# p3 L
答案是D。
0 J; ^- `' T5 g. n6 J5 U: ^+ `4 n, W0 S) o% ^, o! c
15.题中所示的语法是用来进行静态调用的。当方法被静态调用时,它们就像一个独立的函数,与任何类的实例无关。答案是A。$ g( @3 t2 f. a; s. ~
5 h7 j5 h" a2 r q- o+ s16.没有。PHP4只允许声明静态函数变量,没有静态类变量。/ B* ~1 F/ t" _' \% n: O
8 M7 D! {- w! `1 G17.答案是A。类b的属性$myvar将在b的父类——类a调用构造函数时被定义,此外,像PHP4中的普通变量一样,定义类变量时也不需要给它赋值。类b在其父类调用构造函数之前就给$myvar赋了值,所以不管之后如何赋值,输出都是1。
2 }5 ?9 A- p$ N( e0 e7 V# r1 _ {, r' w9 n( d9 N2 a L! M7 E
18.PHP4中无法即时装载类——它们必须在使用前就仔细声明好。PHP5中,可以使用__autoload魔术函数提醒解释器在找不到需要的类时尝试自动调用。因此答案是D。9 ^, D2 g% z p5 }/ U Z/ `
. K0 V3 ?! X8 O/ c/ H9 _& P7 d
19.为软件设计和编程中的常规问题提供良好的解决方案,这显然是在说设计模式。
0 a) ~$ Q; y. ^. q, L# m. ?% _; {" D% \! b: H k
20.脚本什么都不输出(答案是D)。因为子类的构造函数不会自动调用父类的构造函数。 |
|