抽象类和接口,一直比较容易混淆,特性很类似,但是细节上又有不一样,总结如下。
首先,要了解什么是抽象方法。
抽象方法是只有方法声明没有方法体的方法用关节自abstract声明,例如
1 abstract returnType funName(Type t1,type2,t2...); 2 //例如 3 abstract int help(int k);;
包含了抽象方法的类,一定是抽象类。但是抽象类中可以没有抽象方法,也可以用自己的类变量(static修饰)和实例变量(非static 但是在类中方法体之外)。
抽象类可以被继承,但是不能通过new来实例化。以下看起来是可以通过new实例化了,实际上是生成了一个子类,把抽象方法实现了,子类实例化了,而且这个子类没有名字。
也就是说 :
抽象类其实是可以实例化的,但是他的实例化方式不是通过new方式来创建对象,而是通过父类的引用来指向子类的实例来间接地实现父类的实例化(因为子类要实例化前,一定会先实例化他的父类。这样创建了继承抽象类的子类的对象,也就把其父类(抽象类)给实例化了)
1 public abstract class BowlingGame { 2 public int a =1; 3 abstract int help(int k);; 4 5 //这种用法也叫做匿名内部类 6 public static void main(String args[]){ 7 BowlingGame bl = new BowlingGame(){ 8 9 @Override 10 int help(int k) { 11 // TODO Auto-generated method stub 12 return 0; 13 }}; 14 bl.a=3; 15 System.out.println(bl.a);}
在使用抽象类时需要注意几点:
1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
2、抽象方法必须由子类来进行重写。
3、只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
5、子类中的抽象方法不能与父类的抽象方法同名。
6、abstract不能与final并列修饰同一个类。
7、abstract 不能与private、static、final或native并列修饰同一个方法。、
接口:接口是抽象的抽象,接口中全部是未实现的方法,也允许有常量域。允许创建者确定方法名,参数列表和返回类型,但是没有任何方法体。是一个极度抽象的类。用implement实现。java是单继承的,只能继承一个父类,但是却可以实现多个接口。这也就是接口相对于抽象类的优势所在。
interface生来就是被实现的,所以他们默认就是public的啦。试想一下,把他们声明成private protected,不能被实现了他们还有什么意义!!
在使用接口过程中需要注意如下几个问题:
1、个Interface的方所有法访问权限自动被声明为public。确切的说只能为public,当然你可以显示的声明为protected、private,但是编译会出错!
2、接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为为public static final。可以通过类命名直接访问:ImplementClass.name。
由下图可知成员变量默认是public static final
3、接口中不存在实现的方法。//抽象类中可以有实现的方法,抽象类中甚至可以没有抽象方法
4、实现接口的非抽象类必须要实现该接口的所有方法。抽象类可以不用实现。
5、不能使用new操作符实例化一个接口,但可以声明一个接口变量,该变量必须引用(refer to)一个实现该接口的类的对象。可以使用 instanceof 检查一个对象是否实现了某个特定的接口。例如:if(anObject instanceof Comparable){}。
6、在实现多接口的时候一定要避免方法名的重复。
参考:http://blog.csdn.net/chenssy/article/details/12858267