繁体   English   中英

java中静态覆盖的替代方法

[英]Alternative to static overriding in java

我已经为此苦苦挣扎了一段时间。 我想定义一组有限的类型,其中一些类型是其他类型的子类型,其中每种类型都由其属性值定义。 然后这些类型将用于访问它们的属性,并通过工厂方法来创建它们的实例。

现在可能没有多大意义,所以假设我有这段代码。

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

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

现在我想要拥有诸如超类型Car FamilyCarSportsCar和超类型DeliveryCar HeavyTruck之类的类型,每个类型都有多个实例,困难的部分是实例变量不应该真正是“实例”变量 - 它们应该具有相同的值每个FamilyCar ,然后是每个SportsCar一些其他值,以及每个HeavyTruck其他值,它们应该可以在没有实例的情况下访问。 例如,我希望能够编写:

System.out.print("Sports cars' max. speed: " + SportsCar.maxSpeed);

我想到了一些但没有解决的事情:

  • 静态值,但 java 不允许覆盖静态成员
  • 枚举,但在 java 中没有枚举的子类化,因此每个不是DeliveryCar Car都必须具有maxload和可能的其他成员
  • 模拟枚举,如下所示:
class CarType {
    final int seats;
    final int maxSpeed;
    ...
    static final CarType FAMILY_CAR = new CarType(5, 180);
    static final CarType SPORT_CAR = new CarType(2, 280);
    ...
    CarType(int seats, int maxSpeed) {
    ...
}

class DeliveryCarType extends CarType {
    final int maxload;
    ...
    static final DeliveryCarType HEAVY_TRUCK = new DeliveryCarType(3, 150, 500)
    ...
    DeliveryCarType(int seats, int maxSpeed, int maxLoad) {
    ...
}

它会做我需要的事情,但它也会有效地写一些类似DeliveryCar.SPORTS_CAR东西。

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

编辑:我也阅读了这个讨论(以及其他),但那里的想法似乎都没有解决我的问题。

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

public static class Car {
    public final static String NAME = "Car";
    public static String getName() { return NAME; }
}

public static class SportsCar extends Car {
    public final static String NAME = "SportsCar";
    public static String getName() { return NAME; }
}

public static void main(String[] args) {
    Car c0 = new Car();
    System.out.println(c0.NAME);
    System.out.println(c0.getName());
    //  both print "Car"

    SportsCar c1 = new SportsCar();
    System.out.println(c1.NAME);
    System.out.println(c1.getName());
    // both print "SportsCar"

    Car c2 = new SportsCar();
    System.out.println(c2.NAME);
    System.out.println(c2.getName());
    // both print "Car" because c2 ""doesn't know"" that it's really a 'SportsCar'
    // this is an issue with your need for polymorphism with these values
}

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

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);
}

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM