Rockarolla
Rockarolla

Reputation: 99

Define abstract methods with generics

I've been reading a lot on generics but I still have some basic problems implementing a simple hierarchy in Java. The goal is to define an abstract method that will compare two objects of the same class, if the objects are from different classes it should return false. Example:

We define the abstract class Sound

abstract class Sound{
    public boolean check(Sound d){return false;};
}

Some classes that extend Sound and another abstract class that extends from it, like Alarm

abstract class Alarm extends Sound{
    @Override
    public boolean check(Alarm d){//Do something and return boolean};
}

With some more classes that extend from it.

Simple solution would be to define the method as its shown and it will work, BUT I feel there's a better way to enforce the hierarchy so the Sound class defines that the method should be used only with a parameter that is of the same class.

What I've tried with Generics:

abstract class Sound{
    public <T extends Sound> boolean check(T d){return false;};
}

abstract class Alarm extends Sound{
    @Override
    public <T extends Alarm> boolean check(T d){//Do something and return boolean};
}

or

abstract class Alarm extends Sound{
    @Override
    public boolean check(Alarm d){//check and return boolean};
}

Java complains because to the compiler I'm not overriding the check method in Alarm. Any clue on what could be missing?

Upvotes: 3

Views: 4595

Answers (3)

NPE
NPE

Reputation: 500357

How about something like:

interface ISound<T> {
    public boolean check(T d);
}

abstract class Alarm implements ISound<Alarm> {
    @Override
    public boolean check(Alarm d) { return true; };
}

(I hope I understood your question correctly!)

Upvotes: 0

Pradeep Simha
Pradeep Simha

Reputation: 18123

You are not extending any class!!

abstract class Alarm extends Sound {
}

This is the correct way...

Upvotes: -1

SLaks
SLaks

Reputation: 887453

Your idea is inherently wrong.
The point of a generic method is that the caller can specify any type that meets the constraints.
In other words, the caller can write

sound.<NonAlarm> check(...);

Where NonAlarm is any class that inherits Sound.

Since Alarm inherits Sound, its check() method must have the same constraint.

Instead, you can use the CRTP:

public abstract class Sound<T extends Sound<T>> {
    public abstract boolean check(T d);
}

public class Alarm extends Sound<Alarm> {
    @Override
    public boolean check(Alarm d) { ... }
}

Upvotes: 6

Related Questions