Day10 详解JAVA中'接口'的意义概念与应用

InterFace — 接口(Inter废四) Implements — 接口工具(imple 因普李 ments 们斯)
Const — 常量 Final — 不可变
一/接口的概略
接口是多个类情况下的公共规范和标准,
接口是引用类型. 其中最重要的就是[抽象方法]
接口定义格式:

public interface 接口名称{
      //接口体:即接口内容
    }

其中的接口名称为为大驼峰.
列如:pabulic interface InterfaceName{
//接口内容
}

二/接口内部的功能使用说明
接口内可以包含的内容,依照JDK版本而定,越靠后的版本所新增的内容就越多.
如果是JAVA 7,接口可以包含的内容有:
1\常量(不可改变的’变量’) — 定义格式:public static final 数据类型 常量(变量)名称 = 数据元素;
如:public static fianl int num = 1009;
省略格式:数据类型 常量(变量)名称 = 数据元素;
如:int num = 1009;
意义与作用: 1/接口中的常量较为特殊,一方面是因为像是从变量转变过来的,一方面又因为接口中的这个’变量’不能够被改变,所以称为常量.
接口中,这样的常量(或者叫变量)有3个修饰符起到了,分别为’public’ ‘static’ ‘final’ ,其中’final’起到了让这个原本的’变量’不能被更改的作用.
虽然你可以省略这三个修饰符,但性质仍然没变,在接口中仍然属于’不可改变的变量’,是为常量.
2/定义时,必须赋值.
4/对于接口常量的命名,有个行业内的默契规定,那就是以完全大写命名,用下划线’_"来分割单词. 如 CONST_ONE

2\抽象方法 — 不需要在接口头部声明,直接创建抽象方法即可
,如:

public interface MyInterface {
                                                     public abstract void AbstractMethod();
                                                               }

接口当中的抽象方法必须是两个固定的关键字,‘public’和’abstract’.
同时,这两个关键字修饰符都可以省略(也就是说不支持普通的成员方法,它会在接口中会被识别为抽象方法),但是不推荐.
列如:public abstract void AbstractMethod(); √ 都不省略,推荐!
void AbstractMethodTwo(); √ 都省略,不推荐
public void AbstractMethodThree(); √ 省略abstract,不推荐
abstract void AbstractMethodFour(); √ 省略public,不推荐
private abstract void AbstractMethod(); × 定义出错!仅支持public的属性.

如果是JAVA 8,接口还可以包含的更多内容有:
3\静态方法 — 定义格式:

public static 返回值类型 方法名(){
                                      //方法体;
                                              }

可省略的定义格式:

static 返回值类名 方法名(){
                                      //方法体;
                                             }

意义与作用:静态方法在调用时不可以通过实现类,也就是说要直接调用,调用格式:接口名.静态方法名();

4\默认方法 — 定义格式:

public default 返回值类型 方法名(参数列表-可选){
                                                           //方法体;
                                                  }

可省略的定义格式:

default 返回值类型 方法名(参数列表-可选){
                                                    //方法体;
                                           }

注意:接口的默认方法多用于解决升级问题.实现类既可以重写默认方法,也可不重写.即使不重写,也能通过实现类对象调用到默认方法
Day10 详解JAVA中'接口'的意义概念与应用_第1张图片
5\私有化方法:
意义与作用:1/仅让接口内的其它方法可以访问这个私有方法,从而限制实现类直接访问这个私有方法.
私有方法的主要用途是解决接口内多个方法之间重复代码的问题.以下,以3个方法做例子.
意义与作用:我们知道,在实现类调用接口时,如果接口中有抽象方法(抽象方法在接口中的定义格式有多种),那么就需要重写全部的接口方法才可以;
那么在实现类并非为抽象属性时,如果接口升级的话,比如接口添加了新的方法,那么实现类就必须添加重写这个新添加的方法才可以.
可是,如果在一些大又复杂的项目中,实现类添加新的方法往往会造成bug,这个时候问题就来了.----
---- 在接口升级后,实现类本身又不是抽象属性的情况下,如何能够不让实现类去重写新的接口方法就能够被使用呢?
方法1:

public default void defaultMethod(){
                           System.out.println("我的CPU是I7");
                                    defaultMethodThree();
                              }

方法2:

public default void defaultMethodTwo(){
                           System.out.println("我的CPU是I9");
                                     defaultMethodThree();
                              }

