0

Imagine I have an abstract class like this:

public abstract class Device {

  public Device(DeviceModel model){
    // ...
  }

  public abstract boolean isBuildable();
}

Then I have an implementation of it that might look like this:

public final class Floor extends Device {
  // ...

  @Override
  public void boolean isBuildable(){
    return false;
  }
}

Here, each Device subclass returns either true or false to #isBuildable(). But each instance of Floor always returns false. Another implementation of Device may return true. That sounds like a static data : it does not depends on the current instance, but on the type of the Device.

Currently, I'm creating an instance of the class to get its value, as #isBuildable() isn't static. But I think that's poor code design.

So, what I'm trying to achieve here is like creating abstract static method. I've seen this question that doesn't help so much. I would forces the implementation of #isBuildable (this time as static) in all subclasses of Device, so that I can invoke Floor.isBuildable() or something else of the same kind.

Here I can't control all the source, so I can't use reflectivity on that. Hope you understand this weird question !

  • Even if the value is not dynamic it does not mean it is bad design. Primary you will use the Device class I guess , so it is way better to follow OOP way than make it static. – Traycho Ivanov Jul 30 '20 at 15:21
  • The logic is incorrect. That the result depends on the type makes it dynamic, not static. The type is determined at runtime. Static means it can be resolved at compile time. – Nathan Hughes Jul 30 '20 at 15:31

2 Answers2

1

If you need to store class-specific (not instance-specific) information, custom annotations may be the way to go.

This require a function using reflection to access that piece of information, which could be overkill in a small project, but should be no problem in a larger framework or similar project.

avat
  • 338
  • 3
  • 9
1

In Java, static methods cannot override other static methods, so what you want to do is not possible.

Since Java has no real type variables (the type variables used for generics do not survive until run time) you would need an instance anyway to determine which overridden static method to call. Suppose you have a class Device with two subclasses, Floor and Ceiling, all of which have a method called foo(). Since there are no run-time type variables, T.foo() cannot work, and Device.foo(), Floor.foo() and Ceiling.foo() all specify exactly which method to call.

There are a few solutions/workarounds:

  • Call the right method through reflection. You will lose any static type checking.

  • Introduce a companion enum or class which contains the information about your types. For example:

      public class DeviceType {
          private final boolean buildable;
    
          private DeviceType(boolean buildable) {
              this.buildable = buildable;
          }
    
          public boolean isBuildable() {
              return buildable;
          }
      }
    
      public class Floor extends Device {
          public static final DeviceType DEVICE_TYPE = new DeviceType(false);
          ...
      }
    

    Now you can pass around Floor.DEVICE_TYPE as a kind of representation of the class which contains the information you want.

Hoopje
  • 12,677
  • 8
  • 34
  • 50