How do I make my generic class only receive types that extend from class X or Y?
Example:
class MinhaClasseGenerica<T extends ClasseX ou ClasseY>
Sorry if it got a bit confusing, I'm a newbie yet, I can not explain very well.
How do I make my generic class only receive types that extend from class X or Y?
Example:
class MinhaClasseGenerica<T extends ClasseX ou ClasseY>
Sorry if it got a bit confusing, I'm a newbie yet, I can not explain very well.
This is not possible, nor does it make sense.
The reason is how MinhaClasseGenerica
would be used. In this class, T
could appear as a return type of a method, a parameter, or the type of a field.
Let's suppose it appears as the return of a method:
public T metodoQualquer() {
// ...
return algumObjeto;
}
And I want to use this method:
public void outroMetodo() {
T algumObjeto = metodoQualquer();
// Aqui invoca algum método sobre T.
}
What methods does T
have? The answer is that may have methods of X
and maybe may have Y
methods. But the only methods that we know for sure it will have will be those that are both X
and Y
.
Now, in this case, methods that are X
but not Y
or that are Y
but not X
, can not be used without a cast and the compiler would be right to issue a compile error if you did this:
public void outroMetodo() {
T algumObjeto = metodoQualquer();
algumObjeto.metodoQueSoExisteNoX();
}
After all, this method may not exist in the given reference case algumObjeto
is a Y
instead of a X
. This would force you to use a cast , but if you are forced to use casts , then you have no reason to use the generic type.
Maybe what you want is that T
has the methods of X
and of Y
instead of the methods of X
or % with%. In this case you can declare the following:
class MinhaClasseGenerica<T extends X & Y>
On the other hand, maybe Y
and X
have something in common. In this case the ideal would be to do the following:
interface Z {
// Aqui vai o que há de comum entre X e Y.
}
interface X extends Z {
// Aqui vai o que há em X, mas não em Y.
}
interface Y extends Z {
// Aqui vai o que há em Y, mas não em X.
}
class MinhaClasseGenerica<T extends Z> {
// ...
}
That would solve your problem. It would still allow me to invent a Y
that also inherits from W
and is neither Z
nor X
, but this is inherent in the language: inheritance is open. There is no inheritance closed in Java. By the way, the fact that there is no inheritance closed in Java allows me to do this:
// Isso não é Exception e nem Error, mas eu posso dar throw nele!
class WTF extends Throwable {}
If what you want is something closed, the path might be to work with Y
.
Finally, it is always worth remembering that java does not have multiple class inheritance, and therefore a enums
where both <T extends X & Y>
and X
are classes are forbidden by language. At least one of the two should be an interface.
Take a look at here .
Java does not support multiple inheritance. A class can not extend two classes. You can extend a class and multiple interfaces. For example:
public class GenericsTest {
class Vehicle { }
interface PassengerVehicle { }
interface MotorVehicle { }
// Classe genérica que compila sem problemas
class ParkingGarage<X extends Vehicle & MotorVehicle & PassengerVehicle>{}
// Vamos criar uma segunda classe
class Vehicle2 { }
// Não compila porque X não pode estender duas classes ao mesmo tempo
class ParkingGarage2<X extends Vehicle & Vehicle2 >{}
}
The solution to your problem might be to create a parent class for which your two classes are daughters. You may have a multi-daughters mother class, but not a daughter class with multiple mothers.