方法3:

 public default void defaultMethodThree(){
                           System.out.println("我的品牌是神州");
                           System.out.println("我的内存是8G");
                           System.out.println("我的显卡是RTX580");
                           System.out.println("我的固态是三星512G");
                              }

这个例子中,方法1和方法2除了CPU不同,其它配置都一样,因此都在说明自己的CPU型号后调用了方法3.
其中的方法3并非私有化方法,那么实现类中就能够访问到它.而我们想要的却是:实现类只能访问前两者,
让前两者自己说出CPU型号后再去让它自己调用方法3.这个时候就需要私有化了.
2/私有方法分为[静态私有化]和[普通私有化],两者的区别如下
静态私有化:解决多个静态方法之间的代码重复问题
普通私有化:解决多个默认方法之间的重复代码问题
Day10 详解JAVA中'接口'的意义概念与应用_第2张图片

三/接口的使用条件:
1\接口通常不直接使用,而是需要定义一个"实现类"来实现接口.
实现类的定义格式:

public class 实现类名称 implements 接口名称{
//接口内容
}

2\实现类必须覆盖重写(实现)接口内所有的抽象方法.
在实现类中,覆盖重写接口抽象方法的格式如下(和之前的重写没区别):

  public 返回值类型(包括void) 方法名称(参数列表-可选){方法体}

如:
public void implementsOverRide(){
//方法体
}
3\在主方法中创建实现类的对象,进行使用.

四/实现类继承多个接口:
1/实现类可以继承多个接口,格式为:public class 实现类名 implements 接口名A,接口名B{}
2/实现类不仅可以在继承多个接口的同时,也能继承类. 格式为: public class 实现类名 extends 父类名 implements 接口名A,接口名B{}
要注意不能搞混继承接口和继承类的顺序,继承类要写在继承接口的前面,而不能反过来,比如这个反过来的就是错误的:public class animal implements dog extends frog ×
2/假如多个接口中的[抽象方法]出现重名现象,那么必须直接在实现类中重写.
3/如果名字冲突的接口方法为[默认方法],同样只能在实现类中定义一个重写覆盖,而不能是两个.这样一来,原先重名的默认方法的方法体会被覆盖.
4/当父类的方法和接口的方法重名时,会优先运行父类的方法.

五/接口的多继承:
1/类虽然可以继承,但一个类只能继承一个直接父类,它跟接口的’继承’不同.
2/一个子接口可以继承多个直接接口 格式:public interface 当前接口名称 extends 直接父接口A,直接父接口B{}
3/假如继承的父接口之间有重名的[抽象方法].则子接口[不需要重写],因为这属于抽象方法,所以不冲突.
4/假如继承的父接口间有重名的[默认方法],则子接口需要全部覆盖重写,不然将会报错.

六/[类]继承接口 与 [接口]继承接口的格式概略:
1\实现类继承多个接口的示例:
实现类可以继承多个接口,格式为:public class 实现类名 implements 接口名A,接口名B{}
2\实现类即继承父类又继承接口的示例:
实现类不仅可以在继承多个接口的同时,也能继承类. 格式为: public class 实现类名 extends 父类名 implements 接口名A,接口名B{}
3\接口继承多个父接口的示例:
一个子接口可以继承多个直接接口 格式:public interface 当前接口名称 extends 直接父接口A,直接父接口B{}
继承的总结:当类继承类,或接口继承接口时,用’extends’.当类继承接口,用’Implements’
七/注意:
1/和普通类继承抽象类的规则一样,如果实现类并没有重写接口的全部抽象方法,那么实现类自己就必须是抽象类.
2/因为接口还没有支持所谓的’普通成员方法’,且’抽象方法’的多种定义格式在接口中同普通成员方法的定义格式相似,因此如果你用定义普通成员方法的格式去定义方法,那么就会被识别为抽象方法.
这样的话,你在实现类中就不得不重写它,此时你就可以用’默认方法’来避免这种情况,从而实现与’普通成员方法’相似的作用.
3/实现类将自动继承接口中的默认方法,所以不需要特意在实现类中定义或声明它,直接在main主方法中以对象类的形式调用它即可,格式:对象名.默认方法名()
当然,假如你需要覆盖重写接口的默认方法的话,那么此时才需要在实现类中定义声明它并去重写.
4/接口没有’构造方法’和’静态代码块’ 这个时候在接口中,就需要用到[默认方法]了.
八/关于实现类的一个小技巧
辅助: 当你想要重写接口所有的方法,却不想一个个去接口找再一个个去定义方法的时候,
那么对准实现类的文件头,按Alt+Enter → 选择 Implement methods → 回车.

