一、接口

  •   接口:是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。
  •   接口的定义:它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。   
  •   接口的使用:它不能创建对象,但是可以被实现( implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。

 Tips:引用数据类型:数组,类,接口等。

二、定义格式

  语法格式:

【权限修饰符】 interface 接口名称 {
   接口的成员列表如下:
// 抽象方法
// 默认方法
// 静态方法
// 私有方法
}

  1、JDK1.7及以前接口成员有两种:静态常量和抽象方法(JDK7+)

    全局的静态的常量:接口当中也可以定义“成员变量”,但是必须使用public static final三个关键字进行修饰(可省略),其实就是接口中的【常量】。

    公共的抽象方法:使用publc abstract 关键字修饰,(可以省略)没有方法体。该方法供子类实现使用。

   语法格式

public static final 数据类型 变量名 = 值;
public abstract 返回值类型 方法名称(参数列表);

   Demo:

 public interface InterFaceName {
public static final long MAX_SPEED = 7900000; //常量
  public abstract void method(); //抽象方法
}

    Tips:一旦使用final关键字进行修饰,说明不可改变。

    注意事项

    a、接口当中的常量,可以省略 public static final注意:不写也照样是这样。

    b、接口当中的常量,必须进行赋值;不能不赋值

    c、接口中常量的名称,使用完全大写的字母,用下划线进行分隔。(推荐命名规则)

  2、JDK1.8以后接口有增强两个成员:默认方法和静态方法(JDK8+)

    默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。

   语法格式:

public default 返回值类型 方法名称(参数列表) {
方法体
}

   静态方法:使用public static 修饰,不可省略,供接口直接调用。

   Demo:

 public interface InterFaceName {
public default void method() {
// 执行语句
}
public static void method2() {
// 执行语句
}
}

     扩展:

   (1)为什么 Java8 要允许接口中定义静态方法?

        因为JDK发展了一段时间后,发现类库中,多了很多的成组的API,如Array和Arrays类,Collection接口和Collections工具类。

     一般工具类都是静态方法,这些静态方法,基本上都是为前面这个对应接口服务的。当把这样的静态方法直接挪到接口中定义就好了,减少了这样的工具类的出现。

   (2)为什么 Java8 要允许接口中定义默认方法?

      因为有的时候,一个接口它的大多数实现类对接口的抽象方法的实现代码是一样的,那样写好几次就非常麻烦。即相当于,默认方法是原来的抽象方法有了一个默认实现。

      如果实现类的实现和接口一样,就不需要重写,如果不一样就重写即可。

  3、JDK1.9以后增加两个接口成员:私有方法和私有静态方法(JDK9+)

    私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。

    Demo:

 public interface InterFaceName {
private void method() {
// 执行语句
}
}

三、基本的实现

  1、实现的概述

    类与接口的关系为实现关系,即类实现接口,该类也可以称为接口的实现类,也可以称为接口的子类。

   实现的动作似继承,格式相仿,只是关键字不同,实现使用 implements 关键字。

   非抽象子类实现接口

    •  必须重写接口中所有的抽象方法。
    • 继承了接口的默认方法,即可以直接调用,也可以重写。

   实现格式

class 类名 implements 接口名 {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【可选】
}

  2、抽象方法的使用

      接口中的抽象方法必须全部实现。

      Demo:

 // 定义接口:
public interface LiveAble {
// 定义抽象方法
public abstract void eat();
public abstract void sleep();
} // 定义实现类
public class Animal implements LiveAble {
@Override
public void eat() {
System.out.println("吃东西");
}
@Override
public void sleep() {
System.out.println("晚上睡");
}
}

  3、默认方法的使用

      可以继承,可以重写,二选一,但是只能通过实现类的对象来调用。

       (1)继承默认方法

      Demo:

 // 定义接口
public interface LiveAble {
public default void fly(){
System.out.println("天上飞");
}
} // 定义实现类
public class Animal implements LiveAble {
// 继承,什么都不用写,直接调用
} // 测试类
public class InterfaceDemo {
public static void main(String[] args) {
// 创建子类对象
Animal a = new Animal();
// 调用默认方法
a.fly();
}
}
输出结果:
天上飞

    (2)重写默认方法

 // 定义接口
public interface LiveAble {
public default void fly(){
System.out.println("天上飞");
}
} // 定义实现类
public class Animal implements LiveAble {
@Override
public void fly() {
System.out.println("自由自在的飞");
}
} // 定义测试类
public class InterfaceDemo {
public static void main(String[] args) {
// 创建子类对象
Animal a = new Animal();
// 调用重写方法
a.fly();
}
}
输出结果:
自由自在的飞

  4、静态方法的使用

      静态与 .class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用。

     语法格式

public static 返回值类型 方法名称(参数列表) {
方法体
}

      Demo:

 // 定义接口
public interface LiveAble {
public static void run(){
System.out.println("跑起来~~~");
}
} // 定义实现类
public class Animal implements LiveAble {
// 无法重写静态方法
} // 定义测试类
public class InterfaceDemo {
public static void main(String[] args) {
// Animal.run(); // 【错误】无法继承方法,也无法调用
LiveAble.run(); //
}
}
输出结果:
跑起来~~~

  5、私有方法的使用

      • 私有方法:只有默认方法可以调用;
      • 私有静态方法:默认方法和静态方法可以调用;

     语法格式:

private 返回值类型 方法名称(参数列表){ 方法体}            普通私有方法
private static 返回值类型 方法名称(参数列表) { 方法体} 静态私有方法

     如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法去调用。

     Demo:

 public interface LiveAble {
default void func(){
func1();
func2();
}
private void func1(){
System.out.println("跑起来~~~");
}
private void func2(){
System.out.println("跑起来~~~");
}
}

四、接口的多实现(冲突问题)

   在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。
   实现格式

class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【不重名时可选】
}

  1、抽象方法

    接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次

    Demo:

 // 定义接口
