3.接口

目录

3.接口

3.1.接口概述与生活举例

3.2.接口的定义和使用

3.3.接口中可以定义的方法

3.4.接口中抽象方法定义和使用

3.5.接口中默认方法的使用和解决的问题

3.6.接口中静态方法使用

3.7.接口中私有方法使用及解决的问题

3.8.接口中常量定义和注意事项

3.9.Java9+版本中接口内容

3.10.继承父类并实现多个接口时产生的方法冲突

3.12.接口之间多继承产生的方法冲突


3.接口

3.1.接口概述与生活举例

  • 计算机中,接口是多个类的公共规范,接口是引用数据类型

3.2.接口的定义和使用

  • 接口的定义:接口就是多个类的公共规范。接口是一种引用数据类型,最重要的内容就是其中的抽象方法
  • public interface 接口名称{   //接口内容 }
  • 备注:换成关键字interface后,编译生成的字节码文件仍然是java-->.class
  • 接口使用步骤:
    • 1.接口不能直接使用,必须有一个实现类实现接口.public class 实现类名称 implements 接口名称{  }
    • 2.接口实现类必须重写接口中所有抽象方法。重写:去掉abstract关键字,加上方法体大括号。如果实现类并没有重写接口中所有抽象方法,则实现类必须是抽象类
    • 3.主类中创建接口实现类对象并使用

3.3.接口中可以定义的方法

  • 若是java7 那么接口中可以包含的内容有:
    • 1.常量
    • 2.抽象方法
  • 若是java8 还可以额外包含:
    • 3.默认方法
    • 4.静态方法
  • 若是java9 还可以包含
    • 5.私有方法

3.4.接口中抽象方法定义和使用

  • 在任何版本的Java中,接口都能定义抽象方法。
  • 格式: public abstract 返回类型 方法名称(参数列表);
  • 注意事项:
    • 1.接口中的抽象方法,修饰符必须是两个固定关键字:public abstract
    •  2.这两个关键字修饰符,可以选择性省略(刚学建议写上)
    • 3.方法的三要素(返回类型、方法名、参数类型)可以随意定义
package demo15_interface;
public interface MyInterfaceAbstract {
    //这是一个抽象方法
    public abstract void methodAbs1(int a);
    //这也是一个抽象方法
    public void methodAbs2();
    //这也是一个抽象方法
    abstract void methodAbs3();
}


package demo15_interface;
//接口实现类,alt+enter快捷键重写接口中所有抽象方法
public class MyInterfaceAbstractImpl implements MyInterfaceAbstract {
    @Override
    public void methodAbs1(int a) {
        System.out.println("这是第一个抽象方法的重写");
    }

    @Override
    public void methodAbs2() {
        System.out.println("这是第二个抽象方法的重写");
    }

    @Override
    public void methodAbs3() {
        System.out.println("这是第三个抽象方法的重写");
    }
}



package demo15_interface;
public class Demo01Interface {
    public static void main(String[] args) {
        //创建接口实现类对象
        MyInterfaceAbstractImpl abs = new MyInterfaceAbstractImpl();
        abs.methodAbs1(10);
        abs.methodAbs2();
    }
}

 

3.5.接口中默认方法的使用和解决的问题

  • java8开始,接口中允许定义默认方法
  • 格式: public default 返回类型 方法名称(参数列表){方法体}
  • 作用:接口当中的默认方法,可以解决接口升级问题
    • 比如接口A的实现类有B、C,当接口A需要加入新的抽象方法时,为了避免实现类跟着变动,可在接口中设置该方法为默认方法。
    • 接口中默认方法可被子类(实现类)继承,若无需要,不需重写默认方法
  • 默认方法使用:
    • 1.接口默认方法,可以通过接口实现类对象,直接调用
    • 2.接口默认方法,可以被接口实现类进行覆盖重写
    • 3.接口中默认方法可以省略关键字public,抽象方法可以省略public abstract
package demo16_interface;
public interface MyInterfaceDefault {
    //抽象方法,public abstract是灰色表示可以省略,仍表示抽象方法
    public abstract void methodAbs();

    //现进行接口升级,新添加一个抽象方法public abstract void methodAbs();
    //为了不变动该接口已有的实现类(即在实现类中再实现该新抽象方法)。
    //需要将新添加的方法改为默认方法。
    public default void methodDefault(){ //public关键字是灰色,可以省略
        System.out.println("这是接口中新添加的默认方法");
    }
}



package demo16_interface;
//接口实现类
public class MyInterfaceDefaultA implements MyInterfaceDefault {
    @Override
    public void methodAbs() {
        System.out.println("实现了抽象方法,AAA");
    }
}



package demo16_interface;
//接口实现类
public class MyInterfaceDefaultB implements MyInterfaceDefault {
    @Override
    public void methodAbs() {
        System.out.println("实现了抽象方法,BBB");
    }

    @Override
    public void methodDefault() {
        System.out.println("实现类B重写了接口中默认方法");
    }
}



package demo16_interface;
public class Demo01 {
    public static void main(String[] args) {
        //创建接口实现类对象
        MyInterfaceDefaultA a = new MyInterfaceDefaultA();
        a.methodAbs();//调用抽象方法,实际运行的是右侧实现类MyInterfaceDefaultA
        //调用默认方法,实现类中若没有,则向上找接口
        a.methodDefault();

        MyInterfaceDefaultB b = new MyInterfaceDefaultB();
        b.methodAbs();//抽象方法
        b.methodDefault();//默认方法
    }
}

3.6.接口中静态方法使用

  • 从java8开始,接口当中允许定义静态方法。
  • 格式:public static 返回类型 方法名称(参数列表){方法体}
    • 提示:就是将abstract或default换成static即可,带上方法体。
  •  使用:
    • 1.通过接口名称直接调用其中的静态方法
    • 2.不能通过实现类对象调用接口中静态方法。
    • 3.静态方法属于类,不属于对象,
package demo17_interface;
public interface MyInterfaceStatic {
    public static void methodStatic(){
        System.out.println("这是接口中的静态方法");
    }
}


package demo17_interface;
public class MyInterfaceStaticImpl implements MyInterfaceStatic { }


package demo17_interface;
public class Demo01 {
    public static void main(String[] args) {
        //直接通过接口名称调用静态方法
        MyInterfaceStatic.methodStatic();
    }
}

3.7.接口中私有方法使用及解决的问题

  •  问题描述:
    • 接口中我们需要抽取一个共有方法,用来解决两个默认方法之间重复代码问题。
    • 但是这个共有方法不应该让实现类使用,应该是私有化的,只供本类中方法调用。
  • 解决方案
    • 从java9开始,接口当中允许定义私有方法
    • 1.普通私有方法,解决多个默认方法之间重复代码问题
      •  格式: private 返回类型 方法名称(参数列表){方法体}
    • 2.静态私有方法,解决多个静态方法之间重复代码问题
      •  格式:private static 返回类型 方法名称(参数列表){方法体}
    • 若属性和方法只供在本类/接口中使用,使用private修饰将属性和方法具体实现封装,并提供对应的方法供其他类访问。
package demo18_interface;
public interface MyInterfacePrivateA {

    public default void methodDefault(){
        System.out.println("默认方法1");
        //System.out.println("aaa");
        //System.out.println("bbb");
        methodCommon();
    }

    public default void methodDefault2(){
        System.out.println("默认方法2");
        //System.out.println("aaa");
        //System.out.println("bbb");
        methodCommon();
    }

    //抽取共有方法,解决两个默认方法之间重复代码问题
    //有问题:这样抽取的共有方法能被实现类单独使用,这是不恰当的,
    //      默认方法中抽取的共有方法应该被接口中默认方法调用,
    //      而不是被实现类对象单独调用,即方法设置成私有,
    //      只供本类中方法调用(本类被抽取的方法来调用)。
    /*
      public default void methodCommon(){
        System.out.println("aaa");
        System.out.println("bbb");
    }
    */
    private void methodCommon(){
        System.out.println("aaa");
        System.out.println("bbb");
    }
}


package demo18_interface;
public class MyInerfacePrivateAImpI implements MyInterfacePrivateA{}



package demo18_interface;
import demo16_interface.MyInterfaceDefaultA;
public class DemoA {
    public static void main(String[] args) {
        MyInerfacePrivateAImpI p = new MyInerfacePrivateAImpI();
        p.methodDefault();//调用接口中默认方法(默认方法可在实现类中重写)
        //实现类对象调用接口中抽取的共有方法是不合适的,抽取的方法
        //应该定义成私有,只供本类中方法调用(本类被抽取的方法来调用)。
        p.methodDefault2();
        //p.methodCommon();私有方法无法调用
    }
}



3.8.接口中常量定义和注意事项

  • 接口中也可以定义“成员变量”,但必须使用public static final关键字修饰,从效果上看,这其实就是接口的【常量】
  • 格式:  public static final 数据类型 常量名称=数据值
  • 备注: 一旦使用final关键字,说明变量值不可以改变
  • 注意事项:
    •  1.接口当中的常量,可以省略public static final
    •  2.接口当中的常量,必须进行赋值(否则默认值为0还是常量不能更改,这个常量也没有意义)
    •  3.接口中常量的名称,使用完全大写的字母,用下划线进行分割.
    • 4.接口中常量通过接口调用
package demo19_interface;
public interface MyInterfaceConst {
    public static final int NUM_OF_MY_CLASS=10; //接口中定义常量
}



package demo19_interface;
public class Demo01 implements MyInterfaceConst {
    public static void main(String[] args) {
        //访问接口中常量
        System.out.println("接口中访问常量:"+MyInterfaceConst.NUM_OF_MY_CLASS);
    }
}

3.9.Java9+版本中接口内容

3.10.继承父类并实现多个接口时产生的方法冲突

  • 使用接口时候需要注意:
    • 1.接口是没有静态代码块或者构造方法的。
    •  2.一个类的直接父类是唯一的(单继承),但可同时实现多个接口(多实现)
    • 3.如果实现类所实现的多个接口中,存在重复的抽象方法,只需覆盖重写一次即可。
    • 4.如果实现类没有覆盖重写所有接口当中所有抽象方法,那么实现类必须是抽象类。
    • 5.如果实现类实现的多个接口当中,存在重复的默认方法,则需要重写有冲突的默认方法
    •  6.一个类如果直接父类当中的方法和接口当中默认方法产生冲突,系统优先父类中方法(继承优先于接口实现)
package demo20_interface;
public interface MyInterfaceA {
    public abstract void methodAbs();//抽象方法
    public default void methodDef(){
        System.out.println("接口A的默认方法methodDef()");
    }
}


package demo20_interface;
public interface MyInterfaceB {
    public abstract void methodAbs();//抽象方法
    public default void methodDef(){
        System.out.println("接口B的默认方法");
    }
}




package demo20_interface;
public class Fu {
    public void methodDef(){
        System.out.println("这是父类methodDef()方法,与接口中默认方法冲突,优先使用父类的");
    }
}


package demo20_interface;
public class Zi extends Fu implements MyInterfaceA,MyInterfaceB {
    @Override
    public void methodAbs() {
        //两个接口中抽象方法冲突(重名),只需重写一次
        System.out.println("实现类重写接口的抽象方法");
    }

    @Override
    public void methodDef(){
        //两个接口中默认方法冲突,需重写默认方法
        System.out.println("实现类重写接口A,B中默认方法");
    }
}


package demo20_interface;
public class DemoMain {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.methodAbs();//调用抽象方法
        zi.methodDef();//父类与接口中方法冲突,系统优先使用父类方法
    }
}