分为3个接口3个类
Main主方法的:Demo01MyInterfaceMain.java(普通类)
接口:MyInterface.java(主要接口)
接口:MyInterfaceB.java(用于演示同父类/同其它接口的方法重名)
接口:MyInterfaceC.java(用于演示同其它接口的方法重名)
父类:Fu.java(用于演示和接口的方法重名)
实现类的:MyInterfacelmp.java(继承类’Fu’,和继承MyInterface,MyInterfaceB,MyInterfaceC这三个接口/用于演示重名方法的重写)

Main主方法的:Demo01MyInterfaceMain.java(普通类)

package code.study.day10.Demo01;
public class Demo01InterFaceMain {
    public static void main(String[] args){
        //创建实现类
        MyInterFaceImp Interface = new MyInterFaceImp();
        //通过实现类,调用接口的抽象方法
        Interface.AbstractMethod();
        Interface.AbstractMethodTwo();
        Interface.AbstractMethodThree();
        Interface.AbstractMethodFour();

        //通过实现类,调用接口的默认方法
        Interface.DefaultMethod();

        //不通过实现类,直接调用接口的静态方法
        MyInterface.StaticMethod();

        //通过实现类,调用接口的默认方法,再通过默认方法来调用接口的私有化方法.{电脑配置案例}
        Interface.ComputerCt5na();
        Interface.ComputerCt7na();

        //通过实现类,调用接口的成员常量(不能单独调用)
        System.out.println("接口的成员常量值为:"+Interface.CONST_ONE);

        //通过实现类,调用在实现类继承了多个接口情况下发生重名的[抽象方法].
        Interface.SameMethodName();

        //通过实现类,调用在实现类继承了多个接口情况下发生重名的[默认方法].
        Interface.SameDefaultName();

        //通过实现类,调用父类同接口存在重名的方法,此时编译器会优先调用父类中的方法.
        Interface.SameFuName();

    }
}

接口:MyInterface.java(主要接口)

package code.study.day10.Demo01;
public interface MyInterface {
    //标准的抽象方法定义格式
     public abstract void AbstractMethod(); //同MyInterfaceB名字相同
    //省略式抽象方法定义格式 --- 在接口中是抽象方法,在普通类中什么也不是
    void AbstractMethodTwo();                 //同MyInterfaceB名字相同
    //省略式抽象方法定义格式 --- 在接口中是抽象方法,在普通类中什么也不是
     abstract void AbstractMethodFour();    //同MyInterfaceB名字相同
    //省略式抽象方法定义格式 --- 在接口中是抽象方法,在普通类中是[普通成员方法]
    public void AbstractMethodThree();      //同MyInterfaceB名字相同

    //默认方法的定义   --- 默认方法可以解决接口升级问题,可以用来替代普通成员方法的功能,以此解决抽象方法的定义格式同普通成员方法的冲突问题.
    public default void DefaultMethod(){
        System.out.println("默认方法!");
    }

    //静态方法的定义
    public static void StaticMethod(){
        System.out.println("これが静的な方法です!");
    }

    //私有化方法示例(默认方法形式) --- 电脑型号神州 Z7CT7NA 和 Z7CT5NA
      //神州Z7 CT7NA
    public default void ComputerCt7na(){
        System.out.println("型号:Z7 CT7NA");
        System.out.println("CPU型号:I7 9750H");
        ComputerInfo();
    }
      //神州Z7 CT5NA
    public default void ComputerCt5na(){
        System.out.println("型号:Z7 CT5NA");
        System.out.println("CPU型号:I5 9300H");
        ComputerInfo();
    }
      //配置[私有化]
    private void ComputerInfo(){
        System.out.println("显卡型号:GTX1660TI");
        System.out.println("硬盘:三星固态512GB");
        System.out.println("内存:DDR4 2667 8G");
        System.out.println("主板:HM370");
        System.out.println("显示器:15.6寸");
    }

    //定义常量
    public static final int CONST_ONE = 12;
      //省略格式
    int CONST_TWO = 12;

    //与实现类其它接口的抽象方法重名
    public abstract void SameMethodName();      //同MyInterfaceB名字相同

    //与实现类其它接口的默认方法重名             是默认方法,因此子接口继承我时需要覆盖重写
    public default void SameDefaultName(){
        System.out.println("我是接口'MyInterface'中重名了的默认方法,名叫'SaeDefaultName'");
    }

