接口(基本接口和函数式接口)_接口是函数吗-程序员宅基地

技术标签: lambda  接口  java    

一.接口

接口就是用来规范方法的,接口是方法的模板
接口(硬件类接口)是指同一计算机不同功能层之间的通信规则称为接口。
接口(软件类接口)是指对协定进行定义的引用类型(类,数组,接口)。其他类型实现接口,以保证它们支持某些操作。接口指定必须由类提供的成员或实现它的其他接口。与类相似,接口可以包含方法、属性、索引器和事件作为成员。
在这里插入图片描述

接口是一个特殊的Java类,接口可以做到多继承(接口的继承称为实现,接口可以多实现)

1.基本接口
(1)接口的定义,声明
Java类使用的是class关键字,接口使用interface关键字声明。
语法:public interface 接口的名字{ }
类中有属性;方法:有参构造和普通;代码块:静态代码块和普通代码块;普通方法:静态和非静态,有参无参,有返回值和无返回值
a.属性

在反编译工具中,我们可以看到接口中的属性默认是使用public static final修饰的
接口是一个特殊的类,接口不能自己实例化自己
使用final修饰的属性称为常量,要手动赋予初始值,声明的时候赋值(全局变量)
在这里插入图片描述
usb是一个接口,不能直接实例化
在这里插入图片描述
b.方法
没有代码块、没有静态代码块、没有构造方法、普通方法 、最终方法
可以有静态方法,抽象方法(默认抽象方法是使用public abstract修饰的),默认方法
在这里插入图片描述
抽象方法:使用abstract关键字修饰的没有方法体{}的方法称为抽象方法
默认方法(jdk1.8之后才有的)
在这里插入图片描述

总结接口中的规定:
接口中只能有静态方法(因为静态方法不需要实例化对象)和抽象方法(抽象方法没有方法体:没有具体的执行代码)
接口不能自己像普通类一样直接new自己
接口中的属性都是公共静态常量(public static final), 必须在声明的时候赋予初始值

2.接口如何使用
在开发中大多使用抽象方法
接口的实例化是使用已知实现子类,采用多态思想来实例化对象
a.接口的实现
使用 implements 关键字来实现接口(实现接口的子类必须重写该接口的所有
抽象方法同时必须有具体的方法体)

在这里插入图片描述
在这里插入图片描述

一个子类可以同时实现多个接口 多个接口使用,(逗号)分割
接口可以继承接口
一个类既可以继承一个父类 也可以同时实现多个接口
在这里插入图片描述

b.接口的具体调用
调用静态方法
在这里插入图片描述
c.使用匿名对象的写法来调用
匿名对象就是实例化一个对象 没有具体的引用。匿名对象只能使用一次,不能被重复使用。
接口可以实例化自己,在实例化的时候 使用 new 接口名(){ 重写并实现接口中的所有抽象方法 }

//匿名对象调用接口方法
 @Test
 void test03() {
    
  //使用匿名对象调用普通类的方法
  //如果在操作中,只需要一次该对象就可以使用匿名对象,如果用多次,那还是实例化对象比较方便
  Phone phone=new Phone();//该实例化的对象被phone所引用,phone来重复使用该对象
  phone.chongdian();
  new Phone().chongdian();//匿名对象的调用
  //在接口中使用匿名对象(不考虑静态方法)剩下的都是抽象方法
  //抽象方法没有具体的方法实现(方法体)
  //使用匿名对象实例化接口,必须重写并实现接口中的所有抽象方法new Usb() {重写并实现抽象方法}.chongdian();
  //接口直接实现接口
  new Usb() {
    
   @Override
   public void chongdian() {
    
    // TODO Auto-generated method stub 
    System.out.println("接口自己实例化自己,重写的连接方法");
   }
   //重写该接口的抽象方法(Android)
   @Override
   public void chuanshu() {
    
    // TODO Auto-generated method stub
    System.out.println("接口自己实例化自己,重写的数据传输方法");
   
   }
   
  }.chongdian();
 }
 @Test
 void test04() {
    
  Usb usb=new Usb() {
    
   @Override
   public void chongdian() {
    
    // TODO Auto-generated method stub 
    System.out.println("接口自己实例化自己,重写的连接方法");
   }
   //重写该接口的抽象方法(Android)
   @Override
   public void chuanshu() {
    
    // TODO Auto-generated method stub
    System.out.println("接口自己实例化自己,重写的数据传输方法");
   
   }
   
  };
  usb.chongdian();
 }

接口可以使用多态的思想 用自己的已知实现子类来实例化自己。 最终调用接口的方法其实就是调用已知实现子类重写的方法。

//使用多态来实例化接口对象调用方法,其实调用的是子类的具体操作
 @Test
 void test02() {
    
  //实例化接口(多态:父类引用指向子类对象)
  Usb usb=new Phone();
  usb.chongdian();//手机充电
  Android usb2=new Phone();
  usb2.chuanshu();//使用数据线进行传输
  Usb usb1=new Upan();
  usb1.chongdian();//U盘进行数据传输
 }

接口的作用 : 接口是用来做方法的规定的。具体要根据最终实现自己的子类来决定具体应该怎么做。 一定要使用多态的思想。

子类实现了父类接口,必须要重写并实现接口中的所有的抽象方法
接口所在的包是dao包,接口的实现类所在的包叫 dao.imp

2.函数式接口
有且只有一个抽象方法的接口称为函数式接口。
使用注(是一个特殊的Java类)@FunctionalInterface来判断该接口是不是函数式接口
(1) 声明并验证

@FunctionalInterface//来判断该接口是不是函数式接口
public interface FunInter {
    
 void eat();//被public abstract 修饰
}

(2)使用
a.原始用法
使用已知实现子类
使用匿名对象的写法:new 接口名字(){重写抽象方法}
在这里插入图片描述

b.lambda表达式的用法(1.8新特性的使用方法)
Lambda 表达式 主要是1.8jdk中为了简化对函数式接口的实例化操作
语法:函数式接口类型变量 = (参数... ) -> { 重写的方法中的具体执行代码 };
()在参数只有一个的情况下可以省略
{ } 在方法中只有一条执行代码的时候{} 省略
参数可以不指定类型

package com.xing.yun.fun;
@FunctionalInterface//来判断该接口是不是函数式接口
public interface FunInter {
    
 //没有参数没有返回值
 void eat();//被public abstract 修饰
 
}
@FunctionalInterface
interface FunInter01 {
    
 //有参数没有返回值
 void eat(int a,int b);
 
}
@FunctionalInterface
interface FunInter02 {
    
 //没有参数有返回值
 int eat();
 
}
@FunctionalInterface
interface FunInter03 {
    
 //有参数有返回值
 int eat(int a,int b);
 
}
@FunctionalInterface
interface FunInter04 {
    
 //有一个参数没有返回值
 int eat(int a);
 
}

使用junit进行测试

package com.xing.yun.fun; 
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
//普通对象可以被重复调用,匿名对象只能使用一次
class FunInterTest {
    
 //普通匿名对象方式来实例化函数式接口
  @Test
 void test() {
    
//实例化对象
 new FunInter() {
    
       @Override
       public void eat() {
    
//TODO Auto-generated method stub
      System.out.println();      
      }
 }.eat();       
}
//函数式接口的lambda表达式的实例化调用
    @Test
    void test01() {
    
     //实例化接口对象
     FunInter  fi = () -> {
    System.out.println("我什么也不想吃");};
     fi.eat();
}
 //两个参数的方法,()里面的参数相当于形式参数
	@Test
	void test02() {
    
	//实例化接口对象()中的参数为重写抽象方法之后的形式参数
	FunInter01 fi = (int a,int b) -> {
    System.out.println(a+b);};
	FunInter01 fi1 = (num1,num2) -> {
    System.out.println(num1+num2);};
	//调用方法,就是调用lambda表达式重写之后的方法
	fi.eat(10,20);
	fi1.eat(10,20);
	 }
	//没有参数有返回值
 	 @Test
       void test03() {
    
	//实例化接口对象
        FunInter02 fi = () -> {
    return 100;};
 	FunInter02 fi1 = () -> 100;
         System.out.println(fi.eat());
         System.out.println(fi1.eat());
       }
       //有参有返回值
       @Test
       void test04() {
    
      //实例化接口对象
	 FunInter03 fi = (a,b) -> {
    
                     int num=a+b;
                     return num;
              };
              System.out.println(fi.eat(10,20));//实参类型是接口中的实参类型规定的              
       }
       //一个参数
       @Test
       void test05() {
    
            //实例化接口对象     1--100的总和
              FunInter04 fi = (int a) -> {
    
                     int sum=0;
                     for(int i = a; i <= 100; i++) {
    
                            sum=sum+i;
                     }
                     return sum;
              };
              System.out.println(fi.eat(1));            
       }
}

 

接口与类相似点:

一个接口可以有多个方法。

接口文件保存在 .java 结尾的文件中,文件名使用接口名。

接口的字节码文件保存在 .class 结尾的文件中。

接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

接口不能用于实例化对象。

接口没有构造方法。

接口中所有的方法必须是抽象方法。

接口不能包含成员变量,除了 static 和 final 变量。

接口不是被类继承了,而是要被类实现。

接口支持多继承。

接口特性

接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

重写接口中声明的方法时,需要注意以下规则:

类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。

类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。

如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

在实现接口的时候,也要注意一些规则:

一个类可以同时实现多个接口。

一个类只能继承一个类,但是能实现多个接口。

一个接口能继承另一个接口,这和类之间的继承比较相似。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/serendipity_xr/article/details/109433329

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签