interface A {
public abstract void showA();
public abstract void show();
}
interface B {
public abstract void showB();
public abstract void show();
} //定义实现类
public class C implements A,B{
@Override
public void showA() {
System.out.println("showA");
}
@Override
public void showB() {
System.out.println("showB");
}
@Override
public void show() {
System.out.println("show");
}
}

  2、默认方法

    当一个类同时实现了两个甚至更多个接口时,这些个接口中出现了方法签名相同的默认方法时,

    必须在这个类中,做出选择:

      (1)保留其中一个,放弃另一个;

      (2)两者都不用,完全重写一个;

    Demo:

 interface A{
public default void test(){
System.out.println("aaa");
}
}
interface B{
public default void test(){
System.out.println("bbb");
}
}
class C implements A,B{
//选择一:保留其中一个,放弃另一个
A.super.test(); //保留A接口的实现
B.super.test(); //保留B接口的实现
} class C1 implements A,B{
//选择二:两者都不用,完全重写一个
public void test(){
System.out.println("ccc");
}
}

  3、静态方法

    接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法。

  4、优先级的问题

    当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的方法签名一样的方法,怎么办?

    如何选择?

      (1)默认选择:编译器默认选择父类中的方法

      (2)改选保留接口的

      (3)完全自己重写

    Demo:

 class Father{
public void test(){
System.out.println("ffff");
}
}
interface D{
public default void test(){
System.out.println("dddd");
}
}
class Son1 extends Father implements D{
//选择一:默认选择, 保留父类的
} class Son2 extends Father implements D{
//选择二:改选接口的
public void test() {
D.super.test();
}
} class Son3 extends Father implements D{
// 完全自己重写
public void test() {
System.out.println("ssss");
}
}

五、接口的多继承

    一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。

   如果父接口中的默认方法有重名的,那么子接口需要重写一次。

   Demo:

 //定义父接口
interface A {
public default void method(){
System.out.println("AAAAA");
}
}
interface B {
public default void method(){
System.out.println("BBBBB");
}
} // 定义子接口
interface D extends A,B{
@Override
public default void method() {
System.out.println("DDDDD");
}
}

  Tips:子接口重写默认方法时,default 关键字可以保留;子类重写默认方法时,default 关键字不可以保留。

六、成员特点

  •   接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用 public static final 修饰。
  • 接口中,没有构造方法,不能创建对象。
  • 接口中,没有静态代码块。
  • 一个类如果直接继承父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。

七、接口的特点

  1、接口是标准,就是用来被遵守的,即就是用来被实现的,那么要求实现类在实现接口时,必须实现/重写所有的抽象方法,否则这个实现类就得是一个抽象类;

  2、接口也是不能直接创建对象的;

  3、接口类型的变量与实现类的对象构成多态引用;

  4、一个类继承父类时,Java只支持单继承,但是一个类在实现接口时,可以同时实现多个接口;

  5、一个类如果同时继承父类,又实现接口时,要求继承在前,实现在后;

【修饰符】 class 实现类  extends 父类  implements 父接口们{}

  6、在Java中,接口还可以继承接口;

【权限修饰符】 interface 子接口  extends 父接口们{ }

  