    //与实现类父类的方法名重名
    public default void SameFuName(){
        System.out.println("这是一个与父类方法名重名了的默认方法");
    }

接口:MyInterfaceB.java(用于演示同父类/同其它接口的方法重名)

package code.study.day10.Demo01;

public interface MyInterfaceB {

    //与其它接口的抽象方法重名(两个接口都被同一个实现类继承)  --- 用来演示用实现类继承下的重名
    public abstract void SameMethodName();//同MyInterface名字相同

    //与其它接口的抽象方法相同(两个接口都被同一个子接口继承)  --- 用来演示用子接口继承下的重名
    public abstract void AbstractMethod();//同MyInterface名字相同
    public abstract void AbstractMethodTwo();//同MyInterface名字相同
    public abstract void AbstractMethodThree();//同MyInterface名字相同
    public abstract void AbstractMethodFour();//同MyInterface名字相同

    //与其它接口的默认方法重名
    public default void SameDefaultName(){  //同MyInterface名字相同又是默认方法,因此子接口继承我时需要覆盖重写
        System.out.println("我是接口'MyInterfaceB'中重名了的默认方法,名叫'SameDefaultName");

    }

    public default void SameDefaultC(){}



}

接口:MyInterfaceC.java(用于演示同其它接口的方法重名)

package code.study.day10.Demo01;
/*
接口的多继承:
1/类虽然可以继承,但一个类只能继承一个直接父类,它跟接口的'继承'不同.
2/一个子接口可以继承多个直接接口 格式:public interface 当前接口名称 extends 直接父接口A,直接父接口B{}
3/假如继承的父接口之间有重名的[抽象方法].则子接口[不需要重写],因为这属于抽象方法,所以不冲突.
4/假如继承的父接口间有重名的[默认方法],则子接口需要全部覆盖重写,不然将会报错.

 */
public interface MyInterfaceC extends MyInterface,MyInterfaceB{

    //接下来为自己的方法
    public default void MyInterfaceCmethod(){
        System.out.println("我是MyInterface自己的方法");
    }

   //此为父接口之间重名的[默认方法],因此需要重写
    @Override
    default void SameDefaultName() {
        System.out.println("不好意思...虽然你通过实现类调用到了我这个MyInterfaceC,这个方法名'SameDefaultName'在两个父接口之间是重名的,因此我不得不重写!");
    }
}

父类:Fu.java(用于演示和接口的方法重名)

package code.study.day10.Demo01;

public class Fu {

    public void SameFuName(){
        System.out.println("这是一个和接口默认方法重名了的父类普通方法");
    }
}

实现类的:MyInterfacelmp.java(继承类’Fu’,和继承MyInterface,MyInterfaceB,MyInterfaceC这三个接口/用于演示重名方法的重写)

package code.study.day10.Demo01;
public class MyInterFaceImp extends Fu implements MyInterface,MyInterfaceB,MyInterfaceC {

    //引用接口的抽象方法
    @Override
    public void AbstractMethod() {
        System.out.println("第一方法");
    }

    @Override
    public void AbstractMethodTwo() {
        System.out.println("第二方法");
    }

    @Override
    public void AbstractMethodThree() {
        System.out.println("第三方法");
    }

    @Override
    public void AbstractMethodFour() {
        System.out.println("第四方法");
    }

    //引用接口的默认方法  無
    //  [ 实现类自动继承接口的默认方法 无需特意引用;在main主方法中直接调用即可]
    //  [当然,假如你需要覆盖重写接口的默认方法的话,那么此时才需要在实现类中定义声明它并去重写.]
    @Override
    public void DefaultMethod() {
        System.out.println("覆盖重写了接口的默认方法!");
    }

    //重写在多个接口中重名的[抽象方法]   只能定义一个重写方法.
    @Override
    public void SameMethodName() {
        System.out.println("接口'MyInterface'和接口'MyInterfaceB'两者之间有重复的抽象方法名");
        System.out.println("因此,在这个实现类中只需要重写一个即可.");
    }

    //重写在多个接口中重名的[默认方法]  同样只能定义一个,并将会覆盖原先默认方法的方法体.
    @Override
    public void SameDefaultName(){
        System.out.println("重写了接口MyInterface和接口MyInterfaceB中重复的默认方法,叫做'SameDefaultName'");
    }

}

你可能感兴趣的:(JAVA)