Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java—变量';s静态但扩展的子类don';不要分享价值_Java_Static_Virtual_Abstract - Fatal编程技术网

Java—变量';s静态但扩展的子类don';不要分享价值

Java—变量';s静态但扩展的子类don';不要分享价值,java,static,virtual,abstract,Java,Static,Virtual,Abstract,假设我有一门课: public abstract class Foo{ public static int i = 0; } public abstract class vehicle{ public static int tires; } 我想这样做,当我有两个额外的类,如: public class Bar extends Foo{ public Bar(){ i=1; } } 及 该Bar.i和t.i不是相同的值,而是它们各自的子类的静态值 如何正确地做到这一点 下

假设我有一门课:

public abstract class Foo{
  public static int i = 0;
}
public abstract class vehicle{
  public static int tires;
}
我想这样做,当我有两个额外的类,如:

public class Bar extends Foo{
   public Bar(){ i=1; }
}  

该Bar.i和t.i不是相同的值,而是它们各自的子类的静态值

如何正确地做到这一点

下面是一个更好的例子: 假设我有一门课:

public abstract class Foo{
  public static int i = 0;
}
public abstract class vehicle{
  public static int tires;
}
我有两个子类:

public class car extends vehicle{
  public car(){
    //ALL cars have 4 tires. this is static to cars.
    tires = 4;
  }
}


显然,汽车和摩托车没有相同数量的轮胎,但我仍然希望能够访问car.Tires和motorcycle.Tires,分别返回4和2。我还希望能够调用{variableName}.tires,因为变量是车辆。我还希望以后能够添加更多类似的变量,例如另一个int
numberOfLights

这是您应该做的吗?我不完全确定你在问什么

public abstract class Foo{

}    

public class Bar extends Foo{
   public static int i = 0;
}  
and

public class t extends Foo{
   public static int i = 0;
}

不过,他们也有同样的价值

要么在每个类中都需要一个变量,要么实际上需要实例变量,而不是类变量

abstract class Vehicle {
    public abstract int getTires();
}

class Car extends Vehicle {
    @Override
    public int getTires() { return 4; }
}

class Motocycle extends Vehicle {
    @Override
    public int getTires() { return 2; }
}
更新

至于更好的例子,您需要的是抽象方法,而不是静态变量

abstract class Vehicle {
    public abstract int getTires();
}

class Car extends Vehicle {
    @Override
    public int getTires() { return 4; }
}

class Motocycle extends Vehicle {
    @Override
    public int getTires() { return 2; }
}

你不能做你想做的,静态不做虚拟查找。当您调用严格引用Vehicle上的类变量的
Vehicle.tires
时,它不会查看子类中的任何内容

对于要引用类上的静态变量的代码,它必须首先查看在表达式中命名的特定类,然后沿着类层次结构向上(指向根java.lang.Object),直到找到匹配项为止。因此,如果您调用
Motorcycle.tires
,并且Motorcycle没有名为tires的静态变量,JVM将在Vehicle上找到该名称的变量,但是如果您调用
Vehicle.tires
,那么它将不会在Motorcycle上找到该名称的变量

这与虚拟查找相反,在虚拟查找中,您的代码可能甚至不知道它处理的是什么子类,它让对象计算出在运行时动态触发的行为。要使用静态变量和方法,调用它们的代码必须在编译时非常具体地说明它所使用的子类。这就是为什么他们称之为静态,因为它不会改变

这里最好避免使用静态。为了获得轮胎数量,您可以将车辆委托给某种常见部件:

public Vehicle {
    private VehicleConfig config;
    public int getTireCount() {
        return config.getTireCount();
    }
}

将配置放在单独的对象中意味着您可以将其范围与包含它的对象分开管理。使用static同样是试图以一种不灵活的方式管理对象的范围。

因此,当您初始化
Bar
实例时,您将所有
i
变量设置为
1
?但是
Bar.i
是未定义的。它们都是
Foo.i
如果不希望子类共享,则必须在每个子类中定义一个
static
变量。如果需要实例变量,请删除
static
。“那么如何让子类继承其自己唯一的静态变量?”--您不需要。这是一个很好的例子,说明了继承和静态不能很好地混合。我认为他不希望它们在类之间共享,而只是在同一个类的实例之间共享。