抽象类与接口经常在面试中被问到,因为这两者有相似点,而且最关键的是这两个对于编写可扩展性的java代码有着非常重要的作用。所以今天重新屡屡他们的区别,联系与使用场景.
抽象类
public abstract class Person {
//可以有成员
private String name;
public abstract void eat();
public void say(){
}
}
抽象类就是使用 abstract 关键字修饰的类,抽象类可以没有抽象方法,也可以有抽象方法。一个类只要包含一个或多个抽象方法,那么该类必须声明为抽象类。
接口
public interface Perfomance{
//接口可以有成员
String name="李幼斌";
void act();
}
接口是使用 interface 关键字修饰
抽象类的特征:
抽象类的初衷是“抽象”,即规定这个类“是什么”,具体的实现暂不确定,是不完整的,因此不允许直接创建实例。
- 抽象类是由子类具有相同的一类特征抽象而来,也可以说是其基类或者父类
- 抽象方法必须为 public 或者 protected(因为如果为 private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为 public
- 抽象类不能用来创建对象
- 抽象方法必须由子类来实现
- 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法,如果子类没有实现父类的抽象方法,则必须将子类也定义为抽象类
- 抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动
接口的特征
接口是抽象类的延伸,它可以定义没有方法体的方法,要求实现者去实现。
- 接口的所有方法访问权限自动被声明为 public
- 接口中可以定义“成员变量”,会自动变为 public static final 修饰的静态常量
- 可以通过类命名直接访问:ImplementClass.name
- 不推荐使用接口创建常量类
- 实现接口的非抽象类必须实现接口中所有方法,抽象类可以不用全部实现
- 接口不能创建对象,但可以申明一个接口变量,方便调用
完全解耦,可以编写可复用性更好的代码
抽象类与接口的区别
- 抽象层次不同
1.抽象类是对类抽象,而接口是对行为的抽象
2.抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类进行抽象 - 跨域不同
1.抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类
2.抽象类所体现的是一种继承关系,考虑的是子类与父类本质“是不是”同一类关系而接口并不要求实现的类与接口是同一本质,它们之间只存在“有没有这个能力”的关系 - 设计层次不同
1.抽象类是自下而上的设计,在子类中重复出现的工作,抽象到抽象类中
2.接口是自上而下,定义行为和规范
关于抽象类与接口在实际使用中的思考:
- 抽象类主要用于基类,封装重复的内容。可能有人会说,基类为什么非要用抽象类呢,普通类不可以吗?普通类是可以用做基类,但是抽象类可以有抽象方法,子类如果继承的是抽象类,那么创建子类对象的时候,必须实现基类的抽象方法,这就是定义一种规范,让子类必须按照这个规范去实现,可以让子类与基类的代码风格保持一致性,而普通类就不可以。
2.接口最主要的作用是可以对功能进行扩展,使实现类可以向上转型,同时还能避免 java单继承多实现的问题。
举个例子:我们点击RecyclerView的item,想做跳转的功能,一般是在Activity中使用Adapter.setOnItemClickListener(this),this指代的就是当前Activity,而Activity实现了OnItemClickListener接口。我们知道在Adapter(独立出来,并不在Activity里面创建内部类)里面是不可以直接调用startActivty()的,要调用必须在startActivity前面加个Context,Acvity就是Context的子类,所以在Activity里面可以,但是在Adapter里面不行。那么问题来了,假如我非要在Adapter里面调用呢,有2种方式:
a,在Adapter的构造函数里面传入一个Activity对象,然后在Adaper里面使用这个activity对象调用startActivity;
b,在Adapter里面提供一个接口,暴露出去,让Activity实现,在Activty里面做点击跳转;
两种方式可以明显的看出使用接口回调,暴露接口的方式更好,因为Activity里面可以很清楚的看到点击item的时候从当前界面跳到哪里去,如果写在Adapter里面还要去找,另外可以做到职责分离。让Activity做界面该做的,Adapter只做数据绑定。这个例子中,就是对Activity做了功能扩展,使得Activity具备了点击Adapter的item跳转界面的能力。Activity的类型也向上转型到了onItemClickListener类型,Adapter在调用OnItemClickLister的onItemClick()的时候就指向了Activity的onItemClick,同时Activity还可以继承基类BaseActivity.
抽象类与接口是java面向对象的三大特征里面多态的重要实现方式,具体灵活使用还要在项目中多多思考和练习.