简体   繁体   English

Java:覆盖通用方法

[英]Java: Override generic method

I'm trying to override a method in a child class which inherits an abstract method from the parent. 我试图覆盖子类中的方法,该子类从父类继承了抽象方法。 I'm trying to change the generic return type, but I'm a bit confused. 我正在尝试更改通用返回类型,但我有些困惑。

The base generic class: 基本的通用类:

public abstract class BaseAdapter<T extends IEvent> {
   private List<T> events;

   public BaseAdapter(List<T> events) {
      this.events = events;
   }

   public List<T> sort() {
      // Some sorting...
      return newFilteredEvents;
   }
}

The child class: 子班:

public class AdapterEvent extends BaseAdapter<Event> {
   public AdapterEvents(List<Event> events) {
      super(events);
   }
}

The implementation: 实现:

public abstract class BaseView extends View {

   private BaseAdapter<IEvent> events;

   @Override
   protected View onCreate(Context context) {
       View view = super.onCreate(context);

       this.events = getAdapter();

       return view;
   }

   /**
    * The child class should provide an adapter
    */
   protected abstract BaseAdapter<IEvent> getAdapter();
}

The child View class where I would like to override the parameterized method: 我想覆盖参数化方法的子View类:

public class EventView extends BaseView {

   @Override
   protected View onCreate(Context context) {
      return super.onCreate(context):
   }

   @Override
   protected BaseAdapter<IEvent> getAdapter() {
      List<Event> events = EventManager.getInstance().getEvents();

      return new AdapterEvent(events);
   }

}

This is where Eclipse is throwing an error message: 这是Eclipse抛出错误消息的地方:

Type mismatch: cannot convert from AdapterEvents to BaseAdapter<IEvent>

Note the class and the interface: Event and IEvent: 注意类和接口:Event和IEvent:

public interface IEvent {
   public void setId(long id);
   public long getId();

   public void setStartMillis(long start);
   public long getStartMillis();

   public void setEndMillis(long end);
   public long getEndMillis();
}

And the Model class which inherits from IEvent 还有从IEvent继承的Model类

public class Event implements IEvent {
   private long id;
   private long startTime, endTime;

   @Override
   public void setId(long id) {
      this.id = id;
   }

   @Override
   public long getId() {
      return this.id;
   }

   // The other inherited methods...
}

What I'm trying to achieve is to write much more abstract code, because these classes, interfaces will be extended by multiple classes (diferent View types in my case). 我要实现的目标是编写更多抽象的代码,因为这些类,接口将被多个类(在我的情况下为不同的View类型)扩展。 These are the abstract classes: BaseAdapter , BaseView , IEvent , and these are the implementations: AdapterEvent , EventView , Event . 这些是抽象类: BaseAdapterBaseViewIEvent ,以及以下实现: AdapterEventEventViewEvent

This because there is no covariance in type variables of generics in Java. 这是因为Java中泛型的类型变量没有协方差。

This means that you don't have polymorphism for a generic type if the type argument is polymorphic to the required one. 这意味着,如果类型参数对所需的类型多态,则您对通用类型没有多态性。 In practice List<Event> is not a subtype of List<IEvent> even though Event is-a IEvent . 在实践中List<Event>不是的子类型List<IEvent>即使Event 是-一个 IEvent

That's why Java provides wildcards : 这就是Java提供通配符的原因:

protected abstract BaseAdapter<? extends IEvent> getAdapter();

So that you can do: 这样您就可以:

protected BaseAdapter<? extends IEvent> getAdapter() {
  ..
  return new AdapterEvent(events);
}

Basically you are telling the compiler that getAdapter returns a BaseAdapter of an unspecified type which extends IEvent . 基本上你是在告诉编译器getAdapter返回BaseAdapter延伸不明类型的IEvent This allows what you need. 这可以满足您的需求。

Change BaseAdapter<IEvent> to BaseAdapter<? extends IEvent> BaseAdapter<IEvent>更改为BaseAdapter<? extends IEvent> BaseAdapter<? extends IEvent> on BaseView.events , and the two getAdapter() methods. BaseView.events和两个getAdapter()方法上BaseAdapter<? extends IEvent>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM