Java 接口

1、接口的概念

类是一种具体的实现体,而接口定义了一种规范(抽象方法),接口定义了某一批类所需要遵循的规范,接口不关心类内部的属性和方法的具体实现,只规定这批类必须提供某些方法,提供这些方法的类就可满足对接口的使用。

接口是从多个相似类中抽象出来的规范,不提供具体的实现。

接口体现的是【规范】和【实现】分离的设计哲学。

接口是一种引用数据类型。

2、接口的定义

接口定义的基本语法:

[修饰符] interface 接口名称 extends 父接口1, 父接口2,...{
    // 静态常量
    // 抽象的实例方法(普通方法)
    // 内部类、内部接口、内部枚举(都是静态的)
    // 默认方法(实例方法,由接口的实现类的实例来调用)、类方法(静态方法)
    // 私有方法(java 9 提供)
}

说明:

  • 修饰符:public / 省略(包权限)
  • 接口名称和类名遵循相同命名规则
  • 类是单继承:一个类的直接父类只能有一个
  • 接口是多继承:一个接口的直接父类可以有多个
  • 接口只能继承接口,不能继承类;
    • 类与类之间是单继承;类与接口之间是多实现;接口与接口之间是多继承;接口不能继承类。
  • 接口是一种公共行为规范,不能包含构造器和代码块
  • 接口里的常量、方法(抽象方法、默认方法、类方法)、内部类、枚举、接口都是 public 访问权限
  • 私有方法既可以是类方法,也可以是实例方法
  • 默认方法使用 default 修饰(注:这里的 default 不是访问控制修饰符)

常量

语法格式:

[public] [static] [final] 变量名称 = 变量值;

抽象方法

接口里的普通方法默认为抽象方法。

语法格式:

[public] [abstract] 返回值类型 方法名称(形参列表);

默认方法

语法格式:

[public] default 返回值类型 方法名称(形参列表){
    // 方法体
}

静态方法

从 java 8 开始,允许在接口里定义类方法,类方法必须使用 static 修饰,不能使用 default 修饰。无论程序是否指定访问控制修饰符,类方法总是使用 public 修饰。

如果没有指定 public,系统会自动为类方法添加 public 修饰符。类方法可以直接使用接口来调用。

语法格式:

[public] static 返回值类型 方法名称(形参列表){
    // 方法体
}

实例私有方法

当两个默认方法(或类方法)中包含一段相同的实现逻辑时,程序必然考虑将这段实现逻辑抽取成工具方法,而工具方法是应该被隐藏的,这就是 java 9 增加私有方法的必然性。

实例私有方法:解决多个默认方法之间重复代码的问题。

静态私有方法:解决多个静态方法之间重复代码的问题。

私有方法只有接口自己才能调用,不能被实现类或别人调用

语法格式:

private 返回值类型 方法名称(形参列表){
    // 方法体
}

类私有方法

语法格式:

private static 返回值类型 方法名称(形参列表){
    // 方法体
}

示例

// 使用关键字 interface 定义一个接口
public interface InterfaceTest  {
   // 接口里没有构造器和代码块

   // 定义变量
   // 类常量 自动用 public static final 修饰
   public static final int MAX_SIZE = 20;

   // 定义方法
   // 抽象方法、默认(实例)方法、类方法 都用 public 修饰
   // 抽象方法
   public abstract void abstractMethod();

   // 类方法
   public static void staticMethod() {}

   // 默认方法(实例方法,由接口的实现类的实例来调用)
   public default void defaultMethod() {}

   // 私有方法(java9)
   /*private void privateMethod(){ }*/

   // 接口里定义:内部类、接口、枚举,自动用 public static 修饰
   // 静态内部类
   public static class StaticInnerClass {}
   // 接口
   public static Comparable COMPARABLE = null;
   // 枚举
   public static Enum ENUM = null;
}

3、接口的使用

接口的主要用途就是被实现类实现。

类实现接口的语法格式:

[修饰符] class 类名称 extends 基类 implements 接口1, 接口2, ...{
    
}

说明:

  • 继承使用 extends 关键字;实现使用 implements 关键字。
  • 一个类可以实现多个接口,也是 java 为单继承灵活性不足所做的补充。
  • 实现接口与继承父类类似,一样可以获得接口里常量(包括成员变量)、方法(包括默认方法和抽象方法)。
  • implements 部分必须放在 extends(如果有) 之后

在接口里声明引用类型变量 同样使用 public static final 修饰

不能直接使用接口来创建实例,但可以在接口里声明引用类型变量。

能够对实例进行初始化的地方有三个:声明的同时赋值,代码块、构造器。

因为接口里无代码块和构造器,所以一旦在接口里声明了引用类型变量,同时还要对它进行初始化赋值。

注:

1、实现接口里的方法时,必须使用 public 访问控制修饰符,因为接口里的方法都是 public 的,而子类(相当于实现类)重写父类方法时,访问权限只能更大或相等,所以实现类实现接口里的方法时只能使用 public 访问权限。

2、一个类实现了一个或多个接口之后,这个类必须完全实现(重写)这个接口里的所有抽象方法。否则将保留从父接口那继承的抽象方法,该类也必须定义为抽象类。

除了抽象方法之外,接口里的默认方法也可以被实现类覆盖重写。

默认方法,可以解决接口升级的问题

interface B {
	default void test(){
		System.out.println("B-->默认方法");
	}

}

class A implements B{
	@Override
	public void test() {
		System.out.println("A-->默认方法");

	}
}

注:

  1. 不能通过接口实现类(或者接口实现类对象)来调用接口中的静态方法
  2. 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
  3. 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。
  4. 如果实现类所实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
  5. 一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。
  6. 多个父接口当中的抽象方法如果重复,没关系。
  7. 多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,而且带着 default 关键字。

4、接口和抽象类

相同点

  • 无法实例化,用于被其他类实现或继承。
  • 都包含抽象方法,实现接口或继承抽象类的子类都必须实现这些抽象方法。

不同点(用法上)

  • 接口里的普通方法即为抽象方法;而抽象类既可以有普通方法,也可以有抽象方法
  • 接口里没有代码块和构造器;而抽象类里有
  • 接口里只有静态常量;而抽象类里可以有静态变量,也可以有实例变量
  • 接口之间可以是多继承;而抽象类的类与类之间也是单继承

接口主要是作为一种公共规范标准(通信标准、耦合标准)来使用。

而抽象类主要是一种模板式设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值