接口
interface 接口名 {
接口体;
}
访问修饰符 类名 implements 接口名 {
类体;
}
1、接口不能被实例化
2、接口的修饰符只能为 public 或默认
3、接口允许存在属性,接口中的属性隐式声明为 public static final,且声明不能更改
4、接口的方法
(1)JDK 8 版本之前,接口所有方法都是抽象方法
(2)JDK 8(包括 JDK 8)版本之后,接口有默认方法、静态方法,即有方法的具体实现
(3)接口隐式声明所有方法为 public abstract,除非显式声明 default 以覆盖 abstract
5、接口不能继承类,但可以继承多个接口
interface 接口1 extends 接口2, 接口3 {
接口体;
}
6、类不能继承接口,可以继承类的同时,实现多个接口
访问修饰符 class 类1 extends 类2 implements 接口1, 接口2 {
类体;
}
(1)普通类必须把所有接口的所有抽象方法实现
(2)抽象类可以不实现接口的抽象方法
接口的多态
1、向上转型:接口引用可以指向实现接口的类的对象
2、多态数组(向上转型):接口类型数组可以接收实现接口的类的对象
3、多态参数(向上转型):方法定义时,形参类型为接口类型,允许实参是实现该接口的类的对象
4、多态传递:一个类实现一个接口,若该接口继承了其他接口,则该类就实现了所有接口
default 方法
1、实现类会继承接口中的 default 方法
2、一个类实现多个接口,存在多个同名的 default 方法,该类必须要重写同名方法
(1)如果该同名方法的方法名、形参列表、返回数据类型都一样,那么该类只需要重写其中一个方法即可
@Override
访问修饰符 返回数据类型 方法名(形参列表) {
方法体;//重写接口的默认同名方法,是子类的另一种实现
}
@Override
访问修饰符 返回数据类型 方法名(形参列表) {
接口名.super.方法名;//使用 super 调用指定接口的默认方法
}
(2)如果该同名方法的方法名、形参列表、一样,返回数据类型不一样,需要分别重写返回值不同的同名方法,但只能重写一个方法,只重写一个是无法编译的
(3)如果该同名方法的方法名、返回数据类型一样,形参列表不一样,则该类就继承所有同名方法,实现方法重载
3、一个类继承父类,该子类同时实现接口,父类方法与接口 default 方法是同名方法
(1)如果该同名方法的方法名、形参列表、返回数据类型都一样,子类会继承父类的方法而不是继承接口的方法
(2)如果该同名方法的方法名、形参列表、一样,返回数据类型不一样,需要分别重写返回值不同的同名方法,但只能重写一个方法,只重写一个是无法编译的
(3)如果该同名方法的方法名、返回数据类型一样,形参列表不一样,则该类就继承所有同名方法,实现方法重载
4、如果一个类的默认方法使用相同的函数签名继承自多个接口,只需要遵守下面这三条准则就能解决所有可能的冲突
(1)首先,类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级
(2)如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果 B 继承了 A ,那么 B 就比 A 更加具体(就近原则)
(3)最后,如果还是无法判断,那么继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现
嵌套接口
1、在类中嵌套接口的语法相当明显。就像非嵌套接口一样,它们可以具有 public 或包访问权限的可见性
2、类中 private 的嵌套接口
(1)实现了 private 接口的话,可以在不添加任何类型信息的情况下,限定该接口中的方法定义(也就是说,不允许任何向上转型)
(2)外部类的 public 方法返回内部 private 接口的引用,该返回值必须传递给一个有权使用它的对象,即 private 接口的外部类,接口本身或内部实现类都无权使用
(3)private 接口不能在它们的定义类之外实现
3、接口之间也可以嵌套,嵌套在另一个接口中的接口自动为 public 的,不能设为 private
4、当实现一个接口时,并不需要实现嵌套在其中的接口
新特性
1、JDK 8
(1)default:被 default 修饰的方法可以存在方法实现。即可以利用 default 在接口中声明普通的方法
(2)static:接口可以存在静态方法
(3)规定接口的所有成员必须是 public
(4)表示 default 则为普通方法、所以 default、static 不能组合使用
2、JDK 9
(1)规定接口中可以存在 private static 方法,但是 static 字段和 static 成员类仍然需要是 public
(2) 使用 private 修饰方法后,隐式添加 default
3、JDK 17
(1)密封(sealed)类和密封接口,因此基类或接口可以限制自己能派生出哪些类,这可以对一组固定种类的值进行建模
(2)如果尝试继承未在 permits 子句中列出的子类,比如 D3,则编译器会产生错误
sealed class Base permits D1, D2 {}
final class D1 extends Base {}
final class D2 extends Base {}
// 非法:
// final class D3 extends Base {}
(3)可以密封接口和抽象类
sealed interface Ifc permits Imp1, Imp2 {}
final class Imp1 implements Ifc {}
final class Imp2 implements Ifc {}
sealed abstract class AC permits X {}
final class X extends AC {}
(4)如果所有的子类都定义在同一个文件中,则不需要 permits 子句
sealed class Shape {}
final class Circle extends Shape {}
final class Triangle extends Shape {}
(5)permits 子句允许我们在单独的文件中定义子类
// interfaces/SealedPets.java
sealed class Pet permits Dog, Cat {}
// interfaces/SealedDog.java
final class Dog extends Pet {}
// interfaces/SealedCat.java
final class Cat extends Pet {}
(6)sealed 类的子类只能通过下面的某个修饰符来定义
final:不允许有进一步的子类
sealed:允许有一组密封子类
non-sealed:一个新关键字,允许未知的子类来继承它
(7)注意,一个 sealed 类必须至少有一个子类
(8)一个 sealed 的基类无法阻止 non-sealed 的子类的使用,因此可以随时放开限制
//Sub2 允许任意数量的子类,因此它似乎放开了对可以创建的类型的控制,但还是严格限制 sealed 类 Super 的直接子类,即 Super 仍然只能有直接子类 Sub1 和 Sub2
sealed class Super permits Sub1, Sub2 {}
final class Sub1 extends Super {}
non-sealed class Sub2 extends Super {}
class Any1 extends Sub2 {}
class Any2 extends Sub2 {}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战