Generics: Inheriting from an abstract class that i

2019-02-04 09:13发布

问题:

I have the following interface:

public interface SingleRecordInterface<T> {
    public void insert(T object);
}

I have the abstract class below (that does not mention the method insert):

public abstract class AbstractEntry implements SingleRecordInterface<AbstractEntryBean> {
}

I have the concrete class:

public class SpecificEntry extends AbstractEntry {
    public void insert(SpecificEntryBean entry) {
        // stuff
    }
}

Finally, SpecificEntryBean is defined as:

public class SpecificEntryBean extends AbstractEntryBean {
}

I have the following error:

The type SpecificEntry must implement the inherited abstract method SingleRecordInterface.insert(AbstractEntryBean)

I don't understand the reason for this error, given that SpecificEntryBean extends AbstractEntryBean. How do I fix this error?

回答1:

You need to make your abstract class generic as well:

public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}

Then for your concrete class:

public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
}


回答2:

Change to the following:

public abstract class AbstractEntry<EB extends AbstractEntryBean> implements SingleRecordInterface<EB> {
}

and

public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
    public void insert(SpecificEntryBean entry) {
        // stuff
    }
}


回答3:

The problem is in your declaration of

public abstract class AbstractEntry implements SingleRecordInterface<AbstractEntryBean> {}

This is the place where you define what is type argument (AbstracEntryBean) for the type parameter T.

Therefore, T is AbstracEntryBean, and when you intend to override this method to finally implement it you are required to provide the exact method signature for the method. In this case:

@Override
public void insert(AbstractEntryBean object) {
    // TODO Auto-generated method stub
}

Since Java requires the exact same method signature to override a given method.

You can either provide a type parameter for your class, as others have suggested, or provide a bridge (overloading) method as follows:

//overloading
public void insert(SpecificBean object){
  insert((AbstractEntryBean) object);
}


回答4:

public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}

public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
    public void insert(SpecificEntryBean entry) {
        // stuff
    }
}