如何在Java中实现具有单应性方法的接口?

2024-02-24

在英语中,同形异义词对是具有相同拼写但不同含义的两个单词。

在软件工程中,一对单应性方法是名称相同但要求不同的两种方法。让我们看一个人为的示例,以使问题尽可能清楚:

interface I1 { 
    /** return 1 */ 
    int f()
}
interface I2 {
    /** return 2*/
    int f()
}
interface I12 extends I1, I2 {}

我该如何实施I12? C# 有办法 https://stackoverflow.com/questions/4103300/c-sharp-why-implement-interface-explicitly这样做,但 Java 没有。所以唯一的解决办法就是破解。如何通过反射/字节码技巧/等来完成最可靠(即它不一定是一个完美的解决方案,我只想要最有效的解决方案)?


请注意,我无法合法地进行逆向工程的一些现有闭源大量遗留代码需要类型参数I12并代表I12两者都具有的代码I1作为参数,并且代码具有I2作为参数。所以基本上我需要做一个实例I12知道什么时候它应该充当I1以及何时应充当I2,我相信可以通过在运行时查看字节码 https://stackoverflow.com/questions/2737285/is-there-a-way-to-obtain-the-bytecode-for-a-class-at-runtime直接呼叫者的。我们可以假设调用者没有使用反射,因为这是简单的代码。问题是作者I12没想到Java合并了f来自两个界面,所以现在我必须想出解决该问题的最佳方法。没有任何召唤I12.f(显然,如果作者编写了一些实际调用的代码I12.f,他会在出售之前注意到这个问题)。

请注意,我实际上是在寻找这个问题的答案,而不是如何重组我无法更改的代码。我正在寻找可能的最佳启发式方法或精确的解决方案(如果存在)。请参阅格雷的答案以获得有效的示例(我确信有更强大的解决方案)。


Here https://stackoverflow.com/questions/15795058/triads-not-showing-up-to-fight-java-set-missing-an-item是两个接口中单应性方法问题如何发生的具体示例。这是另一个具体的例子:

我有以下 6 个简单的类/接口。它类似于围绕剧院和在其中表演的艺术家的商业活动。为了简单和具体,我们假设它们都是由不同的人创建的。

Set表示一个集合,如集合论中:

interface Set {
    /** Complements this set,
        i.e: all elements in the set are removed,
        and all other elements in the universe are added. */
    public void complement();
    /** Remove an arbitrary element from the set */
    public void remove();
    public boolean empty();
}

HRDepartment uses Set代表员工。它使用复杂的流程来解码要雇用/解雇哪些员工:

import java.util.Random;
class HRDepartment {
    private Random random = new Random();
    private Set employees;

    public HRDepartment(Set employees) {
        this.employees = employees;
    }

    public void doHiringAndLayingoffProcess() {
        if (random.nextBoolean())
            employees.complement();
        else
            employees.remove();
        if (employees.empty())
            employees.complement();
    }
}

一个的宇宙Set的雇员可能是已向雇主提出申请的雇员。所以当complement当该集合被调用时,所有现有员工都会被解雇,而之前申请的所有其他员工都会被雇用。

Artist代表艺术家,例如音乐家或演员。艺术家有自我。当别人称赞他时,他的自我意识就会增强:

interface Artist {
    /** Complements the artist. Increases ego. */
    public void complement();
    public int getEgo();
}

Theater使Artist执行,这可能会导致Artist待补充。剧院的观众可以在表演之间评判艺术家。表演者的自我意识越高,观众就越可能喜欢他的表演。Artist,但如果自我超越某一点,艺术家就会被观众负面看待:

import java.util.Random;
public class Theater {
    private Artist artist;
    private Random random = new Random();

    public Theater(Artist artist) {
        this.artist = artist;
    }
    public void perform() {
        if (random.nextBoolean())
            artist.complement();
    }
    public boolean judge() {
        int ego = artist.getEgo();
        if (ego > 10)
            return false;
        return (ego - random.nextInt(15) > 0);
    }
}

ArtistSet简单来说就是一个Artist and a Set:

/** A set of associated artists, e.g: a band. */
interface ArtistSet extends Set, Artist {
}

TheaterManager主持节目。如果剧院的观众对艺术家有负面评价,剧院会与人力资源部门沟通,人力资源部门将解雇艺术家、雇用新艺术家等:

