写在前面:在我们的面试过程中,被问到最多的就是抽象类和接口,这也是重点和难点。这篇博客就为大家详细的介绍一下抽象类和接口的联系以及本质区别。
抽象类
首先我们要知道,Java作为一门面向对象(点击此处了解“Java面向对象”)的编程语言,类的概念是至关重要的,而类就是产生我们对象实例的一个蓝图和模板,有了类的出现,我们才产生不同的对象,这也反映出了Java的一大特性:多态。
Java中普通的类由属性、方法组成,而抽象类只是在普通类的基础上扩充了一些抽象方法而已,所谓的抽象⽅法指的是只声明⽽未实现的⽅法(即没有⽅法体)。所有抽象⽅法要求使⽤abstract关键字来定义,并且抽象⽅法所在的类也⼀定要使⽤abstract关键字来定义,表示抽象类。含有抽象方法的类一定是抽象类,但抽象类可以不含任何抽象方法。
下面是一个抽象类的例子:
abstract class Car{
private String style ; // 属性
public String getStyle(){ // 普通⽅法
return this.style;
}
public void setStyle(String style){
this.style = style ;
}
public abstract void getCarInfo() ; //抽象⽅法
}
上述代码有一个抽象方法 getCarInfo() 没有具体实现,因此抽象类不能直接产生实例化对象。
对于抽象类需注意以下几点:
1.抽象类不能被实例化(所有的抽象类必须有子类)
2.如果一个类(非抽象类)继承了抽象类,那一定得实现抽象父类的所有抽象方法(⽅法覆写⼀定要考虑权限问题,权限尽量都⽤public),在这里要注意,重写方法的时候: 派生类的访问权限一定要大于等于基类的访问权限
public > protected > 包访问权限(default)> private
3.如果抽象类继承了抽象类,那么派生抽象类可以不实现抽象父类的抽象方法
4.private和abstract 不能同时出现,不能是final修饰的方法或者类,因为抽象方法必须要能被覆写
5.抽象类的对象可以通过对象多态性利⽤⼦类为其实例化
6.抽象类中允许不定义任何的抽象⽅法,但是此时抽象类依然⽆法直接创建实例化对象
接口
抽象类与普通类相⽐最⼤的特点是约定了⼦类的实现要求,但是抽象类存在单继承局限。如果要约定⼦类的实现要求并避免单继承局限就需要使⽤接⼝。
接口的定义:接⼝就是抽象⽅法和全局常量的集合,在Java中接⼝使用interface关键字定义。
下面定义一个简单的接口:
interface ICar{
public static final String MSG = "I am a Car" ; // 全局常量
public abstract void print() ; // 抽象⽅法
}
为了区分接⼝,建议在所有接⼝前⾯追加字⺟I。
⼦类如果要想使⽤接⼝,那么就必须使⽤implements关键字来实现接⼝,同时,⼀个⼦类可以实现多个接⼝,使用“,”实现多个接口。【可以使⽤接⼝来实现多继承的概念】对于接⼝的⼦类(不是抽象类)必须覆写接⼝中的全部抽象⽅法。随后可以利⽤⼦类的向上转型通过实例化⼦类来得到接⼝的实例化对象。
对于接口需注意以下几点:
1.接⼝中只允许public权限。(不管是属性还是⽅法,其权限都是public)由于接口是抽象⽅法和全局常量的集合,所以以上代码可以简写为:
interface ICar{
String MSG = "I am a Car" ; // 全局常量
void print() ; // 抽象⽅法
}
2.当⼀个⼦类即需要实现接⼝⼜需要继承抽象类时,请先使⽤extends继承⼀个抽象类,⽽后使⽤implements实现多个接⼝
3.⼀个抽象类可以使⽤implements实现多个接⼝,但是接⼝不能继承抽象类(因为抽象类里面有已经实现的方法)
4.⼀个接⼝可以使⽤extends继承多个⽗接⼝,此时的接口拥有了继承接口里面的抽象方法
5.接口不能直接进行实例化
6.如果一个抽象类继承了接口,那么抽象类中可以不实现接口中的抽象方法。但是,如果再有一个普通类继承了此抽象类那么普通类一定要实现接口和抽象类里面的抽象方法
7.在以后的开发过程之中,⼀个操作既可以使⽤抽象类⼜可以使⽤接⼝的时候,优先考虑使⽤接⼝
一张表来对比抽象类和接口
针对这个在面试中令人头疼的问题,以上是对抽象类和接口的一些详细总结,供大家参考。