抽象方法 即使用abstract 关键字修饰,仅有声明没有方法体的方法。
public abstract void f();//没有内容
抽象类即包含抽象方法的类。
如果一个类包含一个或者多个抽象方法,该类必须限定为抽象的。抽象类可以不包含抽象方法。
public abstract class BaseActivity{
private final String TAG =this.getClass().getSimpleName();//抽象类可以有成员
void log(String msg){
System.out.println(msg);//抽象类可以有具体方法
}
//abstract void initView();// 抽象类也可以没有抽象方法
}
接口是抽象类的一种特殊形式,使用interface 修饰。
接口是抽象类的延伸,它可以定义没有方法体的方法
public interface OnClickListener{
void onClick(View v);//没有方法体
}
特点与区别:
抽象类的特点
- 抽象类的初衷是“抽象”,即规定这个类“是什么”,具体的实现暂不确定,是不完整的,因此不允许直接创建实例。
- 抽象类是由子类具有相同的一类特征抽象而来,也可以说是其基类或者父类
- 抽象方法必须为 public 或者 protected(因为如果为 private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为 public
- 抽象类不能用来创建对象
- 抽象方法必须由子类来实现
- 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法,如果子类没有实现父类的抽象方法,则必须将子类也定义为抽象类
- 抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动
接口的特点:
Java 为了保证数据安全性是不能多继承的,也就是一个类只有一个父类。
但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多继承的缺陷。
接口是抽象类的延伸,它可以定义没有方法体的方法,要求实现者去实现。
接口的所有方法访问权限自动被声明为 public
接口中可以定义“成员变量”,会自动变为 public static final 修饰的静态常量
- 可以通过类命名直接访问:ImplementClass.name
- 不推荐使用接口创建常量类
实现接口的非抽象类必须实现接口中所有方法,抽象类可以不用全部实现
接口不能创建对象,但可以申明一个接口变量,方便调用
完全解耦,可以编写可复用性更好的代码
例子:
假设我们新开始一个项目,需要写大量的 Activity,这些 Activity 会有一些通用的属性和方法,于是我们会创建一个基类,把这些通用的方法放进去:
public class BaseActivity extends Activity{
private final String Tag =this.getClass().getSimpleName();
void toast(String msg){
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
}
//其他重复的工作,比如设置标题栏、沉浸式状态栏、检测网络状态等
}
这时 BaseActivity
是一个基类,它的作用就是:封装重复的内容。
写着写着,我们发现有的同事代码写的太烂了,一个方法里几百行代码,看着太痛苦。于是我们就本着“职责分离”的原则,在 BaseActivity
里创建了一些抽象方法,要求子类必须实现:
public abstract class BaseActivity extends Activity {
private final String TAG = this.getClass().