Java 面向对象(六)接口的更多相关文章

  1. Java面向对象:接口

    Java面向对象之接口 什么是接口:接口是一种规范和标准,他们可以约束类的行为,是一些方法特征的集合 语法: [修饰符] interface 接口名 extends 父接口1,夫接口2....... ...

  2. JavaSE入门学习21:Java面向对象之接口(interface)(二)

    一接口实现的多态 在上一篇博文:JavaSE入门学习20:Java面向对象之接口(interface)(一)中提到了接口的实现存在多态性,那么 这一篇主要就要分析接口实现的多态. 实例一 Test.j ...

  3. JavaSE入门学习20:Java面向对象之接口(interface)(一)

    一Java接口 接口(英文:interface)是抽象方法和常量值的集合,在Java编程语言中是一个抽象类型,接口通常以interface来声 明.类是一种详细实现体.而接口定义了某一批类所须要遵守的 ...

  4. Java 面向对象之接口、多态

    01接口的概念 A:接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成 ...

  5. Java面向对象(接口、多态)

    面向对象 今日内容介绍 u 接口 u 多态 第1章 接口 1.1 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的 ...

  6. Java面向对象程序设计--接口和内部类

    1.接口的定义: In the Java programming language, an interface is not a class but          staff[0] =       ...

  7. java面向对象_接口

    java接口 interface,是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承接口的抽象方法. 接口并不是类,编写接口的方式和类很相似,但 ...

  8. Java面向对象之接口interface 入门实例

    一.基础概念 (一)接口可以简单的理解为,是一个特殊的抽象类,该抽象类中的方法都是抽象的. 接口中的成员有两种:1.全局常量 2.抽象方法 定义接口用关键字interface,接口中的成员都用固定的修 ...

  9. Java 面向对象_接口

    接口定义 接口就是多个类的公共规范 接口是一种引用数据类型, 最重要的内容是其中的抽象方法 定义格式: public interface MyInterfaceAbstract { // 这是一个抽象 ...

  10. Java面向对象(二) 接口、多态和泛型

    一.接口 二.多态 多态是同一个行为具有多个不同表现形式或形态的能力. 2.1 类型转换 转换方式 隐式 向上转型 对于基本数据类型,存储容量低的可自动向存储容量高的类型转换 对于引用变量,子类可被转 ...

随机推荐

  1. It’s worth noting值得注意的是

    It’s worth noting that in JavaScript applications the Model is often connected via Ajax to a back-en ...

  2. osg fbx遍历模型节点名称

    ; k<sg->getNumChildren(); k++) { //转换编 std::string name = vcfbx1.w2m1(vcfbx1.m2w1(sg->getCh ...

  3. spring boot配置文件、日志配置和代码的多环境配置

    一般项目都逃不掉开发.测试和生产这三套环境,如果每次给这三套环境打包都去改配置,累死不说,还一不留心就出差错.倒不如每套环境各给一套配置来的轻松.上代码: 1.通用配置放在application.pr ...

  4. 不同操作系统上DNS客户端操作区别汇总

    结论:windows有DNS缓存,Linux默认无DNS缓存,只能依赖于安装其他软件. 一.不同操作系统的客户端的DNS缓存差别 1.windows 系统中dns 解析器会使用系统的dns缓存来提高d ...

  5. [AI] 深度数学 - Bayes

    数学似宇宙,韭菜只关心其中实用的部分. scikit-learn (sklearn) 官方文档中文版 scikit-learn Machine Learning in Python 一个新颖的onli ...

  6. 数据结构与算法 Javascript描述

    数据结构与算法系列主要记录<数据结构与算法 Javascript描述>学习心得

  7. iOS-AVPlayer使用

    1引入AVFoundation.framework框架 2引入头文件<AVFoundation/AVFoundation.h>,并拖入需要播放的视频文件 代码如下: 自定义播放的View, ...

  8. 《CNCF × Alibaba云原生技术公开课》知识点自测(三):Kubernetes核心概念

    (单选)1.Kubernetes的中文含义是___. A. 船   B.舵手  C.容器平台  D.起重机 (单选) 2.Kubectl是_____. A. 一个与Kubernetes集群进行交互.管 ...

  9. 使用GDAL进行波段分离

    波段分离一般最常用的还是OpenCV,使用OpenCV的split方法可以直接对波段分离,并且效果不错,但是有一个问题是只能处理有限波段的数据,比如波段超过一定的数目就无法完成波段分离工作,或者数据有 ...

  10. leetcode1130 Minimum Cost Tree From Leaf Values

    思路: 区间dp. 实现: class Solution { public: int mctFromLeafValues(vector<int>& arr) { int n = a ...