在一个子类中使变量成为 final 和 static,而在 Java 中的其他子类中保持变量不变
Making a variable final and static in one subclass, while keeping it variable in others in Java
我有一个超类和两个扩展它的子类。我想初始化一个名为 radius 的变量,它可以在子类 A 中自由设置,但对于子类 B 总是相同的。我可以在每次创建对象 B 时初始化该变量,但我想知道是否可以子类 B 中的变量 final 和 static,同时仍然能够在我的超类中实现 getter。我可能会实现更多的子类,这些子类的半径要么是最终的,要么是可变的。如果不是,我想知道什么是解决我的问题的最优雅的解决方案。这是一些可以工作但不是很好的示例代码。
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.
}
}
Making a variable final and static in one subclass, while keeping it
variable in others in Java
从技术上讲,你做不到。
一个字段要么是静态字段要么是实例字段,不能两者都是。
作为替代方案,覆盖 B
class 中的 getRadius()
以提供不同的值:
@Override
public double getRadius() {
return 0.2;
}
为了使这个常量得到尊重,您还应该覆盖 B
class:
中的 setter
@Override
public void setRadius(double radius) {
throw new UnsupportedOperationException();
}
你为什么不试试这个:
在超类中将变量设为私有。
在超类中有一个 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");
}
}
另一种方法是将基础 class 放在自己的包 中,并使用受保护的 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,委托给超级:
package sandbox.radius;
import sandbox.radius.base.Radius;
public class FixedRadius extends Radius {
public FixedRadius() {
setRadius(0.2);
}
}
和
package sandbox.radius;
import sandbox.radius.base.Radius;
public class MutableRadius extends Radius {
public void setRadius(double radius) {
super.setRadius(radius);
}
}
所以 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);
}
}
我有一个超类和两个扩展它的子类。我想初始化一个名为 radius 的变量,它可以在子类 A 中自由设置,但对于子类 B 总是相同的。我可以在每次创建对象 B 时初始化该变量,但我想知道是否可以子类 B 中的变量 final 和 static,同时仍然能够在我的超类中实现 getter。我可能会实现更多的子类,这些子类的半径要么是最终的,要么是可变的。如果不是,我想知道什么是解决我的问题的最优雅的解决方案。这是一些可以工作但不是很好的示例代码。
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.
}
}
Making a variable final and static in one subclass, while keeping it variable in others in Java
从技术上讲,你做不到。
一个字段要么是静态字段要么是实例字段,不能两者都是。
作为替代方案,覆盖 B
class 中的 getRadius()
以提供不同的值:
@Override
public double getRadius() {
return 0.2;
}
为了使这个常量得到尊重,您还应该覆盖 B
class:
@Override
public void setRadius(double radius) {
throw new UnsupportedOperationException();
}
你为什么不试试这个:
在超类中将变量设为私有。 在超类中有一个 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");
}
}
另一种方法是将基础 class 放在自己的包 中,并使用受保护的 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,委托给超级:
package sandbox.radius;
import sandbox.radius.base.Radius;
public class FixedRadius extends Radius {
public FixedRadius() {
setRadius(0.2);
}
}
和
package sandbox.radius;
import sandbox.radius.base.Radius;
public class MutableRadius extends Radius {
public void setRadius(double radius) {
super.setRadius(radius);
}
}
所以 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);
}
}