目录
今天来研究一些之前学习遗留的问题,没有认真去解决到的问题,本博文的主题是总结一下抽象类abstract与接口 interface 的区别
一、抽象类(abstract)
在了解抽象类之前,我们先要了解到抽象方法,那么什么是抽象方法呢?
抽象方法是一种特殊的方法,他只有声明,而没有具体的实现
abstract void fun();
抽象方法必须使用abstract修饰,如果一个类含有抽象类的方法,那么这个类被称为抽象类,抽象类必须再类前使用abstract修饰,因为抽象类中含有无具体实现的方法,所以不能用抽象类实例化一个具体的对象
抽象类是为了继承而存在的,如果定义了一个抽象类,而不去继承它,那么你等于白白创建了这个抽象类,因为不能用抽象类来做任何事情。
包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,也可以和普通类一样拥有属性和方法,抽象类和普通类的主要区别有三点
·抽象方法必须为public或者protected修饰(为什么不能为private修饰的呢?因为如果为private修饰的,则不能被子类所继承,子类便无法实现抽象方法)没有写的话默认为public修饰
·抽象类不能被实例 化为一个具体的对象
·如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法,如果子类没有实现父类的抽象方法,那么需要将子类定义为abstract类
二、接口(interface)
接口泛指别人调用的方法或者函数,在Java中,一个接口定义形式如下
public interface Animal{ }
接口中可以含有变量和方法,但是要注意,接口中的属性会被指定为public static final变量,并且只能是public static final变量,使用private修饰的话会编译错误。而方法会被指定为public abstract方法且只能是public abstact方法(使用其他类型修饰会报错)并且接口中所有的方法不能有具体的实现,换个说法就是,接口类中的方法必须都是抽象方法(ps:那么是否可以有具体的实现方法呢?在JDK1.8中可以定义default修饰的方法,JDK1.9中可以有private修饰的方法)从这里可以看出,接口是一种极度抽象的类型,是>抽象类的,并且一般情况下不会再接口中定义变量
对于在JDK1.8中定义default类型修饰的方法的代码也是有的,博主最近在练习排序算法,每天的练习就是使用default方法,简单放一块代码
public interface Sort { public void sort(int[] array); public default void swap(int[] array,int i,int j){ int tmp=array[i]; array[i]=array[j]; array[j]=tmp; } }
public class mergersort implements Sort{ /** * 归并排序 * 时间复杂度O(N*log2^N) * 空间复杂度O(N) * 稳定性:稳定 * @param array */ @Override public void sort (int[] array) { mergersort(array,0,array.length-1); } public static void mergersort(int[] array,int left,int right){ if(left>=right){ return ; } int mid=left+((right-left)>>>1); mergersort(array,left,mid); mergersort(array,mid+1,right); merger(array,left,mid,right); } public static void merger(int[] array,int left,int mid ,int right){ int[] ret=new int[(right-mid)+(mid-left)+1]; int k=0; int s1=left; int s2=mid+1; while(s1<=mid && s2<=right){ if(array[s1]<array[s2]){ ret[k++]=array[s1++]; }else { ret[k++]=array[s2++]; } } while(s1<=mid){ ret[k++]=array[s1++]; } while(s2<=right){ ret[k++]=array[s2++]; } for (int i = 0 ; i < k ; i++) { array[i+left]=ret[i]; } } }
而且一个类只能继承一个抽象类,但是一个类可以遵循多个特定的接口,如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法
三、抽象类和接口的区别
·抽象类可以提供成员方法的实现,而接口中只能存在public abstract方法(JDK1.8以及JDK1.9之后不讨论)
·抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的
·接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态反方
·一个类只能继承一个抽象类,而一个类可以实现多个接口
四、总结
参数 | 抽象类 | 接口 |
默认的方法实现 | 可以有默认的方法实现 | 不存在方法的实现(JKD1.8以及之后不讨论) |
实现 | 子类使用extends继承抽象类,如果子类不是抽象类则需要实现父类中所有声明的方法 | 子类使用关键字implements来实现接口,他需要提供接口中所有声明的方法的实现 |
构造器 | 可以有 | 不能有 |
比较普通类 | 不能实例化具体的类 | 完全不同的类型 |
访问修饰符 | 抽象方法可以有public、protected、default修饰符 | 接口方法默认为public |
main | 抽象方法可以有main方法并且可以运行 | 接口不能有main方法 |
速度 | 相比较运行速度是大于接口的 | 稍慢,因为需要时间寻找类找那个实现的方法 |
添加新方法 | 只需要提供默认的实现 | 必须改变实现该接口的类 |