从抽象类到接口

假设有以下的类
1None.gifpublicabstractclassGunBase//枪械
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicabstractvoidShoot();//射击
4InBlock.gifpublicabstractClipModeClip//配置弹夹
5ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
6InBlock.gifset;
7InBlock.gifget;
8ExpandedSubBlockEnd.gif}

9InBlock.gifpublicabstractvoidLoad();//装填
10ExpandedBlockEnd.gif}

11None.gif
12None.gifpublicenumClipMode
13ExpandedBlockStart.gifContractedBlock.gifdot.gif{
14InBlock.gifInside,
15InBlock.gifOutside
16ExpandedBlockEnd.gif}
我们当然它为抽象类,但这样一个抽象类,其没有构造函数,其所有成员也都完全是抽象的,我们还可以称其为纯抽象(虚)类。因为这个类,是完全的抽象的,但如果代码改为
1None.gifpublicabstractclassGunBase//枪械
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicabstractvoidShoot();//射击
4InBlock.gifprivateClipModeclipMode;
5InBlock.gifpublicabstractClipModeClip//配置弹夹
6ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
7InBlock.gifset
8ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
9InBlock.gifclipMode=value;
10ExpandedSubBlockEnd.gif}

11InBlock.gifget
12ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
13InBlock.gifreturnclipMode;
14ExpandedSubBlockEnd.gif}

15ExpandedSubBlockEnd.gif}

16InBlock.gifpublicabstractvoidLoad();//装填
17ExpandedBlockEnd.gif}


同样是抽象类,但修改后的类,就不再是纯抽象类了。纯抽象的类,我们要求是没有构造函数,没有任何的非抽象成员,所有成员的访问修饰都是public的,这样我们有了一个新的名词:接口interface。

现了解一下接口的定义要求
接口就是一个纯抽象类(所以接口是引用类型),接口可以包含方法、属性、事件和索引器,实现该接口的类或结构必须实现这些成员。
相比起抽象类,接口有以下特征

不需要声明接口为抽象或虚拟(本来就是)
接口不允许有构造函数(纯抽象了,根本不需要构造)
接口不允许有析构函数(本来无构造,何需有析构)
接口的所有成员都是抽象的(纯抽象类嘛)
接口只可以从接口继承(因为只有接口可以保证使纯虚的,如果从抽象类继承,不能保证抽象类中可能存在非抽象的成员)
接口成员不允许有任何修饰(默认就是public的,也只有是public的)
一个类或结构可以实现多个接口

那为什么要接口呢?
我们设想一个场景,假设我要写一个模拟角色的游戏,每个玩家都可以拥有多个角色(职业),如果有一个人其职业是医生,但同时他也是研究生,在学校带课,但又在攻读博士,同时呢,由于工作出色,担任了科室主任,在回家的路上又去了超市。
那我们可以观察到,这个人实现了的角色有:医生、学生、讲师、领导、顾客。那类怎么描述实现呢?用继承?

1None.gifpublicclassPerson
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicstringName;
4InBlock.gifpublicSexSex;
5ExpandedBlockEnd.gif}

6None.gif
7None.gifpublicclassDoctor:Person//医生
8ExpandedBlockStart.gifContractedBlock.gifdot.gif{
9InBlock.gifpublicboolOperations()
10ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
11ExpandedSubBlockEnd.gif}
//返回成功与否
12InBlock.gifpublicstringDiagnosis()
13ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
14ExpandedSubBlockEnd.gif}
//返回诊断意见
15ExpandedBlockEnd.gif}

16None.gif
17None.gif
18None.gifpublicclassGaduate:Doctor//学生
19ExpandedBlockStart.gifContractedBlock.gifdot.gif{
20InBlock.gifpublicvoidGotoClass()
21ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
22InBlock.gif
23ExpandedSubBlockEnd.gif}

24InBlock.gifpublicintExam()
25ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
26InBlock.gif
27ExpandedSubBlockEnd.gif}
//作练习返回成绩
28ExpandedBlockEnd.gif}

29None.gif
30None.gifpublicclassProfessor:Gaduate//教授
31ExpandedBlockStart.gifContractedBlock.gifdot.gif{
32InBlock.gifpublicvoidDisquisition()
33ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
34ExpandedSubBlockEnd.gif}

35ExpandedBlockEnd.gif}

36None.gif
37None.gifpublicclassConsumer:Professor//顾客
38ExpandedBlockStart.gifContractedBlock.gifdot.gif{
39InBlock.gifpublicvoidstock()
40ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
41ExpandedSubBlockEnd.gif}

42InBlock.gifpublicvoidpaying(doublecash)
43ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
44InBlock.gif
45ExpandedSubBlockEnd.gif}
//支付
46ExpandedBlockEnd.gif}


如果你还有一点点面向对象的理智的话,就知道这个非常非常的错误的设计。不但类的结构非常的臃肿,还难以代码重用。


所以我们将代码改为使用接口来实现。
我们把job角色定义为接口,而不是类

1None.gifpublicinterfaceIDoctor//医生
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifboolOperations();//返回成功与否
4InBlock.gifstringDiagnosis();//返回诊断意见
5ExpandedBlockEnd.gif}

6None.gif
7None.gif
8None.gifpublicinterfaceIGaduate//学生
9ExpandedBlockStart.gifContractedBlock.gifdot.gif{
10InBlock.gifvoidGotoClass();
11InBlock.gifintExam();//作练习返回成绩
12ExpandedBlockEnd.gif}

13None.gif
14None.gifpublicinterfaceIProfessor//教授
15ExpandedBlockStart.gifContractedBlock.gifdot.gif{
16InBlock.gifvoidDisquisition();
17ExpandedBlockEnd.gif}

18None.gif
19None.gifpublicinterfaceIConsumer
20ExpandedBlockStart.gifContractedBlock.gifdot.gif{
21InBlock.gifvoidStock();
22InBlock.gifvoidPaying(doublecash);//支付
23ExpandedBlockEnd.gif}

这样Person 类就可以实现(继承)多个接口
1None.gifpublicclassPerson:IDoctor,IGaduate,IProfessor,IConsumer
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicstringName;
4InBlock.gifpublicSexSex;
5InBlock.gifpublicintAge;
6InBlock.gif
7InBlock.gif
8ContractedSubBlock.gifExpandedSubBlockStart.gifIDoctor成员#regionIDoctor成员
9InBlock.gif
10InBlock.gifpublicboolOperations()
11ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
12InBlock.gifreturnfalse;
13ExpandedSubBlockEnd.gif}

14InBlock.gif
15InBlock.gifpublicstringDiagnosis()
16ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
17InBlock.gifreturn"";
18ExpandedSubBlockEnd.gif}

19InBlock.gif
20ExpandedSubBlockEnd.gif#endregion

21InBlock.gif
22ContractedSubBlock.gifExpandedSubBlockStart.gifIGaduate成员#regionIGaduate成员
23InBlock.gif
24InBlock.gifpublicvoidGotoClass()
25ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
26ExpandedSubBlockEnd.gif}

27InBlock.gif
28InBlock.gifpublicintExam()
29ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
30InBlock.gifreturn0;
31ExpandedSubBlockEnd.gif}

32InBlock.gif
33ExpandedSubBlockEnd.gif#endregion

34InBlock.gif
35ContractedSubBlock.gifExpandedSubBlockStart.gifIProfessor成员#regionIProfessor成员
36InBlock.gif
37InBlock.gifpublicvoidDisquisition()
38ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
39ExpandedSubBlockEnd.gif}

40InBlock.gif
41ExpandedSubBlockEnd.gif#endregion

42InBlock.gif
43InBlock.gif
44InBlock.gif
45ContractedSubBlock.gifExpandedSubBlockStart.gifIConsumer成员#regionIConsumer成员
46InBlock.gif
47InBlock.gifvoidIConsumer.Stock()
48ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
49InBlock.gif
50ExpandedSubBlockEnd.gif}

51InBlock.gif
52InBlock.gifvoidIConsumer.Paying(doublecash)
53ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
54InBlock.gif
55ExpandedSubBlockEnd.gif}

56InBlock.gif
57ExpandedSubBlockEnd.gif#endregion

58ExpandedBlockEnd.gif}


注意,IConsumer 成员采用的是显式实现。
标准实现的模型是:public 接口成员[返回值 名字 参数] {}
显式实现的模型是:没有访问修饰符 接口名称.接口成员[返回值 名字 参数] {}

显式实现的接口成员没有访问修饰符,也就意味着显式实现的成员感觉上是私有的,不能被访问。那这样的实现有什么意思呢?
请看下篇:我,只关心接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值