热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

具有将来兼容性的类,不会破坏以后的修改

如何解决《具有将来兼容性的类,不会破坏以后的修改》经验,为你挑选了4个好方法。

我正在阅读Android的源代码,RecyclerView并且正在使用SimpleOnItemTouchListener和阅读有关此类的文档。但是我不确定我是否理解这个意思:

使用此类的另一个好处是将来的兼容性。由于界面可能会发生变化,因此我们将始终在此类上提供默认实现,以便在您更新到支持库的新版本时代码不会中断

这是因为SimpleOnItemTouchListener实现OnItemTouchListener并提供了一些默认行为吗?因此,如果OnItemTouchListener获取更新,SimpleOnItemTouchListener仍将返回默认行为。

关于“如果界面可能会更改”的部分。他们在谈论什么OnItemTouchListener吗?

但是,SimpleOnItemTouchListener公正似乎有空方法,仅此而已。



1> walen..:

假设您有这个介面:

public interface OnItemTouchListener {
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
}

然后,您决定自己实施:

public class MyOwnOnItemTouchListener implements OnItemTouchListener {

    @Override
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        boolean result = doSomething(e);
        return result;
    }

    @Override
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        doSomethingElse(rv, e);
        doSomethingMore(rv);
    }

    @Override
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        if (disallowIntercept) {
            doADifferentThing();
        }
    }
}

一切都很好……
直到六个月后,OnItemTouchListener都进行了修改以引入一种新方法:

public interface OnItemTouchListener {
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
    // New method
    void onMultiTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
}

突然之间,您的应用将无法编译

Error: MyOwnOnItemTouchListener is not abstract and does not override abstract method onMultiTouchEvent() in OnItemTouchListener

这甚至不是您的错,您什么也没改变!只是界面已更改,并且您的代码不是最新的


为了避免这种情况,该API的开发人员为您提供一个“默认”的实现类SimpleOnItemTouchListener即是保证始终是最新与接口,并且您可以去继承:

public class SimpleOnItemTouchListener implements OnItemTouchListener {
    // empty, override in your class 
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { return false; }
    // empty, override in your class 
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
    // empty, override in your class 
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
}

因此,您可以执行以下操作,而不是直接实现接口:

public class MyOwnOnItemTouchListener extends SimpleOnItemTouchListener { //extend Simple instead of implementing interface

    @Override
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        boolean result = doSomething(e);
        return result;
    }

    @Override
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        doSomethingElse(rv, e);
        doSomethingMore(rv);
    }

    @Override
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        if (disallowIntercept) {
            doADifferentThing();
        }
    }
}

现在,如果API开发人员在六个月内需要引入一种新方法,则可以保证更改两个

public interface OnItemTouchListener {
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
    // New method
    void onMultiTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
}
public class SimpleOnItemTouchListener implements OnItemTouchListener {
    // empty, override in your class 
    boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { return false; }
    // empty, override in your class 
    void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
    // empty, override in your class 
    void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
    // New method
    // empty, override in your class 
    void onMultiTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
}

现在,尽管这个变化,MyOwnOnItemTouchListener仍然会进行编译,即使它没有实现onMultiTouchEvent,因为如果在任何时候MyOwnOnItemTouchListener.onMultiTouchEvent()被调用它将只使用从其父(空)的实施,SimpleOnItemTouchListener

而且您的应用将继续运行


现在,回答您的确切问题:

这是因为SimpleOnItemTouchListener实现OnItemTouchListener并提供了一些默认行为吗?

是。尽管这里的“默认行为”是“什么都不做”,所以如果您想实际执行某项操作,则仍然需要在自己的侦听器中实现这些方法。

因此,如果OnItemTouchListener获取更新,SimpleOnItemTouchListener仍将返回默认行为。

对,就是这样。

关于“如果界面可能会更改”的部分。他们在谈论什么OnItemTouchListener吗?

是。

但是,SimpleOnItemTouchListener公正似乎有空方法,仅此而已。

是。他们提供的“默认行为”只是“什么都不做”。这只是避免编译失败的一种方法。
您仍然必须以有意义的方式实现这些方法。但是现在,如果引入了新方法,您将拥有一个安全网。

我想说您实际上了解它的要点,只是空的默认实现令人困惑。



2> marcinj..:

这是因为SimpleOnItemTouchListener实现了OnItemTouchListener并提供了一些默认行为吗?

不,它只是用空方法实现接口。如您所知,实现接口时,需要为所有接口方法添加定义,否则会出现编译错误。但是,如果您扩展了一个类,则无需覆盖所有基本方法(嗯...除非它们不是抽象的-但这不是这种情况)。

关于界面是否可能更改的部分。他们是在谈论OnItemOnTouchListener吗?

是的,他们谈论接口RecyclerView.OnItemTouchListener被更改:

http://androidxref.com/9.0.0_r3/xref/frameworks/support/v7/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java#OnItemTouchListener

假设它们在RecyclerView.OnItemTouchListener中添加了一个新方法:void foo(),那么,如果升级支持库并且您已经在类中直接实现了RecyclerView.OnItemTouchListener,那么您将得到编译器错误(您将需要foo()在类中实现)。在您引用的评论中, android团队承诺他们将在SimpleOnItemTouchListener中实现foo(),因此,如果在其中进行扩展,MyOnItemTouchListener它们将已经具有空的实现-因此不会发生编译错误。



3> Kris..:

我发现它或多或少是Adapter实现的。随着android的不断发展,交互作用将永远不会相同,并且会随着OS的发展而不断发展。

在这里,OnItemTouchListener可以实现根接口,以便应用程序可以控制已消耗或正在消耗的触摸事件。用简单的话说,OnItemTouchListener您要处理触摸事件吗?实施我!但是要准备好处理为您抓到的各种新手势。我很动态

现在,另一个人走了SimpleOnItemTouchListener进来,说:“嘿,我可以作为您的顾问OnItemTouchListener。我们可以就所要处理的问题达成协议。即使OnItemTouchListener对新事物感到恼火,我也会帮助您保持镇定而不改变我会承受痛苦并确保你不被打扰“

所以它的简单性,OnItemTouchListener可能会随着Android的发展而不断发展。SimpleOnItemTouchListener可能会随着一起发展OnItemTouchListener,但不会在任何当前行为中被弃用或遗忘。

添加更多内容,因为SimpleOnItemTouchListener它为您提供了默认的实现,因此您的代码看起来很简洁,因为您只需要覆盖所需的内容即可。



4> 小智..:

我目前正在为我正在处理的项目开发一个插件框架。我试图通过对界面进行版本控制来解决此问题。我确实有像walen所说的基本实现。但是,我担心实现接口而不是基本实现的人员。当然,如果我更改界面并发布,我只会破坏那些决定不扩展基类的插件。

核心应用程序使用该部分代码所需的任何版本的接口。V2版本的接口将扩展V1,V3扩展V2,以此类推。我没有直接调用所有插件,而是有一个可以工作的manager类。这使我可以确保,如果V3功能正在尝试执行,那么我只会在实现了V3版本插件界面的插件上执行此操作。

如果我只是公开基类并从公共API隐藏接口,那么我可能只需要其他人扩展的基础实现就可以实现。不幸的是,由于该接口也是公共的,所以我必须确保不破坏没有扩展基类的开发人员。


推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
author-avatar
nikechen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有