class TheaterManager {
    private Theater theater;
    private HRDepartment hr;

    public TheaterManager(ArtistSet artists) {
        this.theater = new Theater(artists);
        this.hr = new HRDepartment(artists);
    }

    public void runShow() {
        theater.perform();
        if (!theater.judge()) {
            hr.doHiringAndLayingoffProcess();
        }
    }
}

一旦你尝试实施一个ArtistSet:两个超级接口都指定complement应该做其他事情,所以你必须实现两个complement不知何故,在同一个类中具有相同签名的方法。Artist.complement是一个同形异义词Set.complement.


新想法,有点乱……

public class MyArtistSet implements ArtistSet {

    public void complement() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

        // the last element in stackTraceElements is the least recent method invocation
        // so we want the one near the top, probably index 1, but you might have to play
        // with it to figure it out: could do something like this

        boolean callCameFromHR = false;
        boolean callCameFromTheatre = false;

        for(int i = 0; i < 3; i++) {
           if(stackTraceElements[i].getClassName().contains("Theatre")) {
               callCameFromTheatre = true;
           }
           if(stackTraceElements[i].getClassName().contains("HRDepartment")) {
               callCameFromHR = true;
           }
        }

        if(callCameFromHR && callCameFromTheatre) {
            // problem
        }
        else if(callCameFromHR) {
            // respond one way
        }
        else if(callCameFromTheatre) {
            // respond another way
        }
        else {
            // it didn't come from either
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Java中实现具有单应性方法的接口? 的相关文章

  • 如何将 .cer 证书导入 java 密钥库?

    在开发 Java Web 服务客户端期间 我遇到了一个问题 Web 服务的身份验证使用客户端证书 用户名和密码 我从网络服务背后的公司收到的客户端证书位于 cer格式 当我使用文本编辑器检查该文件时 它具有以下内容 BEGIN CERTIF
  • 哪个类调用了我的静态方法?

    假设我有一个带有静态方法的 Java 类 如下所示 class A static void foo Which class invoked me 进一步假设 A 类有任意数量的子类 class B extends A class C ext
  • Eclipse 自动完成更改变量名称

    只是一个愚蠢的问题 但很难搜索 因为有很多关于 Eclipse 自动完成的主题 而且很难找到与我的问题匹配的内容 所以问题是 如果我写 MyClass MyVarName 然后按空格键 添加 new MyClass Eclipse 自动添加
  • 我们如何测试我们的 Java UI?

    我们正在寻找记录和回放类型的测试工具来自动化我们的一些 UI 功能测试 我们已经研究了从 Silke 到 QTP 的大多数常见嫌疑 但没有一个起作用 当需要右键单击才能从右键单击菜单中选择某些内容时 或者当您必须在网格的下拉列表中选择一个值
  • 将 JSON Map 传递到 Spring MVC 控制器

    我正在尝试将 Map 的 JSON 表示形式作为 POST 参数发送到我的控制器中 RequestMapping value search do method RequestMethod GET consumes application j
  • 在 Java 中填充布尔数组

    作为一名相当新手的 Java 程序员 我给自己设定了一个艰巨的挑战 尝试编写一个简单的文本冒险 不出所料 我已经遇到了困难 我试图为我的 Location 类提供一个属性来存储它包含的退出 我为此使用了一个布尔数组 本质上保存代表每个出口的
  • 获取TextView的高度

    我有一些文字将被放入TextView 我这样做是使用setText 现在我需要找到文本在文本中占据的行数或高度TextView 我尝试使用getHeight 但它总是返回 0 无论如何 有没有办法获得文本中存在的文本的高度TextView
  • 将多个视频文件合并到一个文件中

    我有多个以相同帧速率和分辨率录制的视频 我想将两个视频合并为一个视频 因此结果文件将是大视频 我正在使用 MP4 解析器 api 并使用下面的代码 Movie countVideo new MovieCreator build Channe
  • 将 EditText 聚焦在设备上运行的 PopupWindow 中时出现异常

    我正在为 Android 开发一个弹出窗口 它正在工作 我在上面添加了一个 EditText 和一个按钮 当在 ADV 上运行时 它可以正常工作 而在设备上运行时 当我专注于 EditText 时 这会抛出一个奇怪的异常 android v
  • perl 和 java 正则表达式功能之间有什么区别?

    perl 和 java 在支持哪些正则表达式术语方面有什么区别 这个问题仅涉及正则表达式 并且特别排除了how可以使用正则表达式 即使用正则表达式的可用函数 方法 以及语言之间的语法差异 例如java要求转义反斜杠等 特别令人感兴趣的是 j
  • 我们必须将 .class 文件放在 Tomcat 目录中的位置

    我必须把我的 class文件在 Tomcat 目录中 在我的 Java Complete Reference 书中 他们告诉将其放入C Program Files Apache Tomcat 4 0 webapps examples WEB
  • Java 7 中 Object 和 int 的比较

    最近我偶然发现了一个问题 让我停下来思考 对我来说 下面的代码应该总是会触发错误 但是当我的一位同事问我为什么 Eclipse 没有显示错误时 我无法回答任何问题 class A public static void main String
  • 在 Java 中使用 Inflater 解压缩 gzip 数据

    我正在尝试使用以下方法解压缩 gzip 数据Inflater 根据文档 如果参数 nowrap 为 true 则 ZLIB 标头和校验和 字段将不会被使用 这提供了与 GZIP 和 PKZIP 使用的压缩格式 注意 使用 nowrap 选项
  • Akka 和 spring 配置

    我正在尝试将 akka 与 spring 结合起来 但没有成功 基本上 我的应用程序似乎不习惯读取 akka 模式 具有架构的 service context xml 的一部分
  • 在Spring-Boot中,我们如何在同一个项目中连接两个数据库(Mysql数据库和MongoDB)?

    我正在尝试创建一个 Spring Boot 项目 其中我有一个要求 我想连接到不同的数据库 MySql 和 MongoDB 我是否需要做一些特殊的事情来连接到这两个数据库 或者 spring boot 会自动计算出自己连接到这两个数据库 我
  • 设置 JAVA_HOME 变量时出现问题

    所以我刚刚下载了 Android Studio 并尝试设置 JAVA HOME 变量以便我可以运行它 我使用的是 Windows 8 并按照我找到的所有说明进行操作 但无济于事 转到高级系统设置 gt 环境变量 然后使用包含我的 jre7
  • 如何告诉 IntelliJ 使用 Java 1.6 JDK 启动 gradle?

    一个简单的问题 即使经过几个小时的尝试和搜索 我也无法弄清楚 我安装了 Java 6 和 7 如何告诉 IntelliJ 使用 JDK 版本 1 6 启动 Gradle 构建 无论我做什么 IntelliJ 都会以以下方式开始我的 grad
  • Java 相当于 Python 的 urllib.urlencode(基于 HashMap 的 UrlEncode)

    From https stackoverflow com questions 2018026 should i use urllib or urllib2 2018103 2018103 Java 中 Python 的 urllib url
  • 如何隐藏或删除 Android HoneyComb 中的状态栏?

    如何隐藏或删除 Android HoneyComb 中的状态栏 每次运行应用程序时 我都会发现某些内容必须被状态栏覆盖 我尝试改变AndroidManifest xml 但没有任何改变 你不知道 它被认为是永久的屏幕装饰 就像电容式主页 菜
  • 使用 Hibernate 防止无限循环数据检索

    我想知道 想象一个场景 例如 POJO public class User private String userName private String name private String surname private List

随机推荐

  • 如何在flutter中创建工具栏搜索视图

    我需要实施searchview在工具栏中我的应用程序用于过滤列表视图 在 aziza回答的帮助下 我用下面的列表过滤器编写了搜索视图的详细代码片段 这对其他人有帮助 import package flutter material dart
  • SQL SERVER MANAGEMENT STUDIO:突出显示变量

    SQL SERVER MANAGEMENT STUDIO 中有没有一种方法可以在我们单击变量名称时突出显示变量的所有用法 它可能不适用于所有情况 但我发现使用F2按钮 在我的机器上映射到 View EditLabel 它使我能够突出显示所有
  • range::sort 无法编译

    在 MyRect h 中 struct MyRect MyRect std initializer list
  • Fluentd 发送到 Splunk HEC:想要将源类型设置为命名空间

    是否可以以编程方式将源类型设置为生成日志的名称空间 我正在使用 fluidd 插件将数据发送到 Splunk http 事件收集器 在其他地方 建议使用 record kubernetes namespace name 将索引名称设置为命名
  • 函数的隐式声明在 C99 中无效

    我是 C 语言新手 我遇到了一个我真的不明白的问题 我试图从另一个函数获取一个数组 但是当我尝试提取信息时 它给了我以下警告 函数 getk vector calculation 的隐式声明在 C99 中无效 数组初始值设定项必须是初始值设
  • 使用访问权限填充多对多表

    我有两张桌子 persons and projects 位于多对多表中 因此通过第三个表链接在一起persons projects 在 ms access 中 我现在创建了一个表单 显示来自projects table 我想要的是有一个显示
  • 如何使用 openXML 深度克隆 .xlsx 文件中的行?

    我有 template xlsx 文件 必须通过在特定索引中添加一行的几个副本来修改该文件 当我尝试使用克隆方法进行此操作时 我添加了一行 但每行都互相修改 我需要创建 opemxml 行对象的深度克隆 但是当我尝试此操作时 出现 open
  • 具有多个选项的 jQuery 日期选择器

    我想得到datepicker显示我发送的日期名称 但它仍然使用默认值 有什么东西应该关闭吗 我应该使用单个选项语句设置值吗 我在 Firebug 中没有收到任何错误 这是我的代码 datepicker dateFormat dd mm yy
  • 在 C# 中旋转色调

    我正在寻找复制发现的 CSS3 色调旋转行为here http css3 bradshawenterprises com filters 原始图像 色调旋转 180 度的图像 我已经可以准确地将 RGB 值转换为 HSL 值 然后再转换回来
  • 为什么即使我设置了随机种子,我也无法在 Keras 中获得可重现的结果?

    我正在 Mac OSX 上使用 Keras 在虚拟数据上训练 MobileNet 架构 我都设置了nump random and tensorflow set random seed 但由于某些原因 我无法获得可重现的结果 每次重新运行代码
  • 您知道 NTSC 解码器 API 吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 API 可以用来解码模拟信号的数字样本 根据 http en wikipedia org
  • if fi [: 参数太多

    这个脚本有什么问题吗 if grep q
  • 如何更改LocationRequest的间隔

    我将应用程序设置为每 5 秒获取一次位置通知 mLocationRequest LocationRequest create mLocationRequest setPriority LocationRequest PRIORITY HIG
  • 如何跟踪点击时正确的标注附件视图的位置

    正如您在下面看到的 我有一个带有右键的注释视图 当用户点击右侧按钮时 我将呈现一个弹出窗口 问题是我不知道用户点击的位置 因此我没有 X 和 Y 来相应地显示弹出窗口 如何找出用户点击的位置 即 X 和 Y HotelAnnotationV
  • 如何快速检查一个对象是否是动态类类型?

    我正在实现一个名为的函数ofType它过滤掉给定类型的所有元素 这是我的代码 class Animal class Mammal Animal class Monkey Mammal class Pig Mammal class Human
  • 如何调试 Firefox 扩展,它似乎无声地崩溃

    我不知道如何调试我的简单扩展 脚本 内容脚本 加载 因为第一个 console log 调用显示在选项卡的控制台中 但随后什么也没有 没有任何错误 也没有第二次 console log 调用 我的问题不是关于解决我的代码问题 肯定有一个 如
  • Matplotlib/Pandas 中条形图的优化

    代码 df pd DataFrame 770 215 179 107 83 82 70 60 57 54 52 index A B C D E F G H I J K ax df plot kind bar stacked False al
  • java 解组 LocalDateTime

    这是我的适配器类 public class LocalDateTimeAdapter extends XmlAdapter
  • 在同一 lambda 函数中从不同帐户访问两个表

    是否可以在一个 lambda 函数中访问两个表 其中一个表与 lambda 函数位于同一帐户中 另一个表位于另一个帐户中 我看过有关的文章跨账户访问委托 https docs aws amazon com IAM latest UserGu
  • 如何在Java中实现具有单应性方法的接口?

    在英语中 同形异义词对是具有相同拼写但不同含义的两个单词 在软件工程中 一对单应性方法是名称相同但要求不同的两种方法 让我们看一个人为的示例 以使问题尽可能清楚 interface I1 return 1 int f interface I