美文网首页
Java 开发,关于接口以及abstract class的二三事

Java 开发,关于接口以及abstract class的二三事

作者: 天下第九九八十一 | 来源:发表于2021-02-17 18:20 被阅读0次

    一、接口

    Java 用 implements interface 的模式使用接口。

    interface jieKou{ void some_action(); }
    class A implements interface { @override void  some_action(){/* do some thing*/}; }
    

    一开始还以为 @override 是必须要写的,原来不是,转到 IDEA 后用Java是真的舒服,就是内存要求有点高,几年前的8GB内存,现在已经隐隐不够用了……

    接口中定义的方法,可由父类实现,即在扩展类中,用接口去“套”父类中的方法。

    使用接口的特性,可以用一致接口将多个不同的实现统合为一。一个典型的列子就是通用的webview接口,比如 webview.evaluateJavascript() ,先定义接口:

    public interface UniversalWebviewInterface {
        void evaluateJavascript(String jsText, ValueCallback<String> valueCallback);
    }
    

    然后,对于原生webview和腾讯公司研发的X5Webview,可以分别这样:

    • 原生webview
    public class WebViewNative extends WebView implements UniversalWebviewInterface {
    // 可以除了构造,啥都不用写
    }
    
    • X5Webview
    package com.tencent.smtt.sdk;
    
        public void evaluateJavascript(String var1, android.webkit.ValueCallback<String> var2) {
            try {
                View var3 = this.X5WebView.getView();
                Method var4 = ReflectionUtils.a(var3, "evaluateJavascript", String.class, android.webkit.ValueCallback.class);
                var4.setAccessible(true);
                var4.invoke(this.X5WebView.getView(), var1, var2);
            } catch (Exception var7) {
                var7.printStackTrace();
                this.loadUrl(var1);
            }
        }
    

    这是“反混淆”解压出后的代码,可以看出已经帮我们实现好了,直接用接口“套”它即可。不过并非所有方法如此,有的方法 X5WebView 使用了自定义类,而不是 android.webkit.* 中的原生类,我对“反混淆”后的代码进行魔改,最终证明是能够兼容的。

    接口的方法定义后会占用一个方法数,子类继承父类实现接口,父类被“套”上的方法,不会再额外计入方法数。

    如何查看方法数:将文件拖入 android studio 即可。

    如何反编译(非 JD-GUI):

    java -cp "C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.2.3\plugins\java-decompiler\lib\java-decompiler.jar" org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true . src

    如何“反混淆”:结合其他资料,手动修改 a b c d e f g。

    二、抽象类

    abstract class 可以implements多个接口,但不用做任何定义。

    abstract class  SuperAmazingAbstract implements jiekou1, jiekou2, jiekou3{
                       // 这里啥都不用写
    }
    
    class Activity123 ...{
        void HaHa{
              SuperAmazingAbstract shiXian = new SuperAmazingAbstract(){
                        // 实现 jiekou1 中定义的方法
                        // 实现 jiekou2 中定义的方法
                        // 实现 jiekou3 中定义的方法
        }
         }
    }
    

    一个典型例子是用一个内部类同时糅和 View.onClickListener、View.onLongClickListener、AdapterView.OnItemClickListener 等监听器,使用起来极为方便。

    • 定义
    package com.knziha.polymer.widgets;
    
    import android.view.View;
    import android.widget.AdapterView;
    
    public abstract class SuperItemListener
            implements View.OnClickListener ,
            View.OnLongClickListener, AdapterView.OnItemClickListener
    { }
    
    
    • 使用
    SuperItemListener schEngItemLis = new SuperItemListener() {
        boolean isLongClicked;
        boolean longClick;
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            onClick(view);
        }
        
        @Override
        public boolean onLongClick(View v) {
            isLongClicked=true;
            longClick=true;
            onClick(v);
            return longClick;
        }
        
        @Override
        public void onClick(View v) {
            SearchEnginesItemBinding itemData = (SearchEnginesItemBinding) getTypedTagInAncestors(v, 3, SearchEnginesItemBinding.class);
            if(itemData!=null) {
                int position = (int) itemData.title.getTag();
                int id = v.getId();
                switch (id) {
                    ...
                }
            }
        }
    

    最后,展示下最近用此方法实现的,用于浏览器的,搜索引擎列表。自定义修改、排序最为便捷,向左侧滑动打开选项菜单,可以同时打开多个,长按其中的按钮或可进行批量操作。

    200k 动图:




    \

    三、避坑 java.lang.VerifyError

    用接口去套父类的方法,若该方法在低版本的安卓平台上不存在,那就悲催, 在构造的时候会抛出 java.lang.VerifyError ,出现类验证错误,还是第一次遇到这个 BUG。

    比如,webview 用于打印PDF的接口,API > 21 才有效。

        PrintDocumentAdapter createPrintDocumentAdapter(String name);
    

    只好改写,我算是明白 X5Webview 的 createPrintDocumentAdapter 方法为何返回 Object 了。此处连名字都要避讳,真是晦气。

        Object initPrintDocumentAdapter(String name);
    

    全文完

    相关文章

      网友评论

          本文标题:Java 开发,关于接口以及abstract class的二三事

          本文链接:https://www.haomeiwen.com/subject/cpzixltx.html