黑马程序员技术交流社区

标题: 抽象类和接口的理解,不知道对不对!! [打印本页]

作者: 会飞的鱼    时间: 2012-10-25 21:18
标题: 抽象类和接口的理解,不知道对不对!!
本帖最后由 古银平 于 2012-10-29 22:48 编辑

/*
* 1、抽象类是用abstract修饰的类,主要用于提取共性。
* 抽象类不能被实例化(new),只能通过继承了该类的子类才能创建对象。
* 继承抽象类时,必须覆盖该类中的每一个抽象方法,此跟接口类似。
* 抽象类的非抽象方法实现部分功能,并且可以让子类直接调用或者重写(与接口最大的不同)。
*
* 2、继承是面向对象语言的重要机制。
* 在java中,继承是通过扩展(extends)原有的类,声明新类来实现的。
* 扩展声明的新类称为子类,原有的类称为父类。
* 并且子类可以拥有超类的所有属性和方法,同时也可以另外定义自己特有的属性,方法。
*
* 3、接口可以提高程序的复用率,增加程序的可维护性,可扩展性。
* java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现。
* 也就是说一个java类只能继承一个父类,但却能同时实现多个接口。
*
* 4、个人理解,不知道这样理解对不对!!
* 假设有Car(车),Plane(飞机),Ship(船)三个类,而他们都是交通工具的一种,
* 因此可以抽象出一个交通工具类:Transportation,并且有一个抽象的方法Run()。
* 但是它们Run的方式又有不同,Car是Walk(),Plane是Fly(),而Ship是Swim()。
* 假设把这个Walk(),Fly()和Swim()都抽象在Transportation()类里或者都写在一个接口里,
* 那么只要继承了这个抽象类或者实现了这个接口的类,这个交通工具就必须又能Walk(),又能Fly(),而且还要能Swim(),这显然不合理。
* 但是如果把这Walk(),Fly(),Swim()分别置于IWalk,IFly,ISwim三个接口中,
* 那么只要继承了Transportation类,并且实现了IWalk接口就是Car,能Walk()。
* 继承了Transportation类,并且实现了IPFly接口就是Plane,能Fly()。
* 而继承了Transportation类,并且实现了ISwim接口就是Ship,能Swim()。
* 同时这样提供了极大的便利与拓展,如:
* 假设有个摩托艇,能在地上Walk(),并且能在水中Swim().那么只要继承了Transportation类,并且实现了IWalk,ISwim接口,就可以了。
* 而如果有个海陆空的怪物,能Walk(),能Fly(),并且还能Swim().那么只要继承Transportation类,同时实现了IWalk,IFly,ISwim三个接口就可以了。
*/
作者: 马磊    时间: 2012-10-25 21:25
如果是只有单一功能的,只要用子类重写父类的run方法就行了吧,不用实现接口这么麻烦。
比如你说的汽车的walk(),用汽车子类里重写父类的run(),把其功能实现在里面就行了吧?
但是要有一个多功能的汽车,会跑还会游,那用接口实现比较方便。
作者: 会飞的鱼    时间: 2012-10-25 21:47
马磊 发表于 2012-10-25 21:25
如果是只有单一功能的,只要用子类重写父类的run方法就行了吧,不用实现接口这么麻烦。
比如你说的汽车的wa ...

如果都设成abstract方法,那么跟接口没什么两样,都需要覆盖重写。
而不设为abstract,那么可能直接覆盖和重写。也就是说当没有覆盖和重写的时候,Car或许只能Fly()而不能Walk()。而Plane或许能Swim()和Walk()但却不能Fly().
作者: 王永荣    时间: 2012-10-25 23:00
什么时候用抽象类,什么时候用接口?
一个报警门例子:不同的门都具有本质特征动作 open(), close()。那么抽象类和接口都可以定义这两个方法。现在要求它具有报警alarm功能。
1) 如果这3个功能都放在抽象类里面,那么所有的门都具备了这3个功能,无疑不妥,有的门不需要报警功能啊!
2) 如果这3个功能都放到接口里面,需要用到报警功能的其他类,就需要实现门的open和close功能,这样子也不对!

所以,应该把门的open, close和alarm分离,让所有的门都有open, close动作,继承抽象类Door。而需要添加报警功能的门,则再继承接口Alarm。
  1. abstract class Door {
  2.  abstract void open();
  3.  abstract void close();
  4. }

  5. interface Alarm {
  6.  void alarm();
  7. }

  8. class AlarmDoor extends Door implements Alarm {
  9.  void open() { … }
  10.  void close() { … }
  11.  void alarm() { … }
  12. }
复制代码
可以看出,因为抽象类是用于单一继承,接口是用于多重继承,所以需要这样安排。而同时看到,抽象类就是类的本质特征,共同的;接口是个性化的,你想让类更具个性化,则继承其他相应个性特征的接口。
由此可以得到:抽象类,"is-a"关系,抽象出共同的本质特征,单一继承;接口,"like-a"关系,个性化特征,多重继承。
参考资料:http://tech.ccidnet.com/art/3737/20060512/550983_1.html


作者: 会飞的鱼    时间: 2012-10-25 23:08
王永荣 发表于 2012-10-25 23:00
什么时候用抽象类,什么时候用接口?
一个报警门例子:不同的门都具有本质特征动作 open(), close()。那么 ...

{:soso_e181:}
作者: 黑马张旭    时间: 2012-10-27 16:33
说下我的体会,实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。 所以一般一类东西中的个别东西想要扩展功能 一般得需要使用接口来完成







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2