接口定义
接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法
(JDK 9),接口就是多个类的公共规范,接口是一种数据引用类型,其中重要内容是方法。
是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并
不是类,而是另外一种引用数据类型。(编译生成的字节码文件仍然是:.java -> .class
接口格式
public interface 接口名称 {
// 抽象方法
// 默认方法
// 静态方法
// 私有方法
// 常量
}
接口的使用步骤
1.接口不能直接使用,必须有一个“实现类”来“实现”该接口
//格式
public class 实现类名称 implements 接口名称{
}
2.接口的实现类必须覆盖重写(实现)接口中所有的抽象方法
实现:去掉abstract关键字,加上方法体大括号
3.创建实现类的对象进行使用
使用注意事项:
如果实现类没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。
抽象方法的使用
//定义接口
public interface MyInterfaceAbstract {
public abstract void method1();
public abstract void method2();
abstract void method3();
void method4();
}
//定义实现类
public class MyInterfaceAbatratImpl implements MyInterfaceAbstract {
@Override
public void method1() {
System.out.println("这是第一");
}
@Override
public void method2() {
System.out.println("这是第二");
}
@Override
public void method3() {
System.out.println("这是第三");
}
@Override
public void method4() {
System.out.println("这是第四");
}
}
//定义测试类
public class Demo01Interface {
public static void main(String[] args) {
MyInterfaceAbatratImpl impl=new MyInterfaceAbatratImpl();
impl.method1();
impl.method2();
}
}
注意点:
1.接口中的抽象方法修饰符必须是两个字符:public abstract
2.这两个关键字修饰符,可以选择性省略(可以全省略)
3.方法三要素,可以随意定义
默认方法的使用
接口中的默认方法用于解决接口升级的问题(当接口已经定义好,且有一些类适用这个接口,为了不影响这些类的使用,所有使用默认方法在接口里添加)
//定义接口
public interface Live {
public default void fly(){
System.out.println("在天上飞");
}
}
//定义实现类
public class Animal implements Live {
//自动继承默认方法,什么都不用写,直接用
//也可以在实现类里重写方法
}
//定义测试类
public class Test {
public static void main(String[] args) {
Animal a=new Animal();
a.fly(); //调用默认方法
}
}
注意事项:
- 定义默认方法时的public可以省略
- 接口的默认方法可以通过接口实现类对象直接调用
- 接口的默认方法,可以被接口实现类进行重写
静态方法的使用
静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
正确调用方法:通过接口名称直接调用其中的静态方法
格式:接口名称.静态方法名
//定义接口
public interface Live {
public static void run(){
System.out.println("在地上跑");
}
}
//定义实现类
public class Animal implements Live {
//无法重写静态方法
}
//定义测试类
public class Text {
public static void main(String[] args) {
// Animal animal=new Animal();
// animal.run(): 【错误】:无法继承静态方法,也无法调用
Live.run();
}
}
注意事项:
1.定义静态方法时的public可以省略
2.不能通过接口实现类的对象来调用接口中的静态方法
私有方法的使用(JDK9以上)
如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法
去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助。这个
这个方法是不让实现类使用的,是私有化的。
普通私有方法
私有方法:只有默认方法可以调用。解决多个默认方法重复问题。
//格式
private 返回值类型 方法名称(参数列表){
方法体
}
静态私有方法
私有静态方法:默认方法和静态方法可以调用。解决多个静态方法之间重复代码问题。
//格式
private static 返回值类型 方法名称(参数列表){
方法体
}
public interface Live {
default void func(){
fun1();
fun2();
}
private void fun1(){
System.out.println("跑起来");
}
private void fun2(){
System.out.println("跑起来");
}
}
接口的常量的使用
接口当中也可以定义“成员变量”,但必须是使用 public、static、final 三个关键字进行修饰,从效果看,这就是接口的【常量】
格式:
public static final 数据类型 常量名称 = 数据值;
//public代表公共的,static表示与对象无关,final是指不可变
//常量名称需要是大写 多个单词的话需要用下划线分割
//定义接口
public interface Live {
public static final int NUM_OF_MY=12;
}
//定义实现类
public class Number implements Live {
}
//定义测试类
public class Test {
public static void main(String[] args) {
System.out.println(Live.NUM_OF_MY); //用接口来调用
// Number number =new Number();
// number.NUM_OF_MY; 【错误】:不能用实现类对象调用
}
}
注意事项
1.接口中的常量,可以商量public static final
2.接口中的常量必须进行赋值,不能不赋值
3.接口当中的常量名称,使用完全大写的字母,用下划线进行分割
使用接口的注意事项
1.接口是没有静态代码和构造方法
2.一个类的直接父类是唯一的,但是一个类可以同时实现多个接口
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【不重名时可选】
}
//[ ]: 表示可选操作。
3.接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次。
//第一个接口
public interface InterfaceA {
public abstract void showA();
public abstract void show();
}
//第二个接口
public interface InterfaceB {
public abstract void showB();
public abstract void show();
}
//实现类
public class C implements InterfaceA,InterfaceB {
@Override
public void showA() {
}
@Override
public void showB() {
}
@Override
public void show() { //抽象方法有重名的,只需要重写一次
}
}
4.如果实现类没有覆盖重写所有接口中的所有抽象方法,那么实现类就必须是个抽象类
5.接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次。
//第一个接口
public interface InterfaceA {
public default void methodA(){}
public default void method(){}
}
//第二个接口
public interface InterfaceB {
public default void methodB(){}
public default void method(){}
}
//实现类
public class C implements InterfaceA,InterfaceB {
@Override
public void method() {
}
}
6.优先级问题:当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法。(继承优先于接口)
//定义接口
interface A {
public default void methodA(){
System.out.println("AAAAAAAAAAAA");
}
}
//定义父类
class D {
public void methodA(){
System.out.println("DDDDDDDDDDDD");
}
}
//定义子类
class C extends D implements A {
// 未重写methodA方法
}
//定义测试类
public class Test {
public static void main(String[] args) {
C c = new C();
c.methodA();
}
}
输出结果:
DDDDDDDDDDDD
接口的多继承
接口的继承使用 extends 关键字,子接口继承父接口的方法。
1.类与类之间是单继承的,直接父类只有一个
2.类与接口之间是多继承的,一个类可以实现多个接口
3.接口和接口之间是多继承的
//定义父接口
interface A {
public default void method(){
System.out.println("AAAAAAAAAAAAAAAAAAA");
}
}
interface B {
public default void method(){
System.out.println("BBBBBBBBBBBBBBBBBBB");
}
}
//定义子接口
interface D extends A,B{
@Override
public default void method() {
System.out.println("DDDDDDDDDDDDDD");
}
}
//子接口重写默认方法时,default关键字可以保留。
//子类重写默认方法时,default关键字不可以保留。
注意事项
1.如果父接口中的默认方法有重名的,那么子接口需要重写一次,而且带着default关键字。
2.多个父接口当中的抽象方法重复也没有关系。