接口(基本接口和函数式接口)

一.接口

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

接口是一个特殊的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 修饰会报编译错误)。

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

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

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

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值