当前位置: 首页 > 知识库问答 >
问题:

通过泛型方法覆盖非泛型方法

韶和璧
2023-03-14

我想在我的android项目中自动转换视图。所以,我想重写

View findViewById(int id) {...}

方法

<T extends View> findViewById(int id) {...}

方法但是java编译不允许这样做,但是重写的方法不会与父方法冲突,并且总是返回视图对象或其子对象。我发现了一些信息,java不允许用泛型方法重写非泛型方法,但我找不到解释。

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ824这个FAQ说这是不可能的,但我不明白为什么。例如,我们有这样的课程:

class Super { 
  public void set( Object arg) { ... } 
  public Object get() { ... } 
} 
class Sub extends Super {  
  public <S extends Number> void set( S arg) { ... } // overloads 
  public <S extends Number> S get() { ... } // overloads 
}

常见问题解答说他们应该使用重载进行编译,但我有一件奇怪的事情:getter返回与findviewbyd相同的错误,但是setter编译时没有错误。

有人能给我解释一下这件事吗?为什么java不允许通过泛型覆盖非泛型,为什么setter被编译,getter-no?

我知道,我可以用另一种方法,例如

<T extends View> findView(int id){
  return (T) findViewById(id);
}

<T extends View> findView(int id, Class<T> clazz) {
  return clazz.cast(findViewById(id));
}

但是我想明白了,为什么我要使用新的方法,而不是凌驾于?

//1
@Override
public View findViewById(int id) {
    return (View) super.findViewById(id);
}
//2
@Override
public <T extends View> T findViewById(int id) {
    return (T) super.findViewById(id);
}

那么,在编译期间,1和2之间的区别是什么?甚至方法1也比方法2更一般。

//3
@Override
public <T extends View> View findViewById(int id) {
    return (View) super.findViewById(id);
}

在我添加了如上所述的方法之后,我终于意识到,“T扩展视图”告诉编译器,它与没有“T扩展视图”的方法不同。所以,事实上,我创建了另一个新方法,但具有相同的名称和参数,因此无法编译。也许这并不完全正确,但正如我所理解的,这与事实类似。

谢谢你们所有试图帮助我的人。

共有1个答案

督坚白
2023-03-14

Sub中的set方法会编译,因为您正在声明一个名为set的新方法,该方法可以接受扩展Number的任何参数S.请注意,您没有重写子类中Super类的set方法,您已经重载了set方法
withgetmethod,您正在执行完全相同的操作,即重载get方法,但这次编译器会抱怨,因为它无效,因为您只更改了方法的返回类型。对于例如。

public Object get() {
    return null;
}

您可以在同一个类或子类中声明另一个方法,方法的返回类型如下所示

    public Number get() {
        return null;
    }

然后编译器会抱怨“methodget()已经定义”,因为在java中,返回类型不是方法签名的一部分
如果声明,则可以为set方法复制相同的问题

public <S extends Number> void set( Object arg) {  }

在这种情况下,我们只需更改方法的返回类型,但要成为有效的重载方法,那么方法参数应该不同

public <S extends Number> void set( String arg) {  } // overloads

将是有效的过载

 类似资料:
  • 我在覆盖接口中声明的方法时遇到了一些问题,该方法使用泛型参数作为其异常,并使用泛型作为其参数之一。为了说明,我编写了以下代码接口 通过javac运行,我得到 请注意,在接口中,metodoA和metodoB之间的唯一区别在于它们的参数。 为什么Implementadora(Implementadora)的metodoB(metodoB)(代码)不重写Interfaz(代码),但重写metodoB(

  • 我定义了一个通用的环境特征: 为此,我提供了以下实现: 此外,我定义了一个通用事件特征,该特征具有一个接受通用环境作为参数的方法: 对于这个事件特征,我提供了以下实现,其中exec()方法接受MyEnvironment类型的参数,使我能够访问MyEnvironment的特定值。 然而,Scala编译器输出了一个错误,从中可以看出MyEnvironment似乎没有被识别为环境[整数]: 错误:方法e

  • 编译时,此代码将产生以下+错误: 问题是访问中的类型T与列表中的T不相同。如何修复此编译问题?

  • 我想说得具体一点。我有一个名为Result的类和一个名为Result的派生类 这些类在方法中用作返回类型。为此,我创建了这个helper类: 正如您所看到的,上面的代码对于成功有两种返回类型,一种是如果您不想返回任何东西,另一种是如果您想返回一些东西,但是失败的结果永远不会返回什么东西。这是不必要的,只是一个错误消息。这使我想到以下问题:当我想创建一个可以使用返回类型返回Success,而不使用返

  • 我正在尝试理解使用以下代码得到的名称冲突错误: 错误消息: 错误:名称冲突:

  • 问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符