浅谈接口和抽象类

  今天无聊,学习之余想写点文字性的东西谈谈面向对象中的接口和抽象类的概念。本人纯菜鸟,在黑暗中摸索中前进!

  就我个人学习经历而言,学了这么就的面向对象语言,有涉及到java、c#、Object-C。都有接口和抽象类的概念,对于大多数人都很容易区分这两者的表面区别,知道各自的语法。在接触接口和抽象类之初,感觉接口还有点作用,抽象类基本都不用。但现在想想觉得当时的想法有些可笑。

  抽象类,抽象类首先他是一个类,也就是 IS A的关系。接口是CAN DO 的关系。抽象类中的方法可以有实现了的方法和未实现的方法。他的未实现的方法必须被他的子类具体去实现,这就有了多态性(这些都是废话)。我们可以知道一种设计模式------模版方法,在抽象类实现子类中共有的方法,而不同方法则由子类去具体实现。也可以实现的方法中调用未实现的方法,尽可能地减少代码重复。我觉得这是抽象类最闪耀的地方。

  接口,接口中的方法全是未实现的方法。OC中的接口称为protocal(协议)。也就是一个类要遵循某个协议才能干什么事情,通俗点将就是这个类必须去实现接口中的方法才能做某件事情(体现了CAN DO 关系)。OC中称实现了接口的子类为delegate,这是非常有道理的,它和C#的代理(它可以看成一个函数指针)实现还是不同的,但完成的功能基本相同。比如说按钮事件监听,我们写的处理事件都是在实现接口类中的方法中的。这就是设计模式------代理模式了。个人感觉这种模式是设计模式中最重要的一种了吧!这种设计模式确实很巧妙,用到了回调机制----方法的定义和方法的调用不在同一个地方(类)。方法的定义往往是我们自己写的(但必须按接口写),而调用往往被封装了。

  虽然理解了接口和抽象类的作用,但是对我这种新手而言在写代码时候考虑得这么周到确实感觉困难。可能一开始我们不可能直接就想到将某个类直接定义为抽象类,而是先将一个类定义为普通的类,当我们想到还有好多类和当前类有好多相同代码时候,我们可以将该类改为抽象类。(*这也算是我的一点小经验吧,但是听师兄讲实际开发中如果抽象类中实现了的方法(也就是子类共同的方法)要根据子类不同做不同的修改时,这也是一个头疼的问题,我暂时没找到好的方法去解决,望大神支招!)

  同样,接口自己用起来也是很困难。但是理解起来去觉得挺简单的,就比如UI界面用的最广泛了,对事件添加监听啊,自己写的监听都要实现某些接口,一旦事件触发了,在sender(控件)类内部肯定封装了调用该接口的那个方法。在比如说线程吧,有两种方式,一种是继承线程类,一种是实现Runnable接口,实现了这个接口就必须重写run方法。那么当thread.start()的时候,会运行thread.run();想必Thread类的run方法中肯定有一句类似这样的代码wjy.run();这里wjy是实例化的Runnable的一个实现类。有些代码虽然被封装了,但我们应该要多思考它内部是如何实现的。

  下面像举个例子综合了接口和抽象类的使用,都是从面向对象考虑的。假如现在我们要写一个对数据库操作(增删改查)的封装。而且如果数据库有两种(sql server / orcal),那么这两个类是去完成一样的功能,用到接口还是比较好的。当写到具体对某个类型的数据库比如sql server操作时,对不同的表的增删改的代码应该是差不多的,只是查询不同,查询也不是完全不同,我们只把不同的对表字段的遍历放到子类中去实现,这里用到了抽象类。就这个例子的实现,我想对于新手写起来还真是不容易(尤其在抽象类中重构方法那一块),又是抽象类又是接口的,就算了写出来给别人维护理解也不是那么容易。现在的困惑就是得与失的问题:接口用得太多也未必是好事,这真是一个值得深入探究的问题。这就让我想到了梅老师的话了:项目组中老大往往是只写接口的,看起来挺轻松,但接口写不好是会害死人的事情。

  最后是我个人总结:如果两个类同样完成某个功能,那么可能用到接口;如果两个类的实现有很多相同之处,那么可能用到抽象类。

  (接口-可扩展性,抽象类-代码复用)

                                                           2013-08-02 00:57:26 随笔

  

posted @ 2013-08-02 00:58  吴加跃  阅读(329)  评论(0)    收藏  举报