在Java中,在一个子类中使变量成为final和static,而在其他子类中保持变量

在Java中,在一个子类中使变量成为final和static,而在其他子类中保持变量,java,static,subclass,final,superclass,Java,Static,Subclass,Final,Superclass,我有一个超类和两个扩展它的子类。我想初始化一个名为radius的变量,它可以在子类a中自由设置,但在子类B中总是相同的。我可以在每次创建对象B时初始化该变量,但我想知道是否有可能在子类B中使该变量成为最终的和静态的,同时仍然能够在我的超类中实现getter。我可能会实现更多的子类,它们的半径要么是final,要么是variable。如果不是的话,我想知道解决我的问题最优雅的方法是什么。下面是一些有效的示例代码,但不是很好 abstract class SuperClass { publ

我有一个超类和两个扩展它的子类。我想初始化一个名为radius的变量,它可以在子类a中自由设置,但在子类B中总是相同的。我可以在每次创建对象B时初始化该变量,但我想知道是否有可能在子类B中使该变量成为最终的和静态的,同时仍然能够在我的超类中实现getter。我可能会实现更多的子类,它们的半径要么是final,要么是variable。如果不是的话,我想知道解决我的问题最优雅的方法是什么。下面是一些有效的示例代码,但不是很好

abstract class SuperClass {

    public double getRadius() {
        return this.radius;
    }

    protected double radius;
}

class A extends SuperClass{

    public void setRadius(double radius) { // Would like to put this setter in SuperClass for future subclasses.
        this.radius = radius;
    }
}

class B extends SuperClass{
    public B() {
        radius = 0.2; //Want to make this static and final only for this subclass.
    }
}
在一个子类中生成一个变量final和static,同时保持它 Java中的其他变量

从技术上讲,你做不到。 字段是静态字段或实例字段,而不是两者。 或者,在要提供不同值的B类中重写getRadius:

@Override
public double getRadius() {
    return 0.2;
}
要使该常量得到尊重,还应重写该B类中的setter:


你为什么不试试这个呢:

在超类中将变量设为private。 在超类中有一个getter和setter方法

重写子类中的setter方法,以便无法更改变量

就像这样:

abstract class SuperClass {

    private double radius;

    public double getRadius() {
        return this.radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
}

class A extends SuperClass{

}

class B extends SuperClass{
    public B() {
        super.setRadius(0.2d);
    }

    @Override
    public void setRadius(double radius) {
        throw new UnsupportedOperationException("My Info Text");
    }
}

另一种方法是将基类放在自己的包中,并使用受保护的setter:

package sandbox.radius.base;

public class Radius {
    private double radius;

    public double getRadius() {
        return radius;
    }

    protected void setRadius(double radius) {
        this.radius = radius;
    }
}
然后在另一个包中实现,仅在适当的情况下公开setter,授权给super:

package sandbox.radius;

import sandbox.radius.base.Radius;

public class FixedRadius extends Radius {

    public FixedRadius() {
        setRadius(0.2);
    }

}

因此,API更干净:

public class RadiusApp {

    public static void main(String[] args) {

        FixedRadius fr = new FixedRadius();
        fr.getRadius();
        // fr.setRadius(1.0); //compile error

        MutableRadius mr = new MutableRadius();
        mr.getRadius();
        mr.setRadius(1.0);
    }

}

是什么阻止了你尝试这样做来看看会发生什么?打开eclipse并运行此代码。他说代码有效,他正在寻找一个更优雅的解决方案…@B001我有,我知道你不能完全按照我的要求去做。我在寻找同样效果的东西,所以我不会每次初始化B时都创建一个新变量。
package sandbox.radius;

import sandbox.radius.base.Radius;

public class MutableRadius extends Radius {

    public void setRadius(double radius) {
        super.setRadius(radius);
    }

}
public class RadiusApp {

    public static void main(String[] args) {

        FixedRadius fr = new FixedRadius();
        fr.getRadius();
        // fr.setRadius(1.0); //compile error

        MutableRadius mr = new MutableRadius();
        mr.getRadius();
        mr.setRadius(1.0);
    }

}