1。8 类(Classes) 1 ~8 r4 n& Z8 u$ v! B9 c
类用于定义一个新的引用类型。c#不支持多重继承,但支持一个类多重界面(“interfaces”)。 $ ^+ r* s( D! Y' z类的成员包括常量、位域、方法、属性、索引(indexers)、事件、操作符、构造器、析构器和嵌套 - k7 e3 h/ ~/ Z# X& f: O
类型声明。(一口气说这么多,呼——) 4 y) A& S( a2 G' \" {' ~6 h
对类中得所有成员有五种访问权限: k) N3 l7 A, J0 P# ?- Z· “public” 可以被所有代码访问; 9 i" n4 `4 M; W! P1 C· “protected” 只可以被继承类访问; ! R7 f ?5 V3 G4 z
· “internal” 只可以被同一个项目的代码访问; 5 f: }& Y% D1 h
· “protected internal”只可以被同一个项目的代码或继承类访问; 2 v# K% D% x s' Q* K' W· “private” 只可以被本类中的代码访问。 ( @' z( m5 X/ L$ @
缺省状态是“private”。 & V: B: M: B# `
( c: {) g; [' ~" `! {8 y1。9 结构(Structs) - h1 }. `( ~$ U- F
结构和类又非常多的相似之处,如结构可以实现界面,和可以拥有和类一样的成员。结构与类也有一些重要的区 3 a6 `3 b! X, O, h P
别:结构是值类型,而不是引用类型,所以不支持继承!结构被存在堆栈中或者是内联。结构在精心下可以提高 - J. `% k, ]5 ]% l/ A- m; j) A
存储效能。例如,定义一个与类有着相同信息的结构可以大大地减少存储空间。在下例中,程序创建并初始化100 - T3 `0 n8 t% p* o个points。在类“Point”中需要分配101个独立的对象(object)。*/ # e _; _0 [6 R. Y1 f, m
' \7 V3 B( @& ]( c0 o2 Lclass Point 3 _, j7 J+ o0 Y3 D% M' x* z
{ % S' m/ w/ ~$ `; I. n" Q4 s! I' z8 @public int x, y; , L- ~" C9 P! A7 ^2 `public Point() { 2 T; B; e! g8 k3 f" m& lx = 0; 0 M/ G4 h) P, C& O+ k; I
y = 0; _( f; b! F5 }& ^
} 8 m: \! U, e+ y, @8 a0 Gpublic Point(int x, int y) { 6 w7 [7 r# T- a- |+ P2 j* ?1 P
this.x = x; # G w$ U: [* f( q
this.y = y; / I" L# F' z% f( g
} ' [6 V& P# \9 b! p! f: m
} " ?5 i( p0 x; b& V% u- _! l; B% ` [
class Test 9 h4 O7 D% {% x5 M{ 5 H8 c' a6 ~& j. E
static void Main() { / G2 v7 d5 M! Q2 C2 Z) J
Point[] points = new Point[100]; - Z0 m/ W1 V( c7 U _
for (int i = 0; i < 100; i++) " V w( m$ J- E5 C: xpoints = new Point(i, i*i); 8 H+ W3 d( |5 P/ b% F
} % i. K9 c, Z- ~0 T8 t/ e; a* o' [
} 9 ~# g |" u- \0 F
/* ( s+ g* Y3 T, B& Q5 r/ N如果“Point”被作为一个结构,就可以这样啦:*/ 8 A3 i+ {8 l/ a/ h1 B5 n2 {
struct Point 1 P( D1 |% J. c1 h* z& P{ 9 S+ H. P$ V3 N) h: r' K% X f/ G8 E
public int x, y; 5 Z; b( C3 {% e8 l+ f7 L* X5 lpublic Point(int x, int y) { Q7 \4 z/ }( ?. R: `7 _this.x = x; ( |$ n M8 A$ C; D6 E' `" d
this.y = y; 9 F0 s4 z/ k* r} , p }, H; N6 `# [ S2 p; V f4 r+ p} . `; l' @$ K8 F6 h* y/* ' r/ H- h% z6 N1 x
因为Point在内联中实例化,所以得到了优化。当然,错误运用的只会适得其反。比如,当我们传递结构的 , [3 c# r5 Q5 _7 }! H0 ?3 \
时候就会比传递类要慢。因为结构的传递是拷贝值,类是引用值的地址。数据量越大差距就越明显。 . p1 m' {; a# p- K* e9 D: _
所以“There is no substitute for careful data structure and algorithm design.”(实在是不想译 . y- m+ I I6 a了 ^_^ )。 + a( r3 M8 q( f) f
% W2 `& _) `" N5 d' v- e
1。10 界面(Interfaces) 4 M1 Y- J7 ~8 \' t: c/ ?- N7 n+ t
界面用来定义一种程序的契约。有了这个契约,就可以跑开编程语言的限制了(理论上)。而实现界面的 * O1 _% M8 ^- ^" Q类或者结构要与界面的定义严格一致。界面可以包含以下成员:方法、属性、索引和事件。例子:*/ + N6 R* D1 o* j7 C, j ' ~3 v8 v+ I1 f/ ?9 I+ Z0 c# zinterface IExample : u3 o% j( w( |* t5 E7 D# T{ 3 L7 Y/ V9 L. ~- J8 }- @' K+ V+ ~string this[int index] { get; set; } ; Q% z8 l- J+ L" F+ sevent EventHandler E; / W& y/ M7 w, H" o5 J/ w# ]
void F(int value); # M: i* `- a; O! A" Cstring P { get; set; } 0 a! ~9 d9 W% m/ \& h} , [9 s. ^+ q1 p) _; zpublic delegate void EventHandler(object sender, Event e); 7 I/ _7 V4 j7 W
/* 6 Q9 E7 O( F: x& p8 z8 C3 }, Q. a
例子中的界面包含一个索引、一个事件E、一个方法F和一个属性P。 ! E8 P3 [6 ^8 ]1 v( t' i- ~
界面可以支持多重继承。就像在下例中,界面“IComboBox”同时从“ITextBox”和“IListBox”继承。 : Z( C& o: g1 q7 x. Y) _& U; u
*/ ) a; J0 N6 n" F4 h3 }5 L( p9 Y
interface IControl ( x* Q. H0 R3 u8 K+ H7 E- k{ ( y$ L9 i/ J+ r4 {
void Paint(); ' h* U6 g q& o4 O" k2 Q5 U) T
} 7 L% Z$ i& U* r4 J4 u8 ~
interface ITextBox: IControl 6 ~% ]( o" l: Z4 p$ d7 D
{ $ Q5 A: ] K0 A- {. qvoid SetText(string text); * }$ A& C. D+ u( X} 9 w5 o/ c1 c% Z7 F9 y6 H6 L- [- C
interface IListBox: IControl " M- [2 R) o! k
{ 2 D( x2 c8 N) ?5 O( y5 a( K; N7 ?void SetItems(string[] items); # v: p% ~" W% B9 @) g} ' E) F1 ^% {3 d. X
interface IComboBox: ITextBox, IListBox {} . ?) Z$ W3 j- _. Z" u( g
/* 6 {* V+ S. M) d: c' p
类和结构可以多重实例化界面。 就像在下例中,类“EditBox”继承了类“Control”,同时从“IDataBound” 8 E& i% M+ t; w( |) `; k和“IControl”继承。 & U( G+ I6 S& Z0 B. n
*/ 8 }4 H" N" p; H9 d
interface IDataBound + g6 N4 E% O% o6 T; U$ W: o{ # U X0 G/ J# N( F+ c7 u8 ^7 [
void Bind(Binder b); " g% I, D b6 B} : x1 f& v- ~9 {* [$ u
public class EditBox: Control, IControl, IDataBound + J' {; t1 d5 B' K& R{ + @8 f6 z& f, `public void Paint(); * E% G' I2 J/ Y
public void Bind(Binder b) {...} ; P( E# u W# {6 h V* G
} 6 o+ p' | c& z/ T! H
/* # U3 O& j1 n, `9 ~
在上面的代码中,“Paint”方法从“IControl”界面而来;“Bind”方法从“IDataBound”界面而来,都 6 K/ ]# v; b0 C" q, Z
以“public”的身份在“EditBox”类中实现。