接口(两种方法,根据类不同返回不同的类型)Java

7

任何继承接口的类都必须实现在接口中声明的方法。不确定是否可能,但我想做的是以下操作:

interface test {
   ____ get();
}

class A extends test {
  int val;

  A(int x) {
    val = x;
  }

  int get() {
    return Val;
  } 


  class B extends test {
  String val;

  B(String x) {
    val = x;
  }

  String get() {
    return Val;
  } 

是否可能有一个方法签名,能够返回两种不同的数据类型?


不是Java。但是例如Haskell具有此功能,即对返回类型进行重载。 - zegkljan
在Java中,签名是绝对的,必须按照声明完全遵循。 - crystalfrost
4个回答

25

虽然不是完全相同的情况,但您可以通过使用泛型类型参数来接近。

interface Test<T> {
    T get();
}

class A implements Test<Integer> {
    int val;

    A(int x) {
        val = x;
    }

    @Override
    public Integer get() {
        return val;
    }
}

class B implements Test<String> {
    String val;

    B(String x) {
        val = x;
    }

    @Override
    public String get() {
        return val;
    }
}

你可以看到,你必须使用Integer,因为泛型不支持原始数据类型。

同时注意,这两个版本的相同接口现在实质上是两个不同的接口。


1
不,这是不可能的。接口作为可用签名的“绑定联系人”。
如果您想要,可以使函数返回一个对象,并允许不同的实现返回不同类型的值,但是:
1. 必须是引用,而不是原始类型。 2. 在调用站点上失去了类型安全性。

1
请参考zapl的回答。 - Hovercraft Full Of Eels
@HovercraftFullOfEels - 我们都知道泛型,但那不再是同一个接口了,而且 zapi 在回答中也指出了这一点。正确的答案是没有办法使用单个接口来实现这一点。 - Amit
@Amit 从技术上讲,get() 可以只返回 Object,但对于新手来说,这可能不是一个好建议 :) - Ownaginatious
@Ownaginatious - 这个问题不是关于泛型的,我的回答也不是。 - Amit
从海报问题中所有的语法错误来看,他/她可能不知道泛型,而泛型可能更适合他们正在尝试解决的问题。我+1了你的答案,因为在编辑后,它是最技术上正确的,而且不是当前排名第一的答案的重复。 - Ownaginatious

0

你可以使用泛型来实现这个,但是它在运行时不被强制执行。你应该使用 implements 在类中实现一个接口,而不是使用 extends

interface Test<T> {
   T get();
}

class A implements Test<Integer> {
    int val;

    A(int x) {
        val = x;
    }

    @Override
    Integer get() {
       return Val;
    } 

}

class B implements Test<String> {
    String val;

    B(String x) {
       val = x;
    }

    @Override
    String get() {
        return Val;
    }
}

泛型只适用于类,因此您必须使用Integer而不是int作为返回类型。


0

这个可以编译,但我不确定我建议以这种方式做事情:

interface test {
   Object get();
}

class A implements test {
  int val;

  public A(int x) {
    val = x;
  }

  public Integer get() {
    return val;
  } 
}

class B implements test {
  String val;

  public B(String x) {
    val = x;
  }

  public String get() {
    return val;
  } 
}

在Java中,使用一个原方法返回类型的子类来覆盖一个方法是合法的。这被称为"协变性"。它只适用于返回类型,而不适用于参数。请注意,为了使其编译通过,我必须让类A中的get方法返回Integer而不是int。此外:在实现接口时,请使用implements而不是extends,并确保在引用变量时使用正确的大小写(在您发布的代码中,Val是无效的)。
正如我所说,我不确定我推荐这样做,因为在声明类型为test的任何代码中,get()的结果都是一个Object,你必须将其转换为其他东西才能使其有用。如果可能的话,应该使用泛型。然而,这并不总是可能的。在编写这样的接口之前,请仔细考虑您的设计。也许接口并不是您想要的。但是,如果没有更多关于您试图实现的详细信息,我无法判断。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接