Reputation: 99
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
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
Reputation: 18123
You are not extending any class!!
abstract class Alarm extends Sound {
}
This is the correct way...
Upvotes: -1
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