【问题标题】:Implementing an interface with additional parameters in a method在方法中实现带有附加参数的接口
【发布时间】:2021-11-22 00:51:09
【问题描述】:

我有一个类MyClass 实现了接口IResp

public interface IResp {
    Response onResp(String a, String b)
            throws Throwable;
}
public class MyClass implements IResp {

    public onResp(String a, String b, String c) throws Throwable {
...
}

我需要MyClassonResp方法中的附加String c

现在,我知道我可以通过添加未实现的onResp(String a, String b) throws Throwable{...} 或将MyClass 设为抽象类来实现此目的。

由于我是 Java 新手,请问有什么更好的方法?

注意:我只能对类进行更改,不能创建或修改接口

【问题讨论】:

  • 为什么不对接口定义中的任意数量的字符串参数使用...?看看这个问题的答案stackoverflow.com/questions/3158730/…
  • 如果MyClass的用户只通过IResp调用它,那么他们将永远看不到带有三个参数的变体,他们只能调用IResp中定义的方法,即@ 987654334@,三参数方法是重载方法,不是同一种方法。

标签: java class interface overriding abstract-class


【解决方案1】:

你的意思是用一个空的身体来实现吗? 使用空主体实现该方法可能会产生问题。 假设有人出于某种原因在接口中创建了该方法。

假设一个函数获取接口作为参数。他们会调用哪种方法?两个参数版本一。

void someWork( IResp resp ) 
{
 resp.onResp("a","b");
}

现在,如果实际传递给 resp 的对象是一个 MyClass 并且该函数的实现为空,那么它什么也不做。这就是你想要的吗?

使类抽象比创建一个空的实现更好。这意味着下线的某个人将提供为两个参数版本进行发送的实现。

如果你在 MyClass 中实现了带有 sensible body 的二参数版本,并在 MyClass 中添加了三参数版本,但你不将它添加到接口中,那么 f1 等函数将无法使用它。

从中得出的结论是,您可能会在界面中需要两个版本的 onResp。

【讨论】:

  • 感谢您的意见@Gonen。是的,我问的是一个空的实现。但是,是的,当它什么都不做时,我绝对不想复杂化。虽然,我同意最好在接口中同时实现这两种实现,但遗憾的是我不能修改接口本身。因此我很担心。
  • @curiousCat 然后另一种选择是只使用 3 个参数版本创建另一个接口,而不是让 MyClass 实现这两个版本。您可以让新接口扩展旧接口,但随后您需要再次决定两个版本一的实现。
  • 我知道这将是一个更好的方法。对不起,我应该在前面提到这一点。但是,不幸的是,我只能对班级进行更改。我无法修改或创建新界面。
【解决方案2】:

如果你实现接口IResp,你必须实现带有两个参数的方法。但是您也可以定义带有 3 个参数的第二个方法。例如:

    public class MyClass implements IResp {

        public void onResp(String a, String b) throws Throwable {
            onResp(a, b, null);
        }


        public void onResp(String a, String b, String c) throws Throwable {
            // your logic
        }
    }

【讨论】:

  • 感谢您的意见@Wladimir。你的意思是,在用 2 个参数实现方法时,我需要返回 onResp(a, b, null);像这样?。 public onResp(String a, String b) throws Throwable { return onResp(a, b, null); }
  • 我的意思是,在这个实现中带有 2 个参数的 onResp 是简单的带有 3 个参数的 onResp,其中第三个参数为空。如果你没有 void 方法,你必须返回 onResp(a, b, null);
【解决方案3】:

如果您“实现”一个接口方法,并更改参数签名(如添加第三个字符串),则这不再是该接口的有效实现。你必须有一个像

这样的方法
public Response onResp(String a, String b) {
    // ...
}

在你的MyClass

我需要 MyClass 的 onResp 方法中的附加字符串 c

IResp 接口很可能存在,因为有onResp() 方法的调用者,它们将提供两个字符串,而不是三个。如果您的onResp() 代码在没有获得额外信息 (String c) 的情况下真的无法工作,那么您就有问题了。

你的提议都行不通(如果我理解正确的话):

  • 如果只添加一个空的onResp(String a, String b) 方法,那么该方法将从外部调用,什么也不做,然后返回。
  • 如果您将 MyClass 声明为抽象的,那么您将无法创建 MyClass 的实例,并且如果没有此类的实例,将永远不会调用任何内容。

一种(理论上的?)可能性是将接口方法更改为使用三个而不是两个参数,并修改接口的所有调用者以提供预期的信息作为第三个参数。但我猜界面是固定的,你不能随意这样做。

如果您可以在所有onResp() 调用中使用完全相同的c 值,则可以在创建MyClass 实例时提前提供额外的String c,而不是在每个onResp() 调用中提供,做new MyClass("abc"),假设“abc”是c的合适值。你的类应该是这样的:

public class MyClass implements IResp {
    private String myConstantC;
    public MyClass(String c) {
        this.myConstantC = c;
    }
    privateResponse onResp(String a, String b, String c) {
        // your code
    }
    @Override
    public Response onResp(String a, String b) {
        return onResp(a, b, myConstantC);
    }
}

如果您不能忍受单个常量 c 值,但有机会以某种方式找出给定 onResp(a, b) 调用所需的 c 值,您可以执行类似的操作

public class MyClass implements IResp {
    privateResponse onResp(String a, String b, String c) {
        // your code
    }
    private String findTheCValue(String a, String b) {
        // your way to find and return the correct c value
    }
    @Override
    public Response onResp(String a, String b) {
        String c = findTheCValue(a, b);
        return onResp(a, b, c);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多