viewpager默认界面_使用默认方法的界面演变–第一部分:方法

viewpager默认界面

几周前,我们详细研究了默认方法 -Java 8中引入的一项功能,该功能允许为接口方法提供实现,即方法主体,从而定义接口中的行为。 引入此功能是为了实现接口演进 。

在JDK的上下文中,这意味着在不破坏所有代码的情况下向接口添加新方法。 但是,尽管Java本身非常致力于保持向后兼容性,但其他项目并不一定要做到这一点。 如果愿意,他们可以以让客户更改其代码为代价来发展其接口。

在Java 8之前,这经常涉及客户端编译错误,因此可以避免更改,否则客户端必须一次性迁移。 使用默认方法,接口演变可以成为无错误的过程,在此过程中,客户可以在版本之间留出时间来逐步更新其代码。 这大大增加了开发接口的可行性,并使其成为常规的库开发工具。

让我们看一下如何添加,替换和删除接口方法。 以后的文章将探讨替换整个接口的方法。

总览

该帖子首先定义了一些术语,然后介绍了添加,替换和删除接口方法的方法。 它是从更改库中界面的开发人员的角度编写的。

我觉得该主题不需要示例,因此我没有编写任何示例。 如果您不同意并希望看到一些内容,请发表评论,并且-在时间允许的情况下-我会写一些。

术语

接口具有实现调用者 。 两者都可以存在于库中,在这种情况下,它们都称为internal ,或者在客户端代码中称为external 。 这总共增加了四种使用界面的类别。

根据接口的发展方式和存在的用途,必须采用不同的模式。 当然,如果既不存在外部实现也不存在外部调用者,则这些都不是必需的,因此本文的其余部分假定这些情况中至少有一种确实存在。

接口演变–方法

因此,让我们看看如何在不破坏客户端代码的情况下添加,替换或删除接口方法。

通常可以通过执行以下过程来实现:

新版本

该库的新版本已发布,其中接口定义是过渡性的,并结合了旧的和新的所需轮廓。 默认方法可确保所有外部实现和调用仍然有效,并且在更新时不会出现编译错误。

过渡

然后,客户就有时间从旧大纲过渡到新大纲。 同样,默认方法可确保适应的外部实现和调用有效,并且可以进行更改而不会产生编译错误。

新版本

在新版本中,该库删除了旧轮廓的残差。 鉴于客户端明智地利用了自己的时间并进行了必要的更改,因此发布新版本不会导致编译错误。

这个过程使客户能够按自己的时间表平稳地更新其代码,这使得接口的开发比以前更加可行。

由Johanna Pung在CC-BY-SA 3.0下为Wikimedia Deutschland发布。

Johanna Pung在CC-BY-SA 3.0下为Wikimedia Deutschland 发布 。

在遵循以下详细步骤时,请确保检查何时更新了内部和外部实现以及何时允许内部和外部调用者使用所涉及的方法。 确保在您自己的代码中遵循此过程,并为您的客户正确记录下来,以便他们知道何时执行操作。 Javadoc标签@Deprecated@apiNote是实现此目的的好方法。

通常,不必按该顺序执行过渡内的步骤。 如果是,则明确指出。

如果您向客户提供可以在其界面实现上运行的测试,则这些步骤中包含测试。

仅当存在外部接口实现时才需要此过程。 由于该方法是新方法,因此当然尚未调用,因此可以忽略这种情况。 区分是否可以提供合理的默认实现是有意义的。

存在合理的默认实现

新版本
  • 为新方法定义测试
  • 使用默认实现(通过测试)添加方法
  • 内部呼叫者可以使用该方法
  • 内部实现可以在必要时覆盖该方法
过渡
  • 外部呼叫者可以使用该方法
  • 外部实现可以在必要时覆盖该方法

无需执行任何操作,也不需要任何新版本。 这就是Java 8中添加的许多新的默认方法所发生的事情。

不存在合理的默认实现

新版本
  • 为新方法定义测试; 这些必须接受UnupportedOperationExceptions
  • 添加方法:
    • 包括一个引发UnupportedOperationException的默认实现(通过测试)
    • @apiNote注释文档,默认实现将最终被删除
  • 在所有内部实现中覆盖该方法
过渡

必须按该顺序执行以下步骤:

  • 外部实现必须重写该方法
  • 外部呼叫者可以使用该方法
新版本
  • 测试不再接受UnupportedOperationExceptions
  • 使方法抽象:
    • 删除默认实现
    • 删除@apiNote注释
  • 内部呼叫者可以使用该方法

勉强一致的默认实现允许外部实现逐渐更新。 请注意,在实际在内部或外部调用新方法之前,将更新所有实现。 因此,永远不会发生UnupportedOperationException。

更换

在这种情况下,一种方法将被另一种方法替代。 这包括一种方法更改其签名(例如,其名称或参数数量)的情况,在这种情况下,新版本可以看作是替换旧版本。

当存在外部实现或外部调用者时,必须应用此模式。 仅在两种方法在功能上等效时才起作用。 否则,就是添加一个功能并删除另一个功能的情况。

