+ \2 D( v$ M/ G5 {0 u9 h; h) z% v; K# O) W. e8 L: \
从设计理念层面看abstract class和interface . I4 n' G; M& @5 r; h: h
: y0 g( V8 E4 W! w, R9 L
上面主要从语法定义和编程的角度论述了abstract class和interface的区别,这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。 3 `, V5 v, g- p+ `) W+ t5 F / E) B v* o7 m& x前面已经提到过,abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的(参考文献〔3〕中有关于"is a"关系的大篇幅深入的论述,有兴趣的读者可以参考)。对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。 / [# C+ B+ a+ O0 t t3 v 2 I' h! y( ]+ y+ K考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示: 5 M9 T, j- B1 D# H/ D* o
- d7 v( r+ h7 M* e& T
使用abstract class方式定义Door: ) C) R0 E* T! R+ k* ], `
. P9 r( s9 b Xabstract class Door { ' `) z1 q0 G& x9 E$ U* N& J. B
abstract void open(); , I% j! w% E( @3 @, d abstract void close(); 3 C9 D7 P% Z: ~6 g8 i" ]: w
} . A& g" \7 V- o. s/ s
( c2 E! I1 E; F% q* `0 m
) D. L( s( q, h9 B) B使用interface方式定义Door: ; S( P4 C ?# k1 M7 i' i. [* g& V L( y
; a. x8 F! Z. k" x s 5 y, h: U. O- x) H, Q3 H4 hinterface Door { / E) T0 l6 i, K* S7 ]; T4 |& b void open(); . l5 I; e$ z3 t( g1 i
void close(); 0 z1 d/ R* f. d3 d9 M} ; w( L! v" [1 v v4 R4 H' o
0 e1 N$ ~/ c+ b/ O( m; r % g2 n& o$ g1 H: a. M
其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。 , s2 h9 g* y+ H) r
7 {& A) J: `! \) x' g e
如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在本例中,主要是为了展示abstract class和interface反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解决方案,并从设计理念层面对这些不同的方案进行分析。 " v. V) E8 ^0 k- r$ `# z
4 h1 d% b& n. e. V2 E解决方案一: % ]) r2 ^( ]5 [, Y( U& H
4 ]5 G1 K2 E$ \+ \; Y
简单的在Door的定义中增加一个alarm方法,如下: . q- a; c U6 U m2 D
& H$ m% B+ ?# v) y+ m
abstract class Door { 4 w& v$ p' j1 T" x& \1 r1 f
abstract void open(); % J6 m% h/ R7 Z! f3 x
abstract void close(); & n2 |5 z1 u+ g, Q/ t
abstract void alarm(); " q# P6 Q0 d: b9 d0 B) J+ J
} 3 c7 {" d$ L% d2 O1 s; G
" Q6 i$ G9 q' u. X& n
. l+ b7 q6 h" a) H5 B或者 0 A+ x0 E& L$ [4 z( U ~
: n, t s+ y+ o" q8 ?, x
interface Door { ! l9 u0 D3 u0 L8 T7 h
void open(); , L! `: R$ E1 k' [" d* d( a' m; p
void close(); ) E9 V2 M+ T5 b7 y6 a2 P& P* L' x void alarm(); / `4 e. |1 C$ \& v} 3 I+ l2 L& w9 h4 o8 p3 @
; t) c. M. [/ w; ~( q+ S ) `% e4 T$ l$ a3 _
那么具有报警功能的AlarmDoor的定义方式如下: 0 g! }# [8 N" p9 g) w+ g0 F) \