假如一个抽象类中只有抽象方法,则就可以使用接口完成
接口(interface)
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现接口的方式,从而来实现接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
接口特性:
- 使用interface关键字。
- 接口没有构造方法,不能用于实例化对象。
- 实现类必须重写接口中所有的抽象方法,否则就必须声明为抽象类。
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,其他修饰符都会报错)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
注:JDK 1.8 以后,在JDK1.7的基础上增加了static静态方法和default默认方法。
抽象类(abstract class)
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
抽象类特性:
- 抽象类、抽象方法使用abstract关键词完成。
- 抽象类可以定义构造方法,不能被实例化。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类中的抽象方法只是声明,不包含方法体body。
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
- 抽象类的方法默认访问权限为protected。
注意:JDK 1.8 以后,抽象类的方法默认访问权限变为default。
继承与实现
Java中,类只支持单继承,而接口支持多继承。
- 类与类之间是继承,并且是单继承(extends)
- 接口与接口之间是继承,并且是多继承(extends)
- 类与接口之间是实现,并且是多实现(implements)
注意:接口不能继承类
如果一个类既有继承也有实现,则继承必须位于实现的前面。
补充:
default默认方法的意义:
当一个接口添加新方法时,需要所有的实现类都重写新方法,影响到了已有的实现类,可能导致应用崩溃,而default默认方法可以不强制重写,也不会影响到已有的实现类。
default默认方法和static静态方法的使用:
1 .default方法和static方法必须要有方法体body。
2 .default方法可按个人需求自行选择是否进行重写。
- 如果没有重写,调用接口中的default方法则必须通过实现类的对象调用。
- 如果进行了重写,调用接口中的default方法则只能在重写的方法里通过super关键字进行调用,例如:接口名.super.方法名();。
3 .static方法不能被重写,static方法只能通过接口调用。
注意:如果有两个接口中的静态方法一模一样,并且一个实现类同时实现了这两个接口,此时并不会产生错误,因为jdk8只能通过接口类调用接口中的静态方法,所以对编译器来说是可以区分的。但是如果两个接口中定义了一模一样的默认方法,并且一个实现类同时实现了这两个接口,那么必须在实现类中重写默认方法,否则编译失败。
什么是实例化?
Vehicle veh1 = new Vehicle();
通常把这条语句的动作称之为创建一个对象,也就是实例化
1)右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。
2)末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。
3)左边的“Vehicle veh1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。
4)“=”操作符使对象引用指向刚创建的那个Vehicle对象。
为什么接口中的属性必须是public static final修饰的?
public:使接口的实现类可以使用这个常量。
static:static修饰就表示它属于类的,随着类的加载而存在的,如果是非static类型的话,就表示属于对象的,只有建立对象时才有它,而接口是不能建立对象的,所以接口的常量必须定义为static。
final:final修饰就是保证接口定义的常量不能被实现类修改造成混乱。如果变量不是final,那么每个实现类都可以更改这个变量的值,这也就违反了OCP(开闭原则)原则。