3.12.接口之间多继承产生的方法冲突

  • 1.类与类之间是单继承,直接父类只有一个。
  • 2.类与接口之间是多实现的,一个类可以实现多个接口。
  • 3.接口与接口之间是多继承的。
  • 注意事项:
    • 1.多个父接口当中的抽象方法如果重复,子接口可以不重写该抽象方法。【接口的继承不需要重写父接口的抽象方法,实现类中才需要】
    • 2.多个父接口当中的默认方法如果重复,子接口必须进行默认方法的重写必须带着default关键字(因为是在接口中不能省略)】【因为默认方法是可以通过接口直接调用的,如果子接口实现类中直接通过子接口调用默认方法(此时子接口未重写父接口默认方法),那么该调用父接口A还是B中的同名默认方法呢?所以要重写】
package demo21_interface;
public interface MyInterfaceA {
    public abstract void methodA();//接口的抽象方法
    public abstract void methodCommon();
    public default void methodDef(){
        System.out.println("这是父接口A的默认方法");
    }
}


package demo21_interface;
public interface MyInterfaceB {
    public abstract void methodB();//接口的抽象方法
    public abstract void methodCommon();
    public default void methodDef(){
        System.out.println("这是父接口B的默认方法");
    }
}


package demo21_interface;

/**接口之间的多继承:
 * 这个子接口当中有几个方法?4个
 * methodA来源于接口A
 * methodB来源于接口B
 * methodCommon同时来源于接口A,B
 * method来源于自身
 */
public interface MyInterface extends MyInterfaceA,MyInterfaceB {
    public abstract void method();//子接口本身的抽象方法
    //1.接口的继承不需要重写父接口的抽象方法,实现类中才需要
    public abstract void methodCommon();//子接口可以不重写多个父接口中重复的抽象方法

    @Override
    default void methodDef() {
        //2.子接口需要重写多个父接口中同名的默认方法
        System.out.println("子接口重写父接口们中重名的默认方法");
    }
}


package demo21_interface;
//子接口拥有以下4个抽象方法,子接口实现类需要重写这些抽象方法
public class MyInterfaceImpI implements MyInterface {
    @Override
    public void method() { }

    @Override
    public void methodA() { }

    @Override
    public void methodB() { }

    @Override
    public void methodCommon() { }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值