generics和inheritance问题
我有三节课:
public abstract class fileHandler { } public A extends fileHandler { } public B extends fileHandler { }
现在在我的主要function中我做这样的事情:
fileHandler file= null; If () { fileHandler = new A(); } else fileHandler = new B(): }
但这会产生2个编译时错误:
- 无法将A转换为fileHandler
- 无法将B转换为fileHandler
我如何摆脱这些错误,因为如果基类不是通用的,我不会得到这个错误。
更新:
我的class级层次结构是:
-
class fileHandler { }
-
class A extends fileHandler { }
-
class B extends fileHandler { }
- C类调用函数
gen(object of A)
或 - D类调用函数
gen(object of B)
。 - C和D都来自抽象类E.
现在我应该如何在C和D和E中定义这些函数:
我给出了以下内容:
E:
public abstract void gen (fileHandler A) throws exception;
C:
void gen (fileHandler A) throws exception;
d:
void gen (fileHandler A) throws exception;
C,D和E给出错误fileHandler是原始类型。 应参数化generics类型fileHandler(Key,Value)。
当您使用不同的类型参数实例化generics类型时,这两个实例不是类型兼容的。 generics类型的不同实例化不是类型等效的,因为从另一个类inheritance的类与该类等效,即使类型参数本身可能通过inheritance相关也是如此。 通用性和多态性是两种不同的语言特征。
您的代码等同于以下内容:
// Java defaults unspecified type arguments to Object. fileHandler
如果你真的想要隔离一个独立于用于实例化你的fileHandler类的类型的多态接口,那么我建议你使用一个接口:
interface IFileHandler { // If this interface needs to talk about keys and values, it // does so using only java.lang.Object. } public class fileHandler implements IFileHandler { // ... } public class A extends fileHandler { // ... } public class B extends fileHandler { // ... } IFileHandler file; if (...) { file = new A(); } else { file = new B(); }
我没有编译错误…如果我修复了您提供的代码中的所有错误
class fileHandler { } class A extends fileHandler { } class B extends fileHandler { }
然后
fileHandler file= null; if (/* condition */) { file = new A(); } else { file = new B(); }
问题是您正在尝试将实例分配给类名。 你应该说
if (condition) { file = new A(); } else { file = new B(); }
“file”是这里的引用“fileHandler”是类名。
干杯。
您如何决定修复此警告实际上取决于您要执行的操作以及您希望如何严格限制gen()
参数的允许类型。
例1
很松
abstract class E { public abstract void gen(fileHandler,?> A) throws Exception; } class C extends E { @Override public void gen(fileHandler,?> A) throws Exception {} }
例2
将Key
generic限制为String
abstract class E { public abstract void gen(fileHandler A) throws Exception; } class C extends E { @Override public void gen(fileHandler A) throws Exception {} }
例3
您可能想要命名不受限制的类型,以便您可以参考它。
abstract class E { public abstract void gen(fileHandler A) throws Exception; } class C extends E { @Override public void gen(fileHandler A) throws Exception {} }