If I have a class that contains an enum
type, can I extend this class and override the enum type or add more constants to this enum?
The purpose is that user will be able to call getColor()
method without knowing if the dynamic object is from base class or derived class.
For example:
public class Car {
private String name;
private CarColors color;
public enum CarColors {
BLUE,
GREEN
}
public Car(CarColors c) {
color=c;
}
public CarColors getColor() {
return color;
}
}
public class RacingCar extends Car {
private CarColors color;
public RacingCar(CarColors c) {
color=c;
}
public enum CarColors {
BLUE,
GREEN,
RED
}
@Override //?????
public CarColors getColor() {
return color;
}
}
and in main:
Car racingCar = new RacingCar();
CarColors color = racingCar.getColor();
You can't extend enum
. enums are essentially a final
class. However, enums can implement, so combined with generics, you get:
interface Color{
}
enum CarColor implements Color{
BLUE,
GREEN;
}
enum RacingCarColor implements Color{
BLUE,
GREEN,
YELLOW;
}
class Vehicle<T extends Color> {
protected T color;
protected Vehicle(T color){
this.color = color;
}
public T getColor(){
return color;
}
}
class Car extends Vehicle<CarColor>{
public Car(CarColor color){
super(color);
}
}
class RacingCar extends Vehicle<RacingCarColor>{
public RacingCar(RacingCarColor color){
super(color);
}
}
Voila!
If you want to require that the type be a Color
and be an enum, use this bound:
class Vehicle<T extends Enum<T> & Color> { ...
Or a curious equivalent:
class Vehicle<T extends Enum<? extends Color>> { ...
Can I extend this class and override the enum type or add more constants to this enum?
The problem in your situation is called hiding rather than overriding enums, and two above enums aren't related to each other. If you referred overriding as extending an enum type, since an enum is already declared with keyword final, you can't create a sub type of an enum type to add more constants.
The purpose is that user will be able to call getColor() method without knowing if the dynamic object is from base class or derived class
You're incorrect in overriding the method getColor. Nevertheless, you've made this method in subclass RacingCar has the same signature as the method in superclass Car. You still forgot about the return type that must be same as the return type in superclass or be a subtype of the return type of the overridden method. We have two different enums that shared one name CarColors. In other words, the full qualified name of the enum in subclass is RacingCar.CarColors and in the superclass is Car.CarColors. So far you have broken the rule of overriding methods, not same return type and not a subtype of the superclass's return type.
In this matter, we can't create a subtype and you don't want to insert YELLOW to the enum CarColors in super class Car, here is my solution.
interface IColor{
}
enum CarColors implements IColor{
BLUE,
GREEN;
}
enum RacingCarColors implements IColor{
BLUE,
GREEN,
YELLOW;
}
class Car {
protected IColor color;
public Car(IColor color){
this.color = color;
}
public IColor getColor(){
return color;
}
}
class RacingCar extends Car{
public RacingCar(IColor color){
super(color);
}
public IColor getColor(){
return color;
}
}
public class Test{
public static void main(String[] args) {
Car car = new RacingCar(RacingCarColors.YELLOW);
System.out.println(car.getColor());
}
}
The approach is still overriding the method getColor, but I used one same return type IColor that interface is super type of two enums in your example. This solution completely matched your expectations, but this might be complicated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With