java - 我的“Runnable”实现无法解析已声明接口的对象上的方法
问题描述
我Runnable
在 Java 15 中有一个简单的实现。
package work.basil.example;
public class MonsterRunnable < Monster > implements Runnable
{
private final Monster monster;
// Constructor
public MonsterRunnable ( Monster monster )
{
this.monster = monster;
}
@Override
public void run ( )
{
this.monster.actOut(); // Compiler error: Cannot resolve method 'actOut' in 'Monster'
}
}
我的 IDE(IntelliJ 2020.3)中的编译器无法解析方法行上的actOut
方法。this.monster.actOut();
run
然而,该方法已在界面上明确定义,如下所示。
package work.basil.example;
public sealed interface Monster
permits Demon, Witch
{
String name ( ); // This getter method implemented implicitly by `record` in our concrete classes `Demon` & `Witch`.
public void actOut ( ); // Method is declared, yet cannot be resolved in `Runnable`.
}
我的小演示应用程序正在使用 Java 15 预览功能JEP 360: Sealed Classes (Preview)和JEP 384: Records (Second Preview)。但我不明白这可能是这里的麻烦来源。
我想上面应该是足够的问题代码。但我可以展示接口的这对实现,Demon
并且Witch
.
package work.basil.example;
public record Demon(String name) implements Monster
{
@Override
public void actOut ( )
{
System.out.println( "This monster " + this.getClass().getSimpleName() + " named " + this.name + " buys a soul." );
}
}
……和……</p>
package work.basil.example;
public record Witch(String name) implements Monster
{
@Override
public void actOut ( )
{
System.out.println( "This monster " + this.getClass().getSimpleName() + " named " + this.name + " casts a spell." );
}
}
最后,这里是该actOut
方法工作的演示——如果我this.monster.actOut();
在有问题的方法中删除行run
。
package work.basil.example;
/**
* Hello world!
*/
public class MonterMash
{
public static void main ( String[] args )
{
System.out.println( "Hello World!" );
MonterMash monterMash = new MonterMash();
monterMash.demo();
}
private void demo ( )
{
Monster monster = new Witch( "Rowena" );
System.out.println( "monster = " + monster );
monster.actOut();
}
}
运行时:
你好世界!
怪物=女巫[名字=罗维娜]
这个名叫罗伊娜的怪物女巫施展了一个咒语。
解决方案
签名public class MonsterRunnable < Monster > implements Runnable
引入了一个通用参数Monster
。MonsterRunnable
泛型参数使类.. 泛型。这意味着您可以使用任何类型的类。
例如,当您使用 a 时List<String>
,<String>
是参数,即元素的类型。List
本身被声明为public interface List<E> extends Collection<E>
. 请注意,这E
是通用参数;类型变量List<String>
使用该参数来引用String
s 列表。您还可以引用Integer
s:的列表List<Integer>
。您可以使用List
任何元素类型,因为它是通用的,因为它是通用的参数E
。E
用于“元素”并且是 Java 约定:请参阅类型参数命名约定。E
用于List
表示方法等。
因此,在您的示例中,泛型参数Monster
“隐藏”了 type Monster
,即您的类。引入的泛型类型Monster
没有方法actOut
,这是编译器告诉你的。
你想要的是monster
一种可以扩展的类型Monster
,简单的继承。因此,只需删除通用参数,您就会拥有所需的内容:
public class MonsterRunnable implements Runnable
您在评论部分的注释:
整个实验的实际目标是为 Runnable 实现声明一个泛型类型。
您需要表示泛型 inMonsterRunnable
是以下的实现Monster
:
package work.basil.example;
public class MonsterRunnable < T extends Monster > implements Runnable
{
private final T monster;
// Constructor
public MonsterRunnable ( T monster )
{
this.monster = monster;
}
@Override
public void run ( )
{
this.monster.actOut();
}
}
现在MonsterRunnable
是通用的 using T
,仅限于 extend (implement) Monster
。
推荐阅读
- java - 将 \t\n 显示为节点的原因是什么?
- python - 如何对 list.count() 的结果求和
- python - OverflowErro 无法将“int”放入索引大小的整数中
- django - 在 ElasticSearch/Django 中重建搜索索引时出错
- java - MyBatis 在一次查询中删除-插入-更新
- java - 如何在android中将字符串作为键盘输出发送?
- python - 矩阵乘法中的ValueError
- json - 如何获取多个 ARReferenceImages 名称以从 JSON 文件返回相同的数据?
- javascript - 内容安全策略与可变内联样式(CSP 与 CSS)
- c++ - C++ 标头单元导入语法