Generics: Inheriting from an abstract class that implements an interface - java

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?

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

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

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

public abstract class AbstractEntry<T extends AbstractEntryBean> implements SingleRecordInterface<T> {
}
public class SpecificEntry extends AbstractEntry<SpecificEntryBean> {
public void insert(SpecificEntryBean entry) {
// stuff
}
}

Related

Disabling derived classes from overriding interface method

public interface Interface {
void interfaceMethod();
}
abstract class Base implements Interface {
#Override
public void interfaceMethod() {
baseClassMethod();
abstractMethod();
}
private void baseClassMethod() {
System.out.println("Base implementation");
}
protected abstract void abstractMethod();
}
class Derived extends Base {
#Override
protected void abstractMethod() {
System.out.println("Derived implementation");
}
#Override
public void interfaceMethod() {
System.out.println("I still can change this");
}
}
Having this layout, I want Base class to implement method from interface, but some of this implementation still depends on derived classes.
I see no other way than make Base class not implement that interface and make derived to do so and reuse base class method in their implementation.
Is there any other way to protect derived classes from overriding interface method, which is implemented in Base class?
Just make it final:
#Override
public final void interfaceMethod() {
baseClassMethod();
abstractMethod();
}
So you cant override it again from your Derived class.

Avoid raw type warnings with a factory that returns a generic object implementing a strategy pattern

My goal is to have an abstract Game class, whose constructor accepts a GameEngine that is suitable for derived Game classes. This abstract Game class will implement generic methods that are suitable for all Game implementations. You can think of the GameEngine as fulfilling a strategy pattern, to which Game delegates methods.
Therefore, upon creating a Game with a GameFactory, I don't care what implementation of Game the factory returns. I just want to make sure that the Game implementation gets constructed with the appropriate GameEngine implementation. However, if I simply return the raw type Game from the factory, I of course get Raw use of parameterized class 'Game' warnings.
Furthermore, ideally, the GameFactory.createGame(settings) method should not have to pass a type, but simply infer the type based on some property of settings.
This is the gist of the code I have:
public abstract class GameEngine<T extends Game<T>> {
public void doSomethingAllEnginesUnderstand(T game);
}
public class LocalGameEngine
extends GameEngine<LocalGame> {
}
public class RemoteGameEngine
extends GameEngine<RemoteGame> {
}
public abstract class Game<T extends Game<T>> {
private final GameEngine<T> gameEngine;
protected Game(GameEngine<T> gameEngine) {
this.gameEngine = gameEngine;
}
protected abstract T getSelf();
public final void doSomethingAllEnginesUnderstand() {
gameEngine.doSomethingAllEnginesUnderstand(getSelf());
}
}
public class LocalGame
extends Game<LocalGame> {
public LocalGame(LocalGameEngine gameEngine) {
super(gameEngine);
}
#Override
protected LocalGame getSelf() {
return this;
}
}
public class RemoteGame
extends Game<RemoteGame> {
public RemoteGame(RemoteGameEngine gameEngine) {
super(gameEngine);
}
#Override
protected RemoteGame getSelf() {
return this;
}
}
public class GameFactory {
// returns raw type Game
public Game createGame(GameSettings settings) {
if(settings.totalPlayers() > 1) {
return new RemoteGame(new RemoteGameEngine());
}
else {
return new LocalGame(new LocalGameEngine());
}
}
}
Am I misusing/misunderstanding generics to reach my stated goal? Is it possible to not make Game a generics class, while still mandating that an appropriate GameEngine implementation is passed to the constructor?
I feel you overuse the generics and I find Game<T extends Game<T>> an overkill. I'd design it in this way:
Make LocalGame and RemoteGame extends Game (no generic type). Use polymorphysm when you #Override the getSelf method:
public class LocalGame extends Game {
public LocalGame(LocalGameEngine gameEngine) {
super(gameEngine);
}
#Override
protected LocalGame getSelf() {
return this;
}
}
public class RemoteGame extends Game {
public RemoteGame(RemoteGameEngine gameEngine) {
super(gameEngine);
}
#Override
protected RemoteGame getSelf() {
return this;
}
}
Make LocalGameEngine and RemoteGameEngine extends GameEngine (no generic type)
// actuyally, this abstract class can be an interface instead
public abstract class GameEngine {
public void doSomethingAllEnginesUnderstand(Game game) {}
}
public class LocalGameEngine extends GameEngine { }
public class RemoteGameEngine extends GameEngine { }
Make Game require any subclass of GameEngine, the generic part can be used in the constructor only, you don't need to make the whole Game generic (Game<T>).
public abstract static class Game {
private final GameEngine gameEngine;
protected <T extends GameEngine> Game(T gameEngine) {
this.gameEngine = gameEngine;
}
protected abstract Game getSelf();
public final void doSomethingAllEnginesUnderstand() {
gameEngine.doSomethingAllEnginesUnderstand(getSelf());
}
}
The whole GameFactory becomes simplified:
public Game createGame(GameSettings settings) {
if (settings.totalPlayers() > 1) {
return new RemoteGame(new RemoteGameEngine());
} else {
return new LocalGame(new LocalGameEngine());
}
}

