替代java中的静态覆盖

时间:2018-04-12 17:19:45

标签: java inheritance enums static singleton

我一直在苦苦挣扎一段时间。我想定义一组有限的类型,其中一些类型是其他类型的子类型,其中每个类型由其属性的值定义。然后,这些类型将用于访问其属性,也可以通过工厂方法来创建它们的实例。

现在可能没什么意义,所以让我说我有这个代码。

abstract class Car {
    final int seats;
    final int maxSpeed;
    ...
}

abstract class DeliveryCar extends Car {
    final int maxload;
    ...
}

现在我希望有超类型FamilyCar的{​​{1}}和SportsCar以及超类型Car的{​​{1}}类型,其中包含每种类型的多个实例困难的部分是实例变量不应该是真正的“实例”变量 - 它们应该对每个HeavyTruck具有相同的值,然后为每个DeliveryCar提供一些其他值,并且每个{{1}还有其他值并且它们应该可以在没有实例的情况下访问。所以例如我希望能够写:

FamilyCar

我想到的一些事情却没有成功:

  • 静态值,但java不允许覆盖静态成员
  • 枚举,但java中没有枚举的子类,因此SportsCar的每个HeavyTruck都必须包含System.out.print("Sports cars' max. speed: " + SportsCar.maxSpeed); ,可能还有其他成员
  • 模拟枚举,如下所示:
Car

它可以做我需要的东西,但那样做DeliveryCar之类的东西也是有效的。

我不确定我想要实现的设计中是否存在一些根本性的缺陷,但它让我烦恼不已,因为我似乎无法解决可以通过我认为可覆盖的静态成员解决的问题其他一些语言(例如Objective-C)实现。

编辑:我还阅读了this讨论(其中包括),但似乎没有一个想法可以解决我的问题。

2 个答案:

答案 0 :(得分:0)

首先,关于什么不起作用的重要说明(纯静态的东西):

public static class Car {
    public final static String NAME = "Car"; 
    public final static int MAX_SPEED = 90;

    public String getName() { return NAME; }
    public int getMaxSpeed() { return MAX_SPEED; /* Car.MAX_SPEED */ }
    public String toString() { return getName() + ": maxSpeed= " + getMaxSpeed(); }
}

public static class SportsCar extends Car {
    @SuppressWarnings("hiding") public final static String NAME = "SportsCar";
    @SuppressWarnings("hiding") public final static int MAX_SPEED = 120;

    @Override public String getName() { return NAME; /* SportsCar.NAME */}
    @Override public int getMaxSpeed() { return MAX_SPEED; /* SportsCar.MAX_SPEED */ }
    // ** no new fields so just inherit 'toString()'
}

public static class DeliveryCar extends Car {
    @SuppressWarnings("hiding") public final static String NAME = "DeliveryCar";
    @SuppressWarnings("hiding") public final static int MAX_SPEED = 70;
    /* new field ........... */ public final static int MAX_LOAD = 250;

    @Override public String getName() { return NAME; /* DeliveryCar.NAME */}
    @Override public int getMaxSpeed() { return MAX_SPEED; /* DeliveryCar.MAX_SPEED */}
    /* new */ public int getMaxLoad() { return MAX_LOAD; /* DeliveryCar.MAX_LOAD */ }

    @Override public String toString() { return getName() + ": maxSpeed= " + getMaxSpeed() + ", maxLoad= " + getMaxLoad(); }
}

public static class DeliveryTruck extends DeliveryCar {
    @SuppressWarnings("hiding") public final static String NAME = "DeliveryTruck";
    @SuppressWarnings("hiding") public final static int MAX_LOAD = 1000;

    @Override public String getName() { return NAME; /* DeliveryTruck.NAME */}
    @Override public int getMaxLoad() { return MAX_LOAD; /* DeliveryTruck.MAX_LOAD */ }
    // ** no new fields so just inherit 'toString()'
}


public static void main(String[] args) {
    List<Car> list = Arrays.asList(new Car(), new Car(), new SportsCar(), new DeliveryCar(), new DeliveryTruck(), new SportsCar());
    for(Car car : list) {
        System.out.println(car);
    }
    System.out.println("Static Car maxSpeed = " + Car.MAX_SPEED);
    // warning, should access through DeliveryCar.MAX_SPEED since DeliveryTruck doesn't redefine it.
    System.out.println("Static DeliveryTruck maxSpeed = " + DeliveryTruck.MAX_SPEED);
}

如果您需要多态,那么您需要具有返回静态值的实例方法,并覆盖实例方法以返回其类的更新静态值。也许是这样的:

{{1}}

我不是特别喜欢它,但它有效...如果没有别的,这至少是一些头脑风暴,希望能引导我们找到更好的解决方案。如果你想出更好的想法,我很想听听。

答案 1 :(得分:0)

您不需要静态字段,只需使用常规受保护(或公共)字段。如果你想确保其他子类型不能覆盖它,你可以在子类中使它成为最终...

abstract class  Car {
     protected int max = 5;
}

class Family extends Car {
    protected final int max = 10;
}

class Sport extends Car {
    protected final int max = 100;
}

class Other extends Car {
}

public static void main(String[] args) {
  System.out.println(new Family().max);
  System.out.println(new Sport().max);
  System.out.println(new Other().max);
}

提供输出:     10     100     5