首页 > 编程语言 > 详细

Java中抽象类和接口的区别(读书笔记)

时间:2015-12-12 18:45:06      阅读:230      评论:0      收藏:0      [点我收藏+]

Java的抽象类和接口


   抽象类和接口是两个容易混淆的概念,但有一句话能很好地将这两者区分开来,即抽象类是事物的抽象,而接口是行为的抽象。抽象类抽象出来的是一类事物,事物中包含了一些固有的属性和行为,而接口更多的是提供固有属性行为之外的延伸行为。打个比方,可以把动物看成为抽象类,类中有一些固有属性,如身高体重,还有一些共有行为,如吃饭和睡觉,所有的动物都遵循着这些属性和行为。除此之外,有些动物还能飞,但并不是所有的动物都具有飞行这种能力,此时飞行只是事物的延伸功能,相当于一个接口。

一.抽象类
  抽象类是包含抽象方法的类。抽象方法是一种特殊的方法,抽象方法的声明格式为:
    
  abstract void fun()
    
  抽象类有以下三个主要的特点:
  1)它只有声明,没有具体的实现。抽象类和抽象方法都必须用abstract关键字来描述。
  2)抽象方法的具体实现由子类来完成,若子类不实现父类中的抽象类,则该子类同样需要定义为抽象类。因此抽象方法的访问修饰符只能是public和protected,这个很好理解,若访问权限为private则继承该抽象类的子类无法具体该方法。
  3)抽象类不能实例化。因为抽象类中的抽象方法没有具体实现,实例化后调用该方法没有具体操作。若想调用抽象类中的非抽象方法,可以实例化抽象类的子类继而进行调用。(当然,前提是子类不是抽象类)
  另外,尽管抽象类的定义是包含抽象方法的类,但并不意味这抽象类中只能有抽象方法。和普通类一样,抽象类中可以拥有成员变量和普通的成员方法。

  抽象类相对于普通类的三点区别:
  1)抽象方法必须为public或protected(如果是private则无法被子类继承,进而实现方法),缺省情况下默认为public
  2)抽象类不能实例化
  3)如果一个类继承于抽象类,则子类必须实现父类的抽象方法,否则该子类同样为abstract类

二.接口
  修饰词为interface,在软件工程中,接口泛指供别人调用的方法,因为我们也能初步体会Java语言设计者的初衷,即接口是延伸行为的抽象。接口的声明格式为:

  public interface interfaceName
  {
  }

  接口有以下三个特点:
  1)接口是可调用的。这也是接口存在的意义
   2)接口中的变量会被隐式地指定为public static final(并且只能是public static final,用private编译会报错)。但是接口中一般不定义变量(既然所有的方法都没有具体实现,定义了变量也无处可用)
  3)方法会被隐式地指定为public abstract,就是说接口中所有的方法都是抽象方法。而由此可看出接口和抽象类的一个区别,接口是极度的抽象。
    
  实现接口需要用implements关键字,格式为
    
  class className implements Interface1, Interface2,...
  {
  }
    
  由此可以看出接口与抽象类的另一个区别,一个类只能继承一个抽象类,却可以实现多个接口。当一个类实现一个接口时必须实现该接口的所有抽象方法(该实现类为抽象类时例外)

三.抽象类和接口的区别

参数 抽象类 接口
默认的方法实现 它可以有默认的方法实现 接口完全是抽象的。它根本不存在方法的实现
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
构造器 抽象类可以有构造器 接口不能有构造器
与正常Java类的区别 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 接口是完全不同的类型
访问修饰符 抽象方法可以有publicprotecteddefault这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。
多继承 抽象方法可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口
速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。


四.抽象类和接口的使用指导


下面先来看看网上流传最为广泛的例子:门和警报的例子。门和警报都有open()和close()两个动作,此时我们可以通过抽象类和接口来定义这个抽象概念:

public abstract class Door
{
    public abstract void open();
    
    public abstract void open();

}

public interface Door
{
    public abstract void open();

    public abstract void close();

}

那么问题来了,如果我们现在需要给门加上警报alarm()的功能,那么该如何实现?先参考以下两种思路:
1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但实际上门不一定具备报警功能;
2)将这三个功能都放在接口中,但这样一来仅需要实现警报功能的类把open()和close()也给实现了,但实际上该实现类不一定具有open()和close()两个功能,比如火灾报警器。

从这里可以看出,Door中的open(),close()和alarm()从根本上属于不同的范畴,open()和close()属于门本身的固有的行为特性,而alarm()属于延伸的附加行为,因此最好的办法是将警报单独设计为一个接口,包含alarm()行为,Door设计为一个抽象类,包含open()和close()两种行为。至此报警门可设计为一个类继承Door类和实现Alarm接口

public interface Alarm
{
    public abstract void alarm();
}

public abstract class Door
{
    public abstract void open();
    
    public abstract void close();

}

public class AlarmDoor extends Door implements Alarm
{
    public void open(){}

    public void close(){}

    public void alarm(){}

}

由此可以总结得出:

1)如果你想拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类。
2)如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
3)如果基本功能在不断改变,那么就需要使用抽象类。否则一旦需要修改某个接口,就必须相应的修改该接口的所有实现

 

参考文献

http://www.cnblogs.com/dolphin0520/p/3811437.html

http://www.importnew.com/12399.html

 

Java中抽象类和接口的区别(读书笔记)

原文:http://www.cnblogs.com/Michaelali/p/5040288.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!