新版本
  • 为新方法定义测试
  • 添加新方法:
    • 包括调用旧方法的默认实现
    • @apiNote注释文档,默认实现将最终被删除
  • 弃用旧方法:
    • 包括调用新方法的默认实现(旨在进行循环调用;如果存在默认实现,则可以保留)
    • @apiNote注释文档,默认实现将最终被删除
    • @Deprecation评论文档说明将使用新方法
  • 内部实现会覆盖新方法,而不是旧方法
  • 内部调用者使用新方法代替旧方法
过渡
  • 外部实现会覆盖新方法,而不是旧方法
  • 外部呼叫者使用新方法代替旧方法
新版本
  • 使新方法抽象:
    • 删除默认实现
    • 删除@apiNote注释
  • 删除旧方法

尽管循环调用看起来很有趣,但它们确保实现哪种方法都无关紧要。 但是,由于这两种变体都有默认实现,因此,如果两种实现均未实现,则编译器不会产生错误。 不幸的是,这会产生无限循环,因此请确保将其指出给客户。 如果您为他们的实现提供测试,或者他们编写了自己的实现,则他们会立即意识到这一点。

去掉

删除方法时,根据是否存在外部实现,可以应用不同的模式。

存在外部实现

新版本
  • 方法的测试必须接受UnupportedOperationExceptions
  • 弃用该方法:
    • 包括一个引发UnupportedOperationException的默认实现(通过更新的测试)
    • @Deprecation注释文档表明该方法最终将被删除
    • @apiNote注释文档说明默认实现仅存在于逐步淘汰方法中
  • 内部呼叫者停止使用该方法
过渡

必须按该顺序执行以下步骤:

  • 外部呼叫者停止使用该方法
  • 该方法的外部实现已删除
新版本
  • 删除方法

请注意,只有在不存在对该方法的更多调用之后,才删除内部和外部实现。 因此,永远不会发生UnupportedOperationException。

外部实现不存在

在这种情况下,定期弃用就足够了。 仅出于完整性考虑而列出了这种情况。

新版本
  • @Depreated弃用该方法
  • 内部呼叫者停止使用该方法
过渡
  • 外部呼叫者停止呼叫方法
新版本
  • 删除方法

反射

我们已经看到了如何通过添加,替换和删除方法来实现界面演化:新的界面版本结合了旧的和新的轮廓,客户端从前者过渡到后者,而最终版本则消除了旧轮廓的残留物。 所涉及方法的默认实现确保客户端代码的旧版本和新版本都能正确编译和运行。

翻译自: https://www.javacodegeeks.com/2015/03/interface-evolution-with-default-methods-part-i-methods.html

viewpager默认界面

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

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

相关文章

C语言中scanf函数的3种常见问题与应对技巧

在写代码时难免对一些知识点不熟悉,导致犯错,今天分享几点小知识给大家。空白符问题#includeint main(void){int a;printf("input the data ");scanf("%d ",&a); //这里多了一个回车符printf("%d",a);return 0;}结果…

aws上部署hadoop_在AWS Elastic MapReduce上运行PageRank Hadoop作业

