Matt
Matt

Reputation: 4775

Generics: Inheriting from an abstract class that implements an interface

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?

Upvotes: 29

Views: 79679

Answers (4)

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78589

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);
}

Upvotes: 2

synopia
synopia

Reputation: 2314

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

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

Upvotes: 2

Guillaume Polet
Guillaume Polet

Reputation: 47608

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
    }
}

Upvotes: 3

Alex
Alex

Reputation: 13941

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> {
}

Upvotes: 54

Related Questions