java1.8--改进的接口

关于接口,每天的编码都在写,就不多说了。这里对比下接口,抽象类,类3者的关系:
1),接口是一种规范,就是告诉外界这个东东可以做什么。
2),抽象类是一种模板,就是告诉外界这个东西的一部分公共功能。
3),类和上面的接口,抽象类最大的区别就是类可以维护状态信息。

  • 在以前的接口中
1,没有构造方法,不能实例化
2,接口只能继承接口,不能继承类
3,接口里没有普通方法,方法全是抽象的
4,接口里的方法默认修饰符是public abstract
5,接口里的字段全是全局常量,默认修饰符是public static final


java8中的接口在原来的基础上增加了一些功能,主要是2个:默认方法,静态方法。
  • 1,默认方法
首先来了解下为什么会出现默认方法这个东西。许多开发语言都将函数表达式集成到了其集合库中,这样子比循环方式所需的代码更少,并且更加容易理解。比如以前我们写循环代码:
for(int i = 0; i<list.size();i++)
{System.out.println(list.get(i));
}

现在我们使用函数函数式编程,代码如下:
public static void main(String[] args){List<Integer> list = Lists.newArrayList(1, 2, 3);Stream<Integer> stream = list.stream();stream.forEach(System.out::println);}
现在假设我们自己不用流,我们想直接在list集合上面提供一个forEach方法,用来将一个函数应用到集合的每一个元素上面。下面是使用这种方式编写的代码:
list.forEach(System.out::println);
上面的效果很好,如果我们自己定义也就是说重新设计集合当然是没有问题的,但是java的集合是许多年前设计的,这就会带来一个问题,我们为List接口增加了一个方法,那么所有的实现类都要改过,这样子代码才不会报错,这基本是无法想象的。所以呢,java设计者希望通过允许接口包含具体实现的方法来一劳永逸的解决这个问题。当然,为接口提供默认方法还有别的好处,我们一会会整理到。
java8中允许在接口中定义默认方法,默认方法必须使用default来修饰。先来看一个例子,熟悉下java8中默认方法的语法:
public class Test implements TestInterface
{public static void main(String[] args){Test test = new Test();//使用自己类中的方法System.out.println(test.getId());//使用接口中的默认方法System.out.println(test.getName());}@Overridepublic Integer getId(){return 25;}}interface TestInterface
{Integer getId();default String getName(){return "默认方法里面的输出。。。";}
}

上面的代码使用了TestInterface接口中定义的默认方法getName(),程序执行没一点问题。当然我们也可以自己来重写接口中默认方法中的默认方法。
public class Test implements TestInterface
{public static void main(String[] args){Test test = new Test();//使用自己类中的方法System.out.println(test.getId());//使用接口中的默认方法System.out.println(test.getName());}@Overridepublic Integer getId(){return 25;}@Overridepublic String getName(){//默认使用接口中的默认方法,注意下面的使用父类接口中方法的语法//return TestInterface.super.getName();return "自己的类中重写了接口中的默认方法";}}interface TestInterface
{Integer getId();default String getName(){return "默认方法里面的输出。。。";}
}
在上面的使用过程中,我们发现了现在使用java8接口的默认方法很好的解决了前面我说的问题了,我们不必在每个实现类中都去实现接口中新加的方法了,只需要在接口中增加一个default修饰的默认方法就好了。

另外,在上面的编码过程中,我们不难还能发现一个使用默认方法带来的好处,我们现在可以很方便的在接口中指定本质上可选的方法,根据接口的使用方式来选择使用的方法。举个例子吧,比如我们定义了一个接口,里面有一个删除元素的方法remove(),但是实际情况是这个接口应该支持可修改和不可修改2种系列,在可修改系列中没有问题,我们直接实现remove()方法就好了,不可修改系列我们不需要这个方法,但是也只能定义一个remove()的空实现,最好抛出一个异常。现在我们使用java8中的默认方法,就避免了用于不可修改系列的类也必须定义自己的,占位符性质的多余的方法,总结一下就是说默认方法让一些类要去实现的方法变成了可选方法。

  • 总结一下:
默认方法提供了2个优点:
1,优雅的随时间演化接口。也就是代码的向后兼容性
2,提供可选功能,类不必在不需要该功能的时候提供占位符实现。


  • 2,多级继承的问题
java中的继承是单继承,这个不多说了。现在考虑到接口新增的默认方法,现在java是不是绕开了单继承呢?明显不是。接口不能维护状态信息,但是现在默认方法可以提供一些行为上面的多继承。比如说一个类实现2个接口,在这2个接口中定义了2个默认方法,那么这个类同时拿到了2个方法,编码确实多了很大的灵活性。但是也会有一个很明确也是必须要解决的问题,就是冲突问题,比如说A类实现了B接口,C接口,如果B和C接口都提供了一个叫test的默认方法,那A类将实现那个接口里面的test方法呢?又比如说A类提供了自己的实现,这时候将发生什么?又比如说A同时也继承了一个有test方法的类,那么这个时候有事什么情况呢?


不慌的,解决上面的问题很简单,就是定义一组规则就好了,按照一个约定来定义解决上面的冲突。具体的规则如下:
1),在所有的情况,类实现的优先级高于接口的默认实现,也就是先使用自己类中定义的方法或者是父类中的方法。类优先是解决上面系列问题的最主要的规则。
2),当类同时实现了2个接口,2个接口中如果包含相同的默认方法,那么这个类中就必须重写这个接口,不然代码报错。
3),如果是一个接口继承了另外一个接口,2个接口中也包含相同的默认方法,那么继承接口的版本具有更高的优先级。比如A扩展了B接口,那么优先使用A类里面的test方法。
4),通过使用super,可以显式的引用被继承接口的默认实现,语法如下:InterfaceName.super.methodName()。
相关代码如下:
public class Test extends C
{public static void main(String[] args){Test test = new Test();System.out.println(test.getName());}}class C implements A, B
{@Overridepublic Integer getId(){// TODO Auto-generated method stubreturn null;}//不管接口A和接口B中的这个方法是不是默认方法,有没有提供实现都必须重写, 不然代码报错@Overridepublic String getName(){System.out.println(A.super.getName());return "自己类中必须重写这个方法。。。";}}interface A
{Integer getId();default String getName(){return "接口A。。。";}
}interface B
{default String getName(){return "接口B。。。";}}

  • 3,在接口中使用静态方法
在java8中为接口新增了一项功能,定义一个或者更多个静态方法。类似于类中的静态方法,接口定义的静态方法可以独立于任何对象调用。所以,在调用静态方法时,不需要实现接口,也不需要接口的实例,也就是说哦和调用类的静态方法的方式类似。语法如下:
接口名字.静态方法名。
public class Test implements A
{public static void main(String[] args){System.out.println(A.getName());}}interface A
{static String getName(){return "接口A。。。";}
}

注意,实现接口的类或者子接口不会继承接口中的静态方法。static不能和default同时使用。在java8中很多接口中都增加了静态方法,比如下面代码:
public class Test 
{public static void test(List<String> list){//直接使用Comparator的静态方法list.sort(Comparator.comparing(String::length));}public static void main(String[] args){List<String> list = Lists.newArrayList("122","2","32");test(list);for (String str : list){System.out.println(str);}}}

转载于:https://www.cnblogs.com/LinkinPark/p/5232972.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/287049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF效果第一百八十五篇之又玩TreeView

最近又有新的开发任务了,然后我提前瞄了一眼需要实现的效果;发现其中一个和我去年玩耍的有点类似;正好好久也没玩了,那就趁着这个机会再次学习一下;闲话也不多扯了,上效果:2、来看看我的实现方式:3、①是一个分组的数据模板<HierarchicalDataTemplate x:Key"GroupDataT…

ArcGIS实验教程——实验二十三:专题地图制作完整实验步骤

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据) 一、实验描述 专题地图是一个非常复杂的过程,地图数据的符号化与注记标注,都是地图编制准备基础的地理数据。然而,要将准备好的地图数据,通过一幅完整的地图表达出来,还有很多工作,包括布局…

IOS 封装轮播图

轮播图为一种常见的方式&#xff0c;常用于各种网站&#xff0c;或者App中&#xff0c;当然&#xff0c;作为APP的启动视图也是不错的选择。 闲时封装了一个&#xff0c;仅供新手参考。 1.新建工程&#xff0c;建立轮播图类 建立一个空的工程&#xff0c;新建一个类&#xff0c…

分布式事务TCC补偿机制

文章目录 概述工作流程优缺点优点&#xff1a;缺点&#xff1a; 总结Java 示例代码 概述 TCC&#xff08;Try-Confirm-Cancel&#xff09;补偿机制是一种事务处理模式&#xff0c;用于确保分布式系统中的操作成功完成或在失败时进行补偿。TCC将一个事务拆分为三个阶段&#xf…

oracle的本地安装和PUTTY+XMING远程连接安装和oracle翻页功能

因为我也是一个初学者&#xff0c;所以可能有出错的地方&#xff0c;如果有希望大家告诉我QQ:7343696.大家公共学习&#xff0c;进步。Oracle的安装实验的环境是vmware server 1.06 rehl 5.2最小安装。oracle安装的要求。1建议的内存1G&#xff08;10g&#xff09; 9i中是51…

Flutter之导url_launcher包提示 A dependency may only have one source.

1、问题 flutter项目在pubspec.yaml导入url_launcher包&#xff0c;然后点击Pub get错误提示如下 F:\flutter_sdk\flutter\bin\flutter.bat --no-color pub get Running "flutter pub get" in flutter_1... Error on line 25, column 5 of …

这是我第一次使用代码创建出一个窗口【python 游戏实战 01】

前言 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新…

如何html中添加动态图片,把动态图片添加到视频画面中 视频添加自定义动态图片 视频加动态logo...

我前面也编写过关于视频添加动态图片的教程。前面所说的给是视频添加的动态图片是软件中自带的素材&#xff0c;虽然软件中带的动态图片种类繁多&#xff0c;但是不外乎有些时候软件中并没有我们要用的动态图片&#xff0c;这个时候我们就需要重外部添加啦&#xff0c;好多的软…

ASP.NET Core 集成AAD认证在Docker中运行时要注意的一个问题

最近我在准备一个分享&#xff0c;就是基于.NET 6.0的云原生开发Microsoft 365应用&#xff0c;这个看起来很高大上的东东&#xff0c;其实我理解主要就是能把应用容器化&#xff0c;便于与环境无关地进行分发和部署。如果理解有误&#xff0c;请大家纠正我。下面是其中的一个例…

QCon上海2015精彩回顾和总结

金秋十月&#xff0c;历时三天的QCon上海2015于10月17日顺利闭幕。本次大会邀请了100多位技术专家&#xff0c;为参会者奉上了100多场精彩的技术演讲。\\本次QCon邀请了极客邦创始人兼CEO霍泰稳&#xff0c;携程旅行网CTO、高级技术副总裁叶亚明&#xff0c;丁香园技术VP、EGO上…

ArcGIS中合并(merge)、联合(union)、追加(append)、融合(dissolve)的用法区别与联系

ArcGIS中,针对矢量数据拼接,有多个工具:合并(merge)、联合(union)、追加(append)、融合(dissolve)等,本文以甘肃省1:100万县级数据详细讲解以上各个工具的用法、区别和注意事项。 有关合并(merge)、联合(union)、追加(append)、融合(dissolve)等基础操作内…

Singleton

问题&#xff1a;编写一个Singleton类 简单的方式 1 package cn.changb.singleton;2 3 /**4 * 简单的方式:弊端是在并发执行时&#xff0c;14行处可能存在多个实例5 */6 public class SingletonDemo1 {7 private static SingletonDemo1 INSTANCE;8 9 private Singlet…

Flutter之运行提示Could not update files on device: Connection closed before full header was received

1 问题 运行flutter app提示错误如下 Performing hot restart... Syncing files to device MIX 3... Could not update files on device: HttpException: Connection closed before full header was received, uri http://127.0.0.1:65054/-tzvW6oGieQ/ Restarted applicati…

C++ 语法都不会怎么写代码? 03

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。系列教程将会…

自定义dialog弹窗html,自定义H5页面dialog弹窗

弹窗一&#xff1a;样式如下&#xff1a;HTML代码&#xff1a;//弹出窗通知取消确认//遮罩层$(.dialog .content).text(text);$(.dialog, .mark).removeClass(hide);}tipDialog("1111");$(".sure").click(function(){var type $(this).attr(type);if(typeb…

【三维激光扫描】第二章:国内外三维激光扫描设备简介

地面三维激光扫描仪是地面激光扫描系统中最主要的硬件设备,近年来得到了快速发展,主要体现在品牌数量、性能指标、类型等方面的变化。本章主要介绍国内外主要设备的基本情况,对国内外研究现状进行分析,最后指出目前存在的问题与未来的发展趋势。 2.1 国外地面三维激光扫描仪…

Winform定时启动

System.Timers.Timer t;int sum 0;int qian;int bai;int shi;int ge;public 测试定时启动(){InitializeComponent();}//1.使用System.Timers.Timer//2.threadThread th;//定义线程private void 测试定时启动_Load(object sender, EventArgs e){textBox1.Text "00.00&quo…

聊一聊容器暂停退出

1背景介绍 最近在写 docker 相关教程&#xff0c;过程中发现容器暂停退出竟然有 docker kill、docker stop 和 docker pause 三种方式&#xff0c;今天就来分析下三者间的区别。2辅助指令 docker top - 查看容器进程docker event - 查看容器相关事件docker stats -…

初学者必看的文章:在VM12中安装 RedHat RHEL7.2  系统的详细步骤:看我如何操纵RHEL系统...

一、开始安装 1&#xff09;新建虚拟机 RHEL7.2 2&#xff09;成功引导系统--开机出现此画面 Install Red Hat EnterpriseLinux 7.2 安装RHLE7.2 操作系统 Test this edia & install RedHat Enterpris…

Flutter之点击按钮打开百度链接

1 需求 点击按钮&#xff0c;打开百度链接 2 代码实现 import package:flutter/material.dart; import package:url_launcher/url_launcher.dart;void main() {runApp(MyApp1()); }class MyApp1 extends StatelessWidget {overrideWidget build(BuildContext context) {return…