在Java中重写抽象泛型方法 [英] Overriding abstract generic method in Java
问题描述
我正在为我当前项目基础的更好部分进行基因化,并且我有一个想法,即我决定测试覆盖抽象方法。这里是我在Java中的测试类:
public abstract class Base {
public abstract< T扩展Base> T test();
第一次执行:
public class Inheritance extends Base {
@Override
public继承者test(){
return null;
}
}
第二次执行:
public class Inheritor2 extends Base {
@Override
public< T extends Base> T test(){
return null;
}
}
问题1
为什么要编译?我承认我有很高的期望,这是合法的,因为它使得合同不仅确保它返回了一些扩展Base的东西,而且已经更加专业化了(所以我不需要在以后的某个地方把结果投给我的专门类)。
所有的声音都很好,但是我真的完成了基类迫使我进入的契约吗?我在继承者
中的重写实现失去了某种通用性层次吗?我在 Inheritor
中实现此方法并不会返回 Inheritor2
的实例,抽象方法似乎(作为扩展 Base
)。
我想指向文档的一些摘录。我的猜测是它与类型删除有关,如果有人提到它在他/她的答案中的准确性,那将会很好。
问题2
这个程序是否有一个正式名称,而不是我在标题中所说的名称?
问题3
同事的划伤测试似乎在编译时失败。那么在通用抽象方法覆盖的方法中是否有所不同?
以下是技术细节。
关于覆盖:
实例方法
mC $在
中声明或继承的c $ c>,从C C
另一个方法<$ c覆盖
$ c> mA 在类A
中声明,如果以下所有
都为真:
A 是
C
的超类。
C
不会继承mA
。
mC
的签名是mA
的签名的子签名(第8.4.2节)。
- 以下其中一项为真:
mA
为public
。
- [...]
b
在你的情况下, 方法m1的签名是 和 是一个子签名。 退货类型如何? 如果方法声明 在 如果R1是一个引用类型,则下列条件之一成立: 所以要回答你的问题: 未经检查的转换的危险性可让您执行 然后 这会在运行时导致 Problem outline I'm generifying the better part of my current project's base and I had an idea that I decided to test regarding overriding an abstract method. Here are my test classes in Java: First implementation: Second implementation: Question 1 Why does it compile? I admit I had high hopes it would be legal, since it makes the contract not only ensure it returns something that does extend Base, but is more specialized already (so that I don't need to cast the result to my specialized class somewhere later). All sounds nice but do I really fulfill the contract that the base class forces me into? My overriden implementation in I would like pointing to some excerpt from documentation. My guess is it has something to do with type erasure, would be nice if someone mentioned it's accuracy in his/her answer. Question 2 Does this procedure have a formal name other than one I stated in the title? Question 3 Is this possible in C#? Colleague's scratch test seemed to fail on compilation. Is there then a difference in approach to generic abstract method overriding? Here are the technicalities. Concerning overriding: An instance method In your case, The signature of a method m1 is a subsignature of the signature of a
method m2 if either:
- m2 has the same signature as m1, or
- the signature of m1 is the same as the erasure (§4.6) of the signature of m2. The erasure of and is a subsignature. What about the return type? If a method declaration Following the If R1 is a reference type then one of the following is true: So to answer your questions:
The dangers of unchecked conversion would allow you to do and then which would cause a 这篇关于在Java中重写抽象泛型方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! A
是 Base
和 C 是
继承者
, Base#test()
is mA
和继承者#test()
是 mC
。
mC
是 mA的子签名
因为
方法m2的签名的子签名,如果:
- m2具有相同的签名作为m1或
- m1的签名与m2的签名的删除(§4.6)相同。
mA
的删除是
public abstract base test()
mC
public继承者test()
d1
返回类型 R1
覆盖或隐藏另一个方法 d2
的返回类型 R2 $ c>的
声明$ c>,那么 d1
必须是
return-type-substitutable(§8.4.5) for d2
或发生编译时错误
。
return-type-substitutable
,我们看到
R1
转换为 R2的子类型
通过未经检查的转换(§5.1.9)。
继承者 code>是一个子类型
T通过未经检查的转换扩展了Base
,所以我们都很好(尽管你应该从你的编译器得到一个警告)。
class继承者extends Base {
@Override
public继承者test(){
return new Inheritor();
$ / code $ / pre
Base ref = new Inheritor();
Inheritor2 wrong = ref。< Inheritor2> test();
ClassCastException
。使用它需要您自担风险。 public abstract class Base {
public abstract <T extends Base> T test();
}
public class Inheritor extends Base {
@Override
public Inheritor test() {
return null;
}
}
public class Inheritor2 extends Base {
@Override
public <T extends Base> T test() {
return null;
}
}
Inheritor
loses certain layer of genericness doesn't it? My implementation of this method in Inheritor
doesn't ever return an instance of Inheritor2
, possibility of which the abstract method seemed to enforce (as both extend Base
).
mC
declared in or inherited by class C
, overrides
from C
another method mA
declared in class A
, iff all of the following
are true:
A
is a superclass of C
.C
does not inherit mA
.mC
is a subsignature (§8.4.2) of the signature of mA
.
mA
is public
.A
is Base
and C
is Inheritor
, Base#test()
is mA
and Inheritor#test()
is mC
. mC
is a subsignature of mA
because
mA
is public abstract Base test()
mC
public Inheritor test()
d1
with return type R1
overrides or hides the
declaration of another method d2
with return type R2
, then d1
must be
return-type-substitutable (§8.4.5) for d2
, or a compile-time error
occurs.return-type-substitutable
, we see
R1
can be converted to a subtype of R2
by unchecked conversion (§5.1.9).Inheritor
is a subtype of T extends Base
through unchecked conversion, so we're all good (though you should have gotten a warning from your compiler).
class Inheritor extends Base {
@Override
public Inheritor test() {
return new Inheritor();
}
}
Base ref = new Inheritor();
Inheritor2 wrong = ref.<Inheritor2>test();
ClassCastException
at runtime. Use it at your own risk.