泛型和继承问题 [英] generics and inheritance question

查看:112
本文介绍了泛型和继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个类:

  public abstract class fileHandler< Key extends Object,Value extends Object> {
}

public A扩展fileHandler< String,String []> {
}

public B扩展fileHandler< String,String> {
}

现在我的主要功能是做这样的事情:

  fileHandler file = null; 
如果(< condition>){
fileHandler = new A();
} else
fileHandler = new B():
}

但是,这会导致2个编译时错误:


  1. 无法将A转换为fileHandler
  2. 无法转换B到fileHandler

如果基类不是泛型的,我不会得到这个错误,我该如何摆脱这些错误。 p>

更新:



我的类层次结构是:


  1. class fileHandler< Key,Value> {}

  2. class A extends fileHandler< String,String []> {}

  3. class B扩展fileHandler< String,String> {}

  4. 调用函数 gen(A的对象)
  5. 的类C b $ b
  6. 调用函数 gen(B的对象)的D类。

  7. C和D都是从抽象类E派生的。

现在我该如何定义这些函数在C和D和E:

我给了以下内容:

E:



  public abstract void gen(fileHandler A)throws exception; 



C:



  void gen(fileHandler A)抛出异常; 



D:



  void gen(fileHandler A)抛出异常; 



C,D和E给出错误fileHandler是原始类型。

解决方案

在使用不同类型参数实例化泛型时,这两个实例不是类型兼容的。泛型类型的不同实例不是类型等价的,即从另一个类继承的类与该类相当的类型,即使类型实参本身可能通过继承关联。通用性和多态性是两种独立的语言特性。



您的代码等同于以下内容:

  // Java默认未指定Object的类型参数。 
fileHandler< Object,Object>文件;

if(...){
//错误:fileHandler< String,String>不等于fileHandler< Object,Object>
file = new fileHandler< String,String>();
} else {
//错误:fileHandler< String,String []>不等于fileHandler< Object,Object>
file = new fileHandler< String,String []>();





$ b

如果你真的想要分离一个独立于所使用类型的多态接口要实例化你的fileHandler类,那么我建议你使用一个接口:

 接口IFileHandler 
{
//如果这个接口需要谈论关键和值,那
//只使用java.lang.Object。
}

public class fileHandler< Key extends Object,Value extends Object>
实现了IFileHandler
{
// ...
}

public class A extends fileHandler< String,String>
{
// ...
}

公共类B扩展fileHandler< String,String []>
{
// ...
}

IFileHandler文件;

if(...){
file = new A();
} else {
file = new B();
}


I have three classes:

public abstract class fileHandler<Key extends Object, Value extends Object> {
}    

public A extends fileHandler<String, String[]> {
}

public B extends fileHandler<String, String> {
}

Now in my main function i do something like this:

fileHandler file= null;
If (<condition>) {
    fileHandler = new A();
} else
    fileHandler = new B():
}

But this gives 2 compile time errors:

  1. Cannot convert A to fileHandler
  2. Cannot convert B to fileHandler

How can I get rid of these errors as I don't get this error if base class is not generic.

Update:

My class hierarchy is:

  1. class fileHandler<Key, Value> { }
  2. class A extends fileHandler<String, String[]> { }
  3. class B extends fileHandler<String, String> { }
  4. class C that calls function gen(object of A) or
  5. class D that calls function gen(object of B).
  6. both C and D are derived from abstract class E.

Now how should I define these functions in C and D and E:

I gave the following:

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, and E give error fileHandler is raw type. Reference to generic type fileHandler(Key, Value) should be parameterized.

解决方案

When you instantiate a generic type with different type arguments, the two instantiations are not type compatible. Different instantiations of a generic type are not type-equivalent in the way that a class that inherits from another class is type-equivalent to that class, even when the type arguments themselves may be related by inheritance. Genericity and polymorphism are two separate language features.

Your code is equivalent to the following:

// Java defaults unspecified type arguments to Object.
fileHandler<Object, Object> file;

if (...) {
   // Error: fileHandler<String, String> is not equivalent to fileHandler<Object, Object>
   file = new fileHandler<String, String>();
} else {
   // Error: fileHandler<String, String[]> is not equivalent to fileHandler<Object, Object>
   file = new fileHandler<String, String[]>();
}

If you truly want to isolate a polymorphic interface that is independent of the types used to instantiate your fileHandler class, then I would suggest you use an interface:

interface IFileHandler
{
    // If this interface needs to talk about keys and values, it
    // does so using only java.lang.Object.
}

public class fileHandler<Key extends Object, Value extends Object>
    implements IFileHandler
{
    // ...
}

public class A extends fileHandler<String, String>
{
    // ...
}

public class B extends fileHandler<String, String[]>
{
    // ...
}

IFileHandler file;

if (...) {
    file = new A();
} else {
    file = new B();
}

这篇关于泛型和继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