学习资源:拉勾教育
接口的基本概念
- 接口就是一种比抽象类还抽象的类,体现在所有方法都为抽象方法。
- 定义类的关键字是class,而定义接口的关键字是
interface
。 - 接口概念的提出可以弥补Java不能多继承的不足,因为接口支持多实现
implements
public interface InterfaceTest {
/*public static final*/ int CNT = 1; // 里面只能有常量
//private void show(){} // 从Java 9开始允许接口中出现私有方法
/*public abstract*/ void show(); // 里面只能有抽象方法(新特性除外),注释中的关键字可以省略,但建议写上
}
public interface Metal {
// 自定义抽象方法描述发光的行为
public abstract void shine();
}
public interface Money {
// 自定义抽象方法描述购物的行为
public abstract void buy();
}
// 使用implements关键字表达实现的关系,支持多实现
public class Gold implements Metal, Money{
@Override
public void shine() {
System.out.println("发出金黄色的光芒。。。");
}
@Override
public void buy() {
System.out.println("可以买好多好吃的。。。");
}
public static void main(String[] args) {
// 1.声明接口类型的引用指向实现类的对象 形成了多态
Metal mt = new Gold();
mt.shine();
Money mn = new Gold();
mn.buy();
}
}
练习题目
- 编程实现Runner接口,提供一个描述奔跑行为的抽象方法。
- 编程实现Hunter接口继承Runner接口,并提供一个描述捕猎行为的抽象方法。
- 编程实现Man类实现Hunter接口并重写抽象方法,在main方法中使用多方式测试。
public interface Runner {
// 自定义抽象方法描述奔跑的行为
public abstract void run();
}
// 接口只能继承接口,不能继承类
public interface Hunter extends Runner{
// 自定义成员方法描述捕猎的行为
public abstract void hunt();
}
public class Man implements Hunter{
@Override
public void hunt() {
System.out.println("正在追赶一只小白兔。。。");
}
@Override
public void run() {
System.out.println("正在被一只熊追赶,玩命奔跑中。。。");
}
public static void main(String[] args) {
// 1.声明接口类型的引用指向实现类的对象 形成了多态
Runner runner = new Man();
runner.run();
Hunter hunter = new Man();
hunter.hunt();
}
}
类和接口之间的关系
名称 | 关键字 | 关系 |
---|---|---|
类和类之间的关系 | 使用extens 关键字表达继承关系 | 支持单继承 |
类和接口之间的关系 | 使用implements 关键字表达实现关系 | 支持多实现 |
接口和接口之间的关系 | 使用extend 关键字表达继承关系 | 支持多继承 |
接口和抽象类的主要区别(笔试要点)
- 定义抽象类的关键字是
abstract class
,而定义接口的关键字是interface
。 - 继承抽象类的关键字是
extends
,而实现接口的关键字是implements
。 - 继承抽象类支持
单继承
,而实现接口支持多实现
。 - 抽象类中可以
有构造方法
,而接口中不可以有构造方法
。 - 抽象类中可以有
成员变量
,而接口中只可以有常量
。 - 抽象类中可以有
成员方法
,而接口中只可以有抽象方法
。 - 抽象类中增加方法时子类可以
不用重写
,而接口中增加方法时实现类需要重写
(Java8以前的版本)。 - 从Java8开始增加新特性,接口中允许出现
非抽象方法
和静态方法
,但非抽象方法需要使用default
关键字修饰。 - 从Java9开始增加新特性,接口中允许出现
私有方法
。
public interface Runner {
// 自定义抽象方法描述奔跑的行为
public abstract void run();
}
// 接口只能继承接口,不能继承类
public interface Hunter extends Runner{
// 自定义成员方法描述捕猎的行为
public abstract void hunt();
// 将两个默认方法中重复的代码可以提取出来打包成一个方法在下面的两个方法中分别调用即可
// 这里show方法的作用仅仅是为了减少代码的冗余,没必要让实现类去实现这个方法,所以设为private
private void show() {
System.out.println("在以后的开发中尽量减少重复的代码,也就是减少代码的冗余!");
}
// 增加一个抽象方法
//public abstract void show1();
// 增加非抽象方法
public default void show1() {
show();
//System.out.println("在以后的开发中尽量减少重复的代码,也就是减少代码的冗余!");
System.out.println("show1()方法中:这里仅仅是接口中的默认功能,实现类可以自由选择是否重写!");
}
// 增加非抽象方法
public default void show2() {
show();
//System.out.println("在以后的开发中尽量减少重复的代码,也就是减少代码的冗余!");
System.out.println("show2()方法中:这里仅仅是接口中的默认功能,实现类可以自由选择是否重写!");
}
// 增加静态方法 隶属于类层级,也就是接口层级
public static void test() {
System.out.println("这里是静态方法,可以直接通过接口名.的方式调用,省略对象的创建");
}
}
public class Man implements Hunter{
@Override
public void hunt() {
System.out.println("正在追赶一只小白兔。。。");
}
@Override
public void run() {
System.out.println("正在被一只熊追赶,玩命奔跑中。。。");
}
@Override
public void show1() {
System.out.println("看心情重写一下。。。");
}
public static void main(String[] args) {
// 1.声明接口类型的引用指向实现类的对象 形成了多态
Runner runner = new Man();
runner.run();
Hunter hunter = new Man();
hunter.hunt();
hunter.show1();
hunter.show2();
System.out.println("------------------------");
// 2.可以使用接口名称.方式调用接口中的静态方法
Hunter.test();
}
}