aws上部署hadoop在上一篇文章中,我描述了一个执行PageRank计算的示例,该示例是使用Apache Hadoop进行Mining Massive Dataset课程的一部分。 在那篇文章中,我接受了Java中现有的Hadoop作业,并做了一些修改(添加了单元测…

在嵌套使用if语句时,C语言规定else总是什么?

C语言的语法规定:else子句总是与前面最近的不带else的if相结合,与书写格式无关。在C语言中,使用if和else关键字对条件进行判断。请先看下面的代码:#include int main(){ int age; printf("请输入你的年龄:&…

continue语句的作用是结束整个循环的执行吗?

continue 语句的作用是结束本次循环,跳过循环体中剩余的语句而强制进入下一次循环(回到循环体的开头准备再次执行循环体)。continue语句只用在 while、for 循环中,常与 if 条件语句一起使用,判断条件是否成立。使用方式…

linux 远程权限不够,Eclipse连接远程Hadoop集群开发时权限不足问题解决方案

eclipse连接远程Hadoop集群开发时报错Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied: userd, accessWRITE, inode"data":zxg:supergroup:rwxr-xr-xat org.apache.hadoop.hdfs.server.namenode.FSPerm…

一文掌握 C 智能指针的使用

RAII 与引用计数了解 objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。基本想法是对于动态分配的对象,进行引用计数,每当增加一次对同一个对象的引用,那么引用对象的引用计数就会增加一次&a…

fwrite函数的一般调用形式是什么?

fwrite() 是C 语言标准库中的一个文件处理函数,功能是向指定的文件中写入若干数据块,如成功执行则返回实际写入的数据块数目。该函数以二进制形式对文件进行操作,不局限于文本文件。语法:fwrite(buffer,size,count,fp)参数&#x…

lambdas 排序_Java8 Lambdas:解释性能缺陷的排序

lambdas 排序与Peter Lawrey合作撰写 。 几天前,我对使用新的Java8声明式的排序性能提出了一个严重的问题。 在这里查看博客文章。 在那篇文章中,我仅指出了问题,但在这篇文章中,我将更深入地了解和解释问题的原因。 这将通过使用…

strncmp函数用法是什么

strncmp函数用法&#xff1a;函数原型int strcmp(char *str1,char * str2&#xff0c;int n)功能比较字符串str1和str2的前n个字符。头文件#include 返回值返回值&#xff1a;返回整数值&#xff1a;当str1<str2时&#xff0c;返回值<0&#xff1b; str1"str2时&…

分享10个适合初学者学习的C开源项目代码

1.WebbenchWebbench 是一个在 linux 下使用的非常简单的网站压测工具。它使用 fork ()模拟多个客户端同时访问我们设定的 URL&#xff0c;测试网站在压力下工作的性能&#xff0c;最多可以模拟 3 万个并发连接去测试网站的负载能力。Webbench 使用C语言编写&#xff0c; 代码实…

tomcat与tomee_Apache TomEE(和Tomcat)的自签名证书

tomcat与tomee可能在大多数Java EE项目中&#xff0c;您将拥有具有SSL支持&#xff08; https &#xff09;的部分或整个系统&#xff0c;因此浏览器和服务器可以通过安全连接进行通信。 这意味着在处理数据之前&#xff0c;已发送的数据已加密&#xff0c;传输并最终解密。 …

C 线程的使用~(上)

C 11 之前&#xff0c;C 语言没有对并发编程提供语言级别的支持&#xff0c;这使得我们在编写可移植的并发程序时&#xff0c;存在诸多的不便。现在 C 11 中增加了线程以及线程相关的类&#xff0c;很方便地支持了并发编程&#xff0c;使得编写的多线程程序的可移植性得到了很大…

k8s中graphite_在Graphite中存储Hystrix的几个月历史指标

k8s中graphiteHystrix的杀手级功能之一是低延迟&#xff0c;数据密集和美观的仪表板 &#xff1a; 即使这只是Hystrix实际操作的副作用&#xff08;断路器&#xff0c;线程池&#xff0c;超时等&#xff09;&#xff0c;它也往往是最令人印象深刻的功能。 为了使其工作&#…

C语言中的“三字母词”坑了工程师

某软件工程师接盘了前同事的项目&#xff0c;进度一拖再拖&#xff0c;最后发现问题出现在如下代码&#xff1a;// 注释语句 ??/2a b c;请注意代码中的“??/”&#xff0c;就是这注释隐藏的很深&#xff0c;让项目一拖再拖。"??/"会被编译器当作 /&#xff0c…

C 线程的使用~(下)

2.3 detach()detach() 函数的作用是进行线程分离&#xff0c;分离主线程和创建出的子线程。在线程分离之后&#xff0c;主线程退出也会一并销毁创建出的所有子线程&#xff0c;在主线程退出之前&#xff0c;它可以脱离主线程继续独立的运行&#xff0c;任务执行完毕之后&#x…

用c语言编写爱心的代码是什么

用c语言编写爱心的代码&#xff1a;输入完整代码如下&#xff1a;#include int main(void){float a,x,y;for(y1.5f; y>-1.5f; y-0.1f){for(x-1.5f; x<1.5f; x 0.05f){a x*x y*y-1;char ch a*a*a-x*x*y*y*y<0.0f?*: ; putchar(ch); }printf("\n");}retur…

c++ lambda 重载_您会后悔对Lambdas应用重载!

c lambda 重载编写好的API很难。 非常辛苦。 如果您希望用户喜欢您的API&#xff0c;则必须考虑很多事情。 您必须在以下两者之间找到适当的平衡&#xff1a; 用处 易用性 向后兼容 前向兼容性 之前&#xff0c;在我们的文章&#xff1a; 如何设计良好的常规API中&#xf…

7个华为关于C语言的经典面试题

1、找错void test1(){ char string[10]; char* str1"0123456789"; strcpy(string, str1);}这里string数组越界&#xff0c;因为字符串长度为10&#xff0c;还有一个结束符’\0’。所以总共有11个字符长度。string数组大小为10&#xff0c;这里越界了。PS&am…

linux数组操作 增删改查,linuxea:go数组与数组增删改查(19)

复合数据类型是集合类&#xff0c;并且可以存储多个单值。在golang中存储的数组是相同的数据类型&#xff0c;并且长度也是其中的一个属性。在go中&#xff0c;数组的长度一旦定义&#xff0c;就不可变。如果声明了长度的变量&#xff0c;只能赋值相同的长度的数组数组是具有相…

C语言的特点与创建的基本步骤是什么

C语言的特点与创建的基本步骤是&#xff1a;C 语言特点&#xff1a;1.C语言是一种成功的系统描述语言&#xff0c;用C语言开发的UNIX操作系统就是一个成功的范例;2.同时C语言又是一种通用的程序设计语言&#xff0c;在国际上广泛流行。世界上很多著名的计算公司都成功的开发了不…