How do I change the signature of a method I have overriden from my interface that I implemented onto the concrete class I'm using?

For example
//This is part of Comparable Interface:
public int compareTo(T other);//T being any class/type of parameter
//This is part of my own interface:
public void beeper(Object what);
//This is part of my own concrete class which implements both of the above interfaces
public int compareTo(Country other)//Java allows this...
{
//code stuffs....
}
public void beeper(String what)//This does not work...
{
//Code stuffs....
}
How would you make an abstract method that allows you to change the method signature like compareTo does?
Use parameterized type.
Parent interface :
public interface ParentClass<T>{
void beeper(T what);
}
Child class :
public class ChildClass implements ParentClass<String>{
public void beeper(String what){
// your impl
}
}
Comparable is using generics; you can, too:
public interface Beepable<T> {
void beeper(T what);
}
Your code would do this:
public class StringBeeper implements Beepable<String> {
public void beeper(String what) { // implement here }
}

What is the correct way to override method of interface from a child interface using generics?

I have those two interfaces:
public interface ApiResultCallback {
void onSuccess(RestApi.Success<?> successResult);
void onFailure(RestApi.Failure failureResult);
}
public interface GetHappyCowsCallback extends ApiResultCallback {
void onSuccess(RestApi.Success<List<HappyCow>> successResult);
}
Where Success and Failure are:
public static class Success<T> extends ApiResult {
public T data;
}
public static class Failure extends ApiResult {
public String message;
}
I get an error in GetCleverPointsCallback interface saying that
both methods have same erasure but neither overrides the other.
What does that mean? Shouldn't the method from GetHappyCowsCallback override the method of its parent?
What I'm trying to achieve here is some kind of mapping between callbacks and their data without having to implement long mapping functions or even worse, duplicating the Success class like this:
public static abstract class Success<T> extends ApiResult {
public T data;
}
public static class ListHappyCowSuccess extends Success<List<HappyCow>> {
}
void onSuccess(RestApi.Success<?> successResult);
And
void onSuccess(RestApi.Success<List<HappyCow>> successResult);
Do not have the same signature. So the second does not override the first
What you're trying to do can be achieved by making the interface generic:
public interface ApiResultCallback<T> {
void onSuccess(RestApi.Success<T> successResult);
void onFailure(RestApi.Failure failureResult);
}
public interface GetHappyCowsCallback extends ApiResultCallback<List<HappyCow>> {
}
In fact, you probably don't need the second interface at all. Such pseudo-typedefs are even considered an anti-pattern, because the new types cannot be exchanged with their equivalents.
If I have a method like this:
void myMethod(GetHappyCowsCallback callback);
I can not pass an ApiResultCallback<List<HappyCow>> to it.
In most cases interface overriding doesn't really make sense. Unless it involves default methods:
interface InterfaceA {
public void doSomething();
}
interface InterfaceB extends InterfaceA {
#Override
public default void doSomething() {...} // Provides a default implementation
}

determine whether a class's superclass implements a certain interface in java

Let me know if I am wrong but in my experience the instanceof call does not do what I need it to.
I have an abstract class that implements an interface and explicitly overwrites all methods in the interface. I have a subclass of this class. How can I tell if the subclass is an instanceof the interface?
public interface IAnimal {
public void eat();
}
public abstract class Dog implements IAnimal {
#Override
public void eat(){
//eat things
}
public abstract void bark();
}
public class Beagle extends Dog {
#Override
public void bark(){
//specific bark
}
}
So I have an instantiation of Beagle, how do i find out if it is an instance of IAnimal?
You can do a
IAnimal.class.isAssignableFrom(Beagle.class)
or
IAnimal.class.isAssignableFrom(someObjectInstance.getClass());
or even instance of works with interfaces
if (object instanceof IAnimal) { }

Categories

Resources