在 Java 中访问子类中超类"final"字段(并更新它们)



我有一个用于建筑物和从Buildings类继承的不同类型建筑物的子类的字段。Buildings类有一个名为"totalNumber"的字段,每次在其中一个子类中添加建筑时,我都要更新它。

我希望Buildings类中的totalNumber始终显示已创建的建筑总数。

在这种情况下,我应该在"totalNumber"字段中使用"final"关键字吗?

如果在子类"Cottage"(即cott)的对象内部,我调用,会发生什么

cott.totalNumber = cott.totalNumber += 1

它会更新它继承的字段吗?

请帮忙。非常感谢。

final意味着您可以在初始化变量时分配一个值,然后它是只读的。在最简单的情况下,您要查找的是某种static变量,它对创建的Buildings实例进行计数。但这样做很容易:

public class Buildings{
//a simple counter for created instances
private static int createdInstances = 0;
public Buildings(){
//new instance created -> increment counter
createdInstances++;
}
}

如果你创建了一个子类的实例,那么也总是调用超类的构造函数,所以你不需要在子类中做任何事情。

在您的问题中,您表达了对创建的子类实例进行计数的愿望。这真的不在任何一个类的职责范围内。根据您的要求,我会实现这样的解决方案:

abstract class Building { }
final class Cottage extends Building { }
final class House extends Building { }
final class Castle extends Building { }
final class BuildingManager {
private final static BuildingManager _instance = new BuildingManager();
private Set<Building> buildings;
private BuildingManager() {
buildings = new HashSet<>();
}
public static BuildingManager getManager() {
return _instance;
}
public Building getNewBuilding() {
// decide which building to create, but we'll always go with
// a castle for this example
Building castle = new Castle();
buildings.add(castle);
return castle;
}
public int getBuildingCount() {
return buildings.size();
}
}

BuildingManager全权负责Building的创建和计数。

有了这个,你会这样使用它:

BuildingManager manager = BuildingManager.getManager();
Building building = manager.getNewBuilding();
Building building2 = manager.getNewBuilding();
System.out.println(manager.getBuildingCount() + " buildings exist.");

将输出:

2 buildings exist.

要回答您的具体问题:

我希望建筑类中的totalNumber始终显示已建造的建筑总数。在这种情况下,我会在"totalNumber"字段中使用"final"关键字吗?

否。初始化后无法更改最终值字段。您可以使用object来存储这一点(赞扬@scottb提到AtomicInteger),但这并不能改变这样一个事实,即计算应用程序状态下存在的建筑物数量超出了Building的职责范围。

如果在子类"Cottage"的对象内部,cott I调用cott.totalNumber=cott.totalNumber+=1,会发生什么?它会更新它继承的字段吗?

否。一个合理的假设是,如果Building保留一个计数器,它将是一个静态字段或方法,因此类似于

Building.incrementCount();

从超类继承的字段对于该特定实例仍然是唯一的。

最新更新