记得上次阿里二面的时候就问了抽象类和接口的问题,当时回答的不太全面.这次又学到了,就做一个比较详细的总结.
一.抽象类与接口的定义
抽象类与接口都是java中一种更高层次上的抽象.
抽象类:我们用abstract关键字定义抽象类和抽象方法,抽象方法指的是只有定义没有实现的方法,并且规定如果一个类包含一个或者多个抽象方法,则一定要声明为抽象类.抽象类中也可以包含普通的方法,甚至完全没有抽象方法都是普通方法也是可以的(这种情况可能发生在我们不希望这个类创建对象).抽象类的一个重要特点就是不能用来创建对象,只能用来继承.对于抽象类的子类,如果是普通类,那么就一定要实现抽象类中的所有抽象方法,如果仍是抽象类,那么也可以不实现.
接口:我们用interface关键字定义接口.接口可以看成一个极度抽象的类,因为java规定接口中的所有方法都只能有声明不能有实现.如果想继承一个接口,我们使用implements关键字;如果一个类继承了一个接口,那么这个类就必须实现这个接口中的所有的方法;当然接口之间也是可以相互的继承的.对于接口来讲其中的所有方法都必须是public权限的,你可以显式的这样声明但是实际上默认的权限就是public的.
一个实例:在前面学习多态的时候我们定义了一个Cycle基类,和Bicycle,Tricycle,Unicycle三个子类.这几个类中有一个共同的方法wheels(),用于返回其轮子的数目,但是其实因为基类不是一种具体的cycle,他的wheels()是不应该有定义的(前面我是将他的返回值定为0),并且我们也不应该允许Cycle类创建一个对象(因为它的对象意义不明确).所以下面我们用接口和抽象类的形式分别改写代码.
package lkl;
///将基类定义成抽象类
public abstract class Cycle {
///Cycle中的wheels()方法只有声明没有实现
public abstract int wheels();
}
public class Unicycle extends Cycle{
public int wheels(){
return 1;
}
}
public class BiCycle extends Cycle{
public int wheels(){
return 2;
}
}
public class Tricycle extends Cycle{
public int wheels(){
return 3;
}
}
public class RideTest {
public int wheels(Cycle cy){
return cy.wheels();
}
public static void main(String[] args){
//Cycle cy = new Cycle(); 试图创建一个抽象类的对象出错
RideTest rt = new RideTest();
///根据传入的不同子类表现不同的行为,称为多态
System.out.println("Unicylce‘s wheels: "+rt.wheels(new Unicycle()));
System.out.println("Bicycle‘s wheels: "+rt.wheels(new BiCycle()));
System.out.println("Tircycle‘s wheels: "+rt.wheels(new Tricycle()));
}
}
package lkl;
///将Cycle定义为接口
public interface Cycle {
///interface中的方法总是public权限的,即使你没有显式声明
int wheels();
//private int f(); 试图声明一个private权限的方法出错
}
public class Unicycle implements Cycle{
public int wheels(){
return 1;
}
}
public class BiCycle implements Cycle{
public int wheels(){
return 2;
}
}
public class Tricycle implements Cycle{
public int wheels(){
return 3;
}
}
package lkl;
public class RideTest {
public int wheels(Cycle cy){
return cy.wheels();
}
public static void main(String[] args){
RideTest rt = new RideTest();
///根据传入的不同子类表现不同的行为,称为多态
System.out.println("Unicylce‘s wheels: "+rt.wheels(new Unicycle()));
System.out.println("Bicycle‘s wheels: "+rt.wheels(new BiCycle()));
System.out.println("Tircycle‘s wheels: "+rt.wheels(new Tricycle()));
}
}
从上面的代码可以看出,无论是普通基类,还是抽象基类或是接口,整体的结构是类似的.另外还有一个很重要的现象:这二种结构中都表现出来多态性,这说明无论是向上转型成接口或是抽象类,对多态性没有影响.
二.抽象类和接口的区别.
尽管接口和抽象类看起来很是相似,但他们之间还是存在很多的不同点.
(1).抽象类毕竟还是类,所以用class关键字声明然后用extends关键字继承.接口用interface声明,implements继承.
(2).接口中方法权限必须是public,变量是static final型常量;抽象类中的方法权限可以自己设定,变量也一样.
(3).接口中的所有方法都必须是抽象的而抽象类中可以是抽象的也可以是普通的.
(4).最后也是最重要的一点区别是:接口支持多重继承而抽象类是不可以的!这一点带来的一个好处就是,我们能够将一个类向上转型成多个基类.
原文地址:http://blog.csdn.net/acm_lkl/article/details/46044385