Java基础之接口
接口就是一种公共的规范标准,只要符合规范标准就可以通用
接口就是多个类的公共规范,接口是一种引用数据类型,最重要的内容就是:抽象方法
如果是Java7:那么接口可以包含的内容有:
-
常量
-
抽象方法
如果是Java8,还可以额外包含有:
-
默认方法
-
静态方法
如果是java9,还可以额外包含有
-
私有方法
接口当中定义抽象方法
在任何版本的java中接口都可以定义抽象方法
注意:
-
接口当中的抽象方法,修饰符必须是两个固定的关键字 public abstract
-
这两个关键字修饰符,可以选择性的省略
-
方法的三要素,可以随意定义
package com.dcits.day09.demo01; public interface MyInterfaceAbstract { // 这是一个抽象方法 public abstract void method1(); // 这是一个抽象方法 abstract void method2(); // 这是一个抽象方法 public void method3(); // 这是一个抽象方法 void method4(); }
接口的使用步骤
-
接口不能直接使用,必须有一个实现类来实现接口
-
接口的实现类必须覆盖重写接口中所有的抽象方法
-
创建实现类的对象,进行使用
注意:如果实现类没有覆盖重写接口中所有的抽象方法,那么这个实现类自己必须是抽象类
// 接口类 package com.dcits.day09.demo01; public interface MyInterfaceAbstract { // 这是一个抽象方法 public abstract void method1(); // 这是一个抽象方法 abstract void method2(); // 这是一个抽象方法 public void method3(); // 这是一个抽象方法 void method4(); } // 接口实现类 package com.dcits.day09.demo01; public class MyInterfaceAbstractImpl 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("这是第四个方法!"); } } // 调用 package com.dcits.day09.demo01; public class Demo01Interface { public static void main(String[] args) { // MyInterfaceAbstract inter = new MyInterfaceAbstract() 此写法是错误的不能直接new接口对象进行使用 MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl(); impl.method1(); impl.method2(); } }
接口的默认方法定义
从java8开始允许定义默认方法
备注:接口当中的默认方法可以解决接口升级的问题
注意:
-
接口的默认方法,可以通过接口实现类对象,直接调用
-
接口的默认方法,也可以被接口实现类进行覆盖重写
// 接口类 package com.dcits.day09.demo01; public interface MyInterfaceDefault { // 抽象方法 public abstract void methodAbs(); // public abstract void methodAbs1(); // 新添加的方法改成默认方法就可以解决问题 public default void methodDefault() { System.out.println("这是一个默认的方法!!"); } } // 接口实现类A package com.dcits.day09.demo01; public class MyInterfaceDefaultA implements MyInterfaceDefault { @Override public void methodAbs() { System.out.println("AAA"); } } // 接口实现类B package com.dcits.day09.demo01; public class MyInterfaceDefaultB implements MyInterfaceDefault { @Override public void methodAbs() { System.out.println("BBB"); } @Override public void methodDefault() { System.out.println("实现类B覆盖重写了接口类的默认方法"); } } // 调用 package com.dcits.day09.demo01; public class Demo02Interface { public static void main(String[] args) { MyInterfaceDefaultA a = new MyInterfaceDefaultA(); a.methodAbs(); // 调用默认方法,如果实现类当中没有,会向上找接口 a.methodDefault(); MyInterfaceDefaultB b = new MyInterfaceDefaultB(); b.methodAbs(); // 当接口的实现类中有默认方法,则调用自己的默认方法 b.methodDefault(); } }
接口的静态方法定义
从Java8开始,接口当中允许定义静态方法
注意:不能通过接口实现类的对象来调用接口类当中的静态方法
正确用法:通过接口名称,直接调用其中的静态方法
// 接口类 package com.dcits.day09.demo01; public interface MyInterfaceStatic { public static void methodStatic() { System.out.println("接口类中的静态方法"); } } // 调用接口类中的静态方法 package com.dcits.day09.demo01; public class Demo03Interface { public static void main(String[] args) { MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl(); // 错误写法 // impl.methodStatic(); // 直接使用接口类调用即可 MyInterfaceStatic.methodStatic(); } }
接口类的私有方法
从Java9开始,接口当中允许定义私有方法
-
普通私有方法:解决多个默认方法之间重复代码的问题
-
静态私有方法:解决多个静态方法之间重复代码的问题
// 接口类中的私有默认方法 package com.dcits.day09.demo01; public interface MyInterfacePrivateA { public default void methodDefault1() { System.out.println("默认方法1"); methodCommon(); } public default void methodDefault2() { System.out.println("默认方法2"); methodCommon(); } private void methodCommon(){ System.out.println("AAA"); System.out.println("BBB"); System.out.println("CCC"); } } // 接口类中的私有静态方法 package com.dcits.day09.demo01; public interface MyInterfacePrivateB { public static void methodStatic1() { System.out.println("默认方法1"); methodStaticCommon() } public static void methodStatic2() { System.out.println("默认方法2"); methodStaticCommon() } private static void methodStaticCommon(){ System.out.println("AAA"); System.out.println("BBB"); System.out.println("CCC"); } }
接口的常量定义和使用
接口当中也可以定义“成员变量”,但是必须使用public static final 三个关键字进行定义,从效果来看,这就是接口的常量,一旦使用final关键字进行修饰,说明不可改变
注意:
-
接口当中的常量,可以省略public static final,注意:不写也照样是这样
-
接口当中的常量,必须进行赋值,不能不赋值
-
接口中常量的名称,使用完全的大写字母,用下划线分割
// 接口定义常量 package com.dcits.day09.demo01; public interface MyInterfaceConst { // 这既是一个常量,一旦赋值,不可修改 public static final int NUM_OF_MY_CLASS = 10; } // 调用接口的常量 package com.dcits.day09.demo01; public class Demo05Interface { public static void main(String[] args) { // 访问接口中的常量 System.out.println(MyInterfaceConst.NUM_OF_MY_CLASS); } }
接口内容小节
-
成员变量其实是常量。格式: public static final 数据类型 常量名称 = 数据值
-
注意:
-
常量必须进行赋值,而且一旦赋值不能改变
-
常量名称完全大写,用下划线进行分割
-
-
-
接口中最重要的就是抽象方法。格式:public abstract 返回值类型 方法名称(参数列表)
-
注意:
-
实现类必须覆盖重写接口所有的抽象方法,除非实现类是抽象类
-
-
-
从Java8开始,接口里允许定义默认方法。格式:public default 返回值类型 方法名称(参数列表) {方法体}
-
注意:
-
默认方法也可以覆盖重写
-
-
-
从Java8开始,接口里允许定义静态方法。格式:public static 返回值类型 方法名称(参数列表) {方法体}
-
注意:
-
应该通过接口名称进行调用,不能通过实现类对象进行调用接口静态方法
-
-
-
从Java9开始,接口里允许定义私有方法。格式有两种
-
普通私有方法:private 返回值类型 方法名称(参数列表) {方法体}
-
静态私有方法:private static 返回值类型 方法名称(参数列表) {方法体}
-
注意:
-
private的方法只有接口自己才能调用,不能被实现类或别人调用
-
-
继承父类并实现多个接口
使用接口的时候,需要注意:
-
接口是没有静态代码块或者构造方法的
-
一个类的直接父类是唯一的,但是一个类可以同时实现多个接口
-
如果实现类所实现的多个接口中,存在重复的抽象方法,那么只需要覆盖重写一次即可
-
如果实现类没有覆盖重写所有接口类中的所有抽象方法,那么实现类就必须是一个抽象类
-
如果实现类所实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写
-
一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先使用父类中的方法
// 接口A package com.dcits.day09.demo02; public interface MyinterfaceA { public abstract void methodB(); public abstract void methodAbs(); public default void methodDefault(){ System.out.println("默认方法AAA"); } } // 接口B package com.dcits.day09.demo02; public interface MyinterfaceB { public abstract void methodA(); public abstract void methodAbs(); public default void methodDefault(){ System.out.println("默认方法BBB"); } } // 接口的实现类 package com.dcits.day09.demo02; public class MyInterfaceImpl implements MyinterfaceA,MyinterfaceB { @Override public void methodB() { System.out.println("覆盖重写了A方法"); } @Override public void methodAbs() { System.out.println("覆盖重写了AB接口都有的抽象方法"); } @Override public void methodA() { System.out.println("覆盖重写了B方法"); } @Override public void methodDefault() { System.out.println("对多个接口当中冲突的默认方法进行覆盖重写"); } } // 父类 package com.dcits.day09.demo02; public class Fu { public void method(){ System.out.println("父类方法"); } } // 子类 package com.dcits.day09.demo02; public class Zi extends Fu implements Myinterface{ } // 调用 package com.dcits.day09.demo02; public class Demo01Interface { public static void main(String[] args) { Zi zi = new Zi(); zi.method(); // 父类方法 } }
接口之间的多继承
1.类与类之间是单继承的,直接父类只能有一个
2.类与接口之间是多实现的,一个类可以实现多个接口
3.接口与接口之间是多继承的
注意:
-
多个父接口当中的抽象方法如果重复,没关系
-
多个父接口当中的默认方法重复,那么子接口必须进行默认方法的覆盖重写,而且必须带着default关键字