繁体   English   中英

Java变量是静态的,但扩展的子类不共享该值

[英]Java- variable that's static, but extended subclasses don't share the value

假设我有一节课:

public abstract class Foo{
  public static int i = 0;
}

我想做到这一点,当我有2个额外的类,如下:

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

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

Bar.i和ti不是相同的值,而是相应的子类静态。

这怎么做得好?

这是一个更好的例子:

说我上课了:

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

public class motorcycle extends vehicle{
  public motorcycle(){
    //All motorcycles have 2 tires. this is static to motorcycles.
    tires = 2;
  }
}

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

但他们确实分享了价值。

// All print 0
System.out.println(Foo.i);
System.out.println(Bar.i);
System.out.println(T.i);

new Bar(); // all print 1
System.out.println(Foo.i);
System.out.println(Bar.i);
System.out.println(T.i);

new T(); // all now print -1
System.out.println(Foo.i);
System.out.println(Bar.i);
System.out.println(T.i);

你想要每个类中的变量,或者你实际上想要实例变量,而不是类变量。

UPDATE

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

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

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

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

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

对于引用类上的静态变量的代码,它必须通过查看在表达式中命名的特定类来开始,然后沿着类层次结构(朝向根,java.lang.Object)向上工作,直到找到比赛。 因此,如果您调用Motorcycle.tires并且Motorcycle没有名为tire的静态变量,JVM将在Vehicle上找到该名称的变量,但是如果您调用Vehicle.tires那么它将找不到该名称的变量摩托车。

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

这里避免使用静态会更好。 您可以使用某种通用组件,车辆将委托给它以获得轮胎数量:

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

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

暂无
暂无

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

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