有没有办法在抽象超级 class 中声明最终属性并在子 class 中初始化值?

Is there a way to declare a final attribute in an abstract super class and initialize the value in the sub class?

我想要一个带有最终属性 locationNumber 的抽象超级 class Location。 但是 locationNumber 应该像 MarketMosque 一样在子 class 本身中初始化。有干净的方法吗?我知道这样是行不通的,只是为了说明问题。

public abstract class Location {
    protected final int locationNumber;
    Collection<Figure> visitors;

    public int getLocationNumber() {
        return locationNumber;
    }
}

public class Market extends Location {
    locationNumber = 5;
}

public class Mosque extends Location {
    locationNumber = 10;
}

这就是你的做法:

public abstract class Location {

    private final int locationNumber;
    Collection<Figure> visitors;

    public Location(int locationNumber) {
       this.locationNumber = locationNumber;
    }

    public int getLocationNumber() {
        return locationNumber;
    }
}

public class Market1 extends Location {

    public Market1() {
       super(5);
    }
}

public class Market2 extends Location {

    public Market2() {
       super(10);
    }
}

Location m1 = new Market1();
Location m2 = new Market2();

System.out.println(m1.getLocationNumber()); // prints 5
System.out.println(m2.getLocationNumber()); // prints 10

final class成员变量在声明时不需要初始化。它可以在 class 构造函数或初始化块中赋值。

public abstract class Location {

    protected final int locationNumber;
    Collection<Figure> visitors;

    protected Location(int locNum) {
        locationNumber = locNum;
    }

    public int getLocationNumber() {
        return locationNumber;
    }
}

public class Market extends Location {
    public Market() {
        super(5);
    }
}

或者,您可以使方法 getLocationNumber 抽象化,并让每个子class return 具有相关值。那么你就不需要成员 locationNumber.

public abstract class Location {
    Collection<Figure> visitors;

    public abstract int getLocationNumber();
}

public class Market extends Location {

    public int getLocationNumber() {
        return 5;
    }
}

但如果您仍想保留会员 locationNumber 那么以下方法也有效。

public abstract class Location {
    protected final int locationNumber;

    protected Location() {
        locationNumber = getLocationNumber();
    }

    public abstract int getLocationNumber();
}

public class Market extends Location {

    public int getLocationNumber() {
        return 5;
    }
}