JeanAlesi
JeanAlesi

Reputation: 598

invoke methods from enum defined in subclass - Java

I have an abstract class Sensor, which is extended by multiple Device sub-classes. Each sub-class defines an enum. These enums can be different for each Sub-class instance. These enums are used to define a status instance variable. I would like to find a way to define the getter method getStatus() in the parent (abstract) class so that I won't have to reapeat the same lines of code in every subclass..

E.g.:

abstract class Sensor {
    // here I would have liked to declare a "status" variable to hold enum values from subclass
    ....... status;

    Sensor() {}

    public String getStatus() {
        // return the status defined in the subclass
        return status.name();
    }
}
class Device extends Sensor {
    enum Status { ON, OFF };

    Device() {
        super.status = Status.ON;  // store enum value into variable defined in superclass
    }
}
class Device2 extends Sensor {
    enum Status { OPEN, CLOSED, LOCKED };

    Device2() {
        super.status = Status.OPEN;
    }
}

Upvotes: 1

Views: 218

Answers (3)

ILMTitan
ILMTitan

Reputation: 11017

You could make Sensor generic

class Sensor<T extends Enum<T>> {
    T status;
    protected Sensor(T status) {
        this.status = status;
    }

    public String getStatus() {
        return this.status.toString();
    }
}

class Device extends Sensor<Device.Status> {
    enum Status {On, Off}
    public Device() {
        super(Status.On);
    }
}

class Device2 extends Sensor<Device2.Status> {
    enum Status { OPEN, CLOSED, LOCKED }

    Device2() {
        super(Status.OPEN);
    }
}

Or you could make Sensor and getStatus() abstract, and not have as a field status in Sensor.

abstract class Sensor {
    public abstract String getStatus();
}

class Device extends Sensor {
    enum Status {On, Off}
    Status status = Status.On;

    public String getStatus() {
        return this.status.toString();
    }
}

class Device2 extends Sensor {
    enum Status { OPEN, CLOSED, LOCKED }
    Status status = Status.OPEN;
    public String getStatus() {
        return this.status.toString();
    }
}

Upvotes: 5

Beno&#238;t
Beno&#238;t

Reputation: 1100

Since you can't inherit from enums in Java and you want the enums to be specific to each sub-class, I would make the superClass generic with the enum

RQ: I added the static keywords to be use inner classes in a single file. You can remove them once you copy them in separate classes/files:

static abstract class Sensor<T extends Enum<T>> {
    T status;

    Sensor() {}

    public T getStatus() {
        return status;
    }

    public String getStatusAsString() {
        return status.name();
    }
}
static class Device extends Sensor<Device.Status> {
    enum Status { ON, OFF };

    Device() {
        super.status = Status.ON;  // store enum value into variable defined in superclass
    }
}
static class Device2 extends Sensor<Device2.Status> {
    enum Status { OPEN, CLOSED, LOCKED };

    Device2() {
        super.status = Status.OPEN;
    }
}

Upvotes: 2

akhil_mittal
akhil_mittal

Reputation: 24157

IMO the enum should be part of base class and its value can be modified by a device.

abstract class Sensor {
    Sensor() {}

    enum Status { ON, OFF };

    Status status;

    public String getStatus() {
        // return the status defined in the subclass
        return status.name();
    }
}

Now consider a Device as:

public class Device extends Sensor {
    Device() {
        super.status = Status.ON;  // store enum value into variable defined in superclass
    }

    public void setStausToOff() {
        super.status = Status.OFF;
    }
}

Then we can do the testing as:

 public static void main(String[] args) {
        Sensor sensor1 = new Device();
        System.out.println(sensor1.getStatus());

        Device sensor2 = new Device();
        System.out.println(sensor1.getStatus());
        sensor2.setStausToOff();
        System.out.println(sensor2.getStatus());

    }

And it prints:

ON ON OFF

NOTE: You may need to modify it as per your requirement but it will give you some hint.

If each Device is going to have its own Enum (distict) in that case its value will be known to the instance of that class only and not to base class. For example Car is base class and VW is derived class using some special kind features exclusive to this. IN that case you cannot get value of those features in Car class. How can parent class know about the attribute specific to a child class? It cannot.

Upvotes: 